From ea11182a0e8cb62d208b5b53a60c98c8bdef9e9a Mon Sep 17 00:00:00 2001 From: amankumarsingh77 Date: Tue, 28 Jul 2026 21:17:13 +0530 Subject: feat!: remove the deep-research feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- test/deep-research/agent-config-test.ts | 43 ---------------- test/deep-research/fixtures/article-capture.json | 17 ------ .../fixtures/google-serp-captcha.json | 4 -- test/deep-research/fixtures/google-serp-empty.json | 4 -- test/deep-research/fixtures/google-serp-ok.json | 40 --------------- .../deep-research/fixtures/no-article-capture.json | 10 ---- test/deep-research/readability-test.ts | 60 ---------------------- test/deep-research/serp-parser-test.ts | 60 ---------------------- test/domains/fixtures/article-capture.json | 17 ++++++ test/domains/fixtures/google-serp-captcha.json | 4 ++ test/domains/fixtures/google-serp-empty.json | 4 ++ test/domains/fixtures/google-serp-ok.json | 40 +++++++++++++++ test/domains/fixtures/no-article-capture.json | 10 ++++ test/domains/readability-test.ts | 60 ++++++++++++++++++++++ test/domains/serp-parser-test.ts | 60 ++++++++++++++++++++++ 15 files changed, 195 insertions(+), 238 deletions(-) delete mode 100644 test/deep-research/agent-config-test.ts delete mode 100644 test/deep-research/fixtures/article-capture.json delete mode 100644 test/deep-research/fixtures/google-serp-captcha.json delete mode 100644 test/deep-research/fixtures/google-serp-empty.json delete mode 100644 test/deep-research/fixtures/google-serp-ok.json delete mode 100644 test/deep-research/fixtures/no-article-capture.json delete mode 100644 test/deep-research/readability-test.ts delete mode 100644 test/deep-research/serp-parser-test.ts create mode 100644 test/domains/fixtures/article-capture.json create mode 100644 test/domains/fixtures/google-serp-captcha.json create mode 100644 test/domains/fixtures/google-serp-empty.json create mode 100644 test/domains/fixtures/google-serp-ok.json create mode 100644 test/domains/fixtures/no-article-capture.json create mode 100644 test/domains/readability-test.ts create mode 100644 test/domains/serp-parser-test.ts (limited to 'test') diff --git a/test/deep-research/agent-config-test.ts b/test/deep-research/agent-config-test.ts deleted file mode 100644 index 025a844..0000000 --- a/test/deep-research/agent-config-test.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { test, before, describe } from "node:test"; -import assert from "node:assert/strict"; -import { readFileSync } from "node:fs"; -import { join } from "node:path"; - -describe("web-search-researcher subagent config references only real tools", () => { - let frontmatter: string; - let body: string; - let toolsLine: string; - - before(() => { - const agentPath = join(import.meta.dirname, "..", "..", ".pi", "agents", "web-search-researcher.md"); - const raw = readFileSync(agentPath, "utf8"); - const fmMatch = raw.match(/^---\n([\s\S]*?)\n---/); - frontmatter = fmMatch ? (fmMatch[1] ?? "") : ""; - body = fmMatch ? raw.slice(fmMatch[0].length) : raw; - toolsLine = frontmatter.split("\n").find((l) => l.startsWith("tools:")) ?? ""; - }); - - test("S20: tools includes browser_web_search", () => { - assert.ok(toolsLine.includes("browser_web_search")); - }); - - test("S20: tools includes browser_read_page", () => { - assert.ok(toolsLine.includes("browser_read_page")); - }); - - test("S20: tools does NOT include web_search", () => { - assert.ok(!/\bweb_search\b/.test(toolsLine)); - }); - - test("S20: tools does NOT include web_fetch", () => { - assert.ok(!/\bweb_fetch\b/.test(toolsLine)); - }); - - test("S20: isolated: true is present", () => { - assert.ok(/^\s*isolated:\s*true\s*$/m.test(frontmatter)); - }); - - test("S20: body has no WebSearch/WebFetch references", () => { - assert.ok(!/WebSearch|WebFetch/.test(body)); - }); -}); diff --git a/test/deep-research/fixtures/article-capture.json b/test/deep-research/fixtures/article-capture.json deleted file mode 100644 index df9c67c..0000000 --- a/test/deep-research/fixtures/article-capture.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "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/deep-research/fixtures/google-serp-captcha.json b/test/deep-research/fixtures/google-serp-captcha.json deleted file mode 100644 index 7c6610f..0000000 --- a/test/deep-research/fixtures/google-serp-captcha.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "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/deep-research/fixtures/google-serp-empty.json b/test/deep-research/fixtures/google-serp-empty.json deleted file mode 100644 index 34bb1dc..0000000 --- a/test/deep-research/fixtures/google-serp-empty.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "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/deep-research/fixtures/google-serp-ok.json b/test/deep-research/fixtures/google-serp-ok.json deleted file mode 100644 index 61aa483..0000000 --- a/test/deep-research/fixtures/google-serp-ok.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "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/deep-research/fixtures/no-article-capture.json b/test/deep-research/fixtures/no-article-capture.json deleted file mode 100644 index d367b7e..0000000 --- a/test/deep-research/fixtures/no-article-capture.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "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/deep-research/readability-test.ts b/test/deep-research/readability-test.ts deleted file mode 100644 index 211229d..0000000 --- a/test/deep-research/readability-test.ts +++ /dev/null @@ -1,60 +0,0 @@ -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/deep-research/serp-parser-test.ts b/test/deep-research/serp-parser-test.ts deleted file mode 100644 index 433c650..0000000 --- a/test/deep-research/serp-parser-test.ts +++ /dev/null @@ -1,60 +0,0 @@ -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"); - }); -}); 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"); + }); +}); -- cgit v1.2.3