aboutsummaryrefslogtreecommitdiff
path: root/test/domains
diff options
context:
space:
mode:
authoramankumarsingh77 <amankumarsingh7702@gmail.com>2026-07-28 21:17:13 +0530
committerAman Kumar <145339995+amankumarsingh77@users.noreply.github.com>2026-08-02 19:12:46 +0530
commitea11182a0e8cb62d208b5b53a60c98c8bdef9e9a (patch)
tree665fb355b902e5f067694d1e953039f6713e8245 /test/domains
parent91f5ad12fc04264e0423b37c4871c826bb98a66b (diff)
feat!: remove the deep-research feature
The harness ships browser tools; orchestrating a multi-agent research workflow on top of them is the agent's job, not this extension's. Drops the skill, the /deep-research command, and the web-search-researcher subagent config. browser_web_search and browser_read_page are untouched — the two tests that covered their pure parsers move to test/domains/, where the test glob still picks them up. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'test/domains')
-rw-r--r--test/domains/fixtures/article-capture.json17
-rw-r--r--test/domains/fixtures/google-serp-captcha.json4
-rw-r--r--test/domains/fixtures/google-serp-empty.json4
-rw-r--r--test/domains/fixtures/google-serp-ok.json40
-rw-r--r--test/domains/fixtures/no-article-capture.json10
-rw-r--r--test/domains/readability-test.ts60
-rw-r--r--test/domains/serp-parser-test.ts60
7 files changed, 195 insertions, 0 deletions
diff --git a/test/domains/fixtures/article-capture.json b/test/domains/fixtures/article-capture.json
new file mode 100644
index 0000000..df9c67c
--- /dev/null
+++ b/test/domains/fixtures/article-capture.json
@@ -0,0 +1,17 @@
+{
+ "url": "https://blog.example.com/how-cdp-works",
+ "title": "How the Chrome DevTools Protocol Works",
+ "blocks": [
+ { "kind": "other", "text": "Home Products Blog About Contact", "linkTextLength": 33, "inBoilerplate": true },
+ { "kind": "heading", "text": "How the Chrome DevTools Protocol Works", "linkTextLength": 0, "inBoilerplate": false },
+ { "kind": "paragraph", "text": "The Chrome DevTools Protocol lets tools instrument, inspect, and control Chromium-based browsers over a WebSocket connection.", "linkTextLength": 0, "inBoilerplate": false },
+ { "kind": "paragraph", "text": "Each command targets a domain such as Page, Runtime, or Network, and receives a structured JSON response that the client correlates by id.", "linkTextLength": 0, "inBoilerplate": false },
+ { "kind": "heading", "text": "Sessions and Targets", "linkTextLength": 0, "inBoilerplate": false },
+ { "kind": "paragraph", "text": "A target is a page or worker; attaching to one yields a session id that scopes subsequent commands to that target without disturbing others.", "linkTextLength": 0, "inBoilerplate": false },
+ { "kind": "listitem", "text": "Attach with Target.attachToTarget", "linkTextLength": 0, "inBoilerplate": false },
+ { "kind": "listitem", "text": "Drive with Runtime.evaluate", "linkTextLength": 0, "inBoilerplate": false },
+ { "kind": "paragraph", "text": "Subscribe here for our newsletter and follow us on social media for updates", "linkTextLength": 55, "inBoilerplate": true },
+ { "kind": "other", "text": "Copyright 2026 Example Inc. Privacy Terms Cookies", "linkTextLength": 24, "inBoilerplate": true }
+ ],
+ "bodyText": "Home Products Blog How the Chrome DevTools Protocol Works The Chrome DevTools Protocol lets tools instrument inspect and control browsers Copyright 2026"
+}
diff --git a/test/domains/fixtures/google-serp-captcha.json b/test/domains/fixtures/google-serp-captcha.json
new file mode 100644
index 0000000..7c6610f
--- /dev/null
+++ b/test/domains/fixtures/google-serp-captcha.json
@@ -0,0 +1,4 @@
+{
+ "anchors": [],
+ "pageText": "About this page Our systems have detected unusual traffic from your computer network. This page checks to see if it's really you sending the requests and not a robot. Why did this happen? To continue, please type the characters below. reCAPTCHA."
+}
diff --git a/test/domains/fixtures/google-serp-empty.json b/test/domains/fixtures/google-serp-empty.json
new file mode 100644
index 0000000..34bb1dc
--- /dev/null
+++ b/test/domains/fixtures/google-serp-empty.json
@@ -0,0 +1,4 @@
+{
+ "anchors": [],
+ "pageText": "Your search - asdkfjhqwlekjrhqwlekjrhqwe - did not match any documents. Suggestions: Make sure that all words are spelled correctly. Try different keywords."
+}
diff --git a/test/domains/fixtures/google-serp-ok.json b/test/domains/fixtures/google-serp-ok.json
new file mode 100644
index 0000000..61aa483
--- /dev/null
+++ b/test/domains/fixtures/google-serp-ok.json
@@ -0,0 +1,40 @@
+{
+ "anchors": [
+ {
+ "href": "https://www.google.com/url?q=https://real.example/x&sa=U&ved=abc",
+ "heading": "Real Example X — the definitive guide",
+ "snippet": "Real Example X — the definitive guide. Everything about x, explained clearly."
+ },
+ {
+ "href": "https://docs.example.org/guide",
+ "heading": "Official Guide",
+ "snippet": "Official Guide to the thing you searched for."
+ },
+ {
+ "href": "https://www.google.com/search?q=related",
+ "heading": "Related searches on Google",
+ "snippet": "internal google navigation"
+ },
+ {
+ "href": "javascript:void(0)",
+ "heading": "Expand",
+ "snippet": "ui control"
+ },
+ {
+ "href": "https://real.example/x/",
+ "heading": "Real Example X (duplicate with trailing slash)",
+ "snippet": "should be deduped against the first result"
+ },
+ {
+ "href": "https://second.example/a",
+ "heading": "Second Example A",
+ "snippet": "Second result body."
+ },
+ {
+ "href": "https://third.example/b",
+ "heading": "Third Example B",
+ "snippet": "Third result body."
+ }
+ ],
+ "pageText": "Real Example X the definitive guide Official Guide Second Example Third Example About 12,300 results"
+}
diff --git a/test/domains/fixtures/no-article-capture.json b/test/domains/fixtures/no-article-capture.json
new file mode 100644
index 0000000..d367b7e
--- /dev/null
+++ b/test/domains/fixtures/no-article-capture.json
@@ -0,0 +1,10 @@
+{
+ "url": "https://app.example.com/dashboard",
+ "title": "Dashboard",
+ "blocks": [
+ { "kind": "other", "text": "Menu", "linkTextLength": 4, "inBoilerplate": true },
+ { "kind": "listitem", "text": "Widget A", "linkTextLength": 8, "inBoilerplate": true },
+ { "kind": "listitem", "text": "Widget B", "linkTextLength": 8, "inBoilerplate": true }
+ ],
+ "bodyText": "Dashboard Widget A Widget B Your account is active. Usage this month is within limits and no action is required at this time from you."
+}
diff --git a/test/domains/readability-test.ts b/test/domains/readability-test.ts
new file mode 100644
index 0000000..211229d
--- /dev/null
+++ b/test/domains/readability-test.ts
@@ -0,0 +1,60 @@
+import { test, describe } from "node:test";
+import assert from "node:assert/strict";
+import { readFileSync } from "node:fs";
+import { join } from "node:path";
+import { extractReadable, type PageCapture } from "../../src/domains/readpage/readability";
+
+const fixture = (name: string): PageCapture =>
+ JSON.parse(readFileSync(join(import.meta.dirname, "fixtures", name), "utf8")) as PageCapture;
+
+describe("pure readability extractor", () => {
+ test("S10: article body text is present", () => {
+ const page = extractReadable(fixture("article-capture.json"));
+ assert.ok(page.text.includes("Chrome DevTools Protocol lets tools instrument"));
+ });
+
+ test("S10: article headings are preserved", () => {
+ const page = extractReadable(fixture("article-capture.json"));
+ assert.ok(page.text.includes("Sessions and Targets"));
+ });
+
+ test("S10: nav boilerplate is dropped", () => {
+ const page = extractReadable(fixture("article-capture.json"));
+ assert.ok(!page.text.includes("Home Products Blog"));
+ });
+
+ test("S10: footer boilerplate is dropped", () => {
+ const page = extractReadable(fixture("article-capture.json"));
+ assert.ok(!page.text.includes("Copyright 2026"));
+ });
+
+ test("S10: high-link-density promo block is dropped", () => {
+ const page = extractReadable(fixture("article-capture.json"));
+ assert.ok(!page.text.includes("Subscribe here for our newsletter"));
+ });
+
+ test("S10: paragraph/heading structure preserved as markdown", () => {
+ const page = extractReadable(fixture("article-capture.json"));
+ assert.ok(page.text.includes("## Sessions and Targets"));
+ });
+
+ test("S10: title and url passed through", () => {
+ const page = extractReadable(fixture("article-capture.json"));
+ assert.ok(page.title === "How the Chrome DevTools Protocol Works" && page.url.startsWith("https://"));
+ });
+
+ test("S10: word count reflects the article body", () => {
+ const page = extractReadable(fixture("article-capture.json"));
+ assert.ok(page.wordCount > 40);
+ });
+
+ test("S11: structure-less page falls back to non-empty body text", () => {
+ const page = extractReadable(fixture("no-article-capture.json"));
+ assert.ok(page.text.length > 0);
+ });
+
+ test("S11: fallback body text carries the real content", () => {
+ const page = extractReadable(fixture("no-article-capture.json"));
+ assert.ok(page.text.includes("Your account is active"));
+ });
+});
diff --git a/test/domains/serp-parser-test.ts b/test/domains/serp-parser-test.ts
new file mode 100644
index 0000000..433c650
--- /dev/null
+++ b/test/domains/serp-parser-test.ts
@@ -0,0 +1,60 @@
+import { test, describe } from "node:test";
+import assert from "node:assert/strict";
+import { readFileSync } from "node:fs";
+import { join } from "node:path";
+import { classifySerp, parseGoogleSerp, type SerpExtraction } from "../../src/domains/search/google-serp";
+
+const fixture = (name: string): SerpExtraction =>
+ JSON.parse(readFileSync(join(import.meta.dirname, "fixtures", name), "utf8")) as SerpExtraction;
+
+const ok = fixture("google-serp-ok.json");
+const captcha = fixture("google-serp-captcha.json");
+const empty = fixture("google-serp-empty.json");
+
+describe("pure Google SERP parser", () => {
+ test("S1: /url?q= redirect is unwrapped to the real target", () => {
+ const results = parseGoogleSerp(ok.anchors, 10);
+ const urls = results.map((r) => r.url);
+ assert.ok(urls.includes("https://real.example/x"));
+ });
+
+ test("S1: google-internal anchors are dropped", () => {
+ const results = parseGoogleSerp(ok.anchors, 10);
+ const urls = results.map((r) => r.url);
+ assert.ok(!urls.some((u) => u.includes("google.com")));
+ });
+
+ test("S1: javascript: anchors are dropped", () => {
+ const results = parseGoogleSerp(ok.anchors, 10);
+ const urls = results.map((r) => r.url);
+ assert.ok(!urls.some((u) => u.startsWith("javascript:")));
+ });
+
+ test("S2: trailing-slash duplicate collapses to one result", () => {
+ const results = parseGoogleSerp(ok.anchors, 10);
+ const realExampleCount = results.filter((r) => r.url.startsWith("https://real.example/x")).length;
+ assert.equal(realExampleCount, 1);
+ });
+
+ test("S2: rank runs 1..n in input order", () => {
+ const results = parseGoogleSerp(ok.anchors, 10);
+ assert.ok(results.every((r, i) => r.rank === i + 1));
+ });
+
+ test("S2: limit truncates and ranks stay 1..limit", () => {
+ const capped = parseGoogleSerp(ok.anchors, 2);
+ assert.ok(capped.length === 2 && capped[capped.length - 1]?.rank === 2);
+ });
+
+ test("S3: populated SERP classifies as ok", () => {
+ assert.equal(classifySerp(ok.pageText, parseGoogleSerp(ok.anchors, 10).length), "ok");
+ });
+
+ test("S3: captcha page classifies as captcha", () => {
+ assert.equal(classifySerp(captcha.pageText, 0), "captcha");
+ });
+
+ test("S3: empty results classify as no_results", () => {
+ assert.equal(classifySerp(empty.pageText, 0), "no_results");
+ });
+});