Skip to content

Refactor: consolidate 32 tools → 18#61

Merged
angiejones merged 4 commits intomainfrom
refactor/consolidate-tools
Feb 22, 2026
Merged

Refactor: consolidate 32 tools → 18#61
angiejones merged 4 commits intomainfrom
refactor/consolidate-tools

Conversation

@angiejones
Copy link
Copy Markdown
Owner

@angiejones angiejones commented Feb 22, 2026

What

Consolidate the MCP tool surface from 32 tools down to 18, reducing context window cost by ~40%.

Removed (4 tools)

  • find_element — returned only "Element found", no useful data
  • scroll_to_element — thin wrapper around execute_script
  • clear_elementsend_keys already clears first
  • drag_and_dropexecute_script handles it

Consolidated (14 tools → 5)

New tool Replaces
interact click_element, double_click, right_click, hover
window switch_to_window, get_window_handles, switch_to_latest_window, close_current_window
frame switch_to_frame, switch_to_default_content
alert accept_alert, dismiss_alert, get_alert_text, send_alert_text
diagnostics get_console_logs, get_page_errors, get_network_logs

Also

  • Fixed flaky window tests — single McpClient per test file instead of 6
  • Added execute_script drag-and-drop test to prove the escape hatch
  • Added default cases to all action switch statements
  • Rewrote README with collapsible sections
  • Trimmed AGENTS.md to agent-essential info only
  • Added GitHub Actions publish-to-npm workflow
  • Bumped version to 0.2.0

Token cost

Measured with cl100k_base tokenizer: ~2,100 tokens for all 18 tool definitions.

Closes #60

Summary by CodeRabbit

  • New Features

    • Automatic package publish on release; package version bumped to 0.2.0.
    • Unified diagnostics for console, errors, and network.
  • Refactor

    • Consolidated many specialized browser actions into generalized, action-driven APIs (interact, frame, window, alert, diagnostics).
  • Documentation

    • README and agent guide rewritten to a concise, agent-focused usage and setup narrative.
  • Tests

    • Reorganized and expanded test suites; added/updated fixtures for drag-and-drop and alerts and unified test flows.

- Remove find_element, scroll_to_element, clear_element, drag_and_drop
- Consolidate click/doubleclick/rightclick/hover → interact
- Consolidate window management → window (list/switch/switch_latest/close)
- Consolidate frame management → frame (switch/default)
- Consolidate alert handling → alert (accept/dismiss/get_text/send_text)
- Consolidate BiDi diagnostics → diagnostics (console/errors/network)
- Add execute_script drag-and-drop test to prove the escape hatch works
- Fix flaky window tests (single McpClient per test file)
- Add default cases to all action switch statements
- Rewrite README with collapsible sections
- Trim AGENTS.md to essentials
- Add GitHub Actions publish workflow
- Bump version to 0.2.0

Closes #60
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 22, 2026

Warning

Rate limit exceeded

@angiejones has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 20 minutes and 3 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

Consolidates many specialized MCP tools into a smaller set of generalized, action-based tools (interact, frame, window, alert, diagnostics), updates docs, bumps package version to 0.2.0, adds an npm publish workflow, and adapts tests and fixtures to the new tool surface.

Changes

Cohort / File(s) Summary
CI & Versioning
\.github/workflows/publish.yml, package.json
Adds "Publish to npm" workflow (on release) and bumps package version to 0.2.0.
Documentation
AGENTS.md, README.md
Large rewrites: AGENTS.md and README simplified and condensed, removing detailed tool-by-tool API docs in favor of a high-level narrative and streamlined guidance.
Core Server
src/lib/server.js
Replaces many specific tools with unified tools: interact, frame, window, alert, diagnostics; server now reads version from package.json; introduces diagnosticTypes mapping and consolidated BiDi handling.
Tests — API surface updates
test/bidi.test.mjs, test/interactions.test.mjs, test/navigation.test.mjs, test/server.test.mjs
Updates test calls to new unified APIs (e.g., interact action variants, diagnostics types); updates expected tool lists and descriptions.
Tests — New/Consolidated suites
test/new-tools.test.mjs, test/tools.test.mjs, test/...
Consolidates and expands tests into unified suites covering element attributes, execute_script, window/frame/alert management, and drag-and-drop; adds Chrome args and safer teardown.
Fixtures
test/fixtures/drag-drop.html, test/fixtures/alerts.html
Adds result display and event handling for drag-and-drop; adds alert-result DOM update for alert tests.
Other test updates
test/interactions.test.mjs, test/navigation.test.mjs, test/bidi.test.mjs
Replaces legacy per-tool calls with new tool signatures and action/type parameters across multiple test files (selector/value preservation noted).

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client (MCP client)
    participant Server as MCP Selenium Server
    participant Browser as Browser (BiDi)

    Client->>Server: tool call "interact" {action: "click", selector}
    Server->>Browser: BiDi command (resolve element, perform click)
    Browser-->>Server: BiDi event/result (success or error)
    Server-->>Client: tool response (OK / standardized error)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hopped through code, found tools too many,
I nudged them close — now five are plenty.
Interact, frame, window, alert, diagnostics sing,
Tests and docs dance round the new spring.
🥕 Little rabbit applauds the tidy thing.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the primary objective of the PR: consolidating 32 tools down to 18, which is the main architectural change driving all other modifications.
Linked Issues check ✅ Passed The PR fully addresses issue #60's requirement to reduce the number of tools and lower context token costs by consolidating from 32 to 18 tools through targeted mergers of related functionality.
Out of Scope Changes check ✅ Passed Documentation updates (README, AGENTS.md), version bump, GitHub Actions workflow, and test improvements are all aligned with preparing for a major version release following the tool consolidation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/consolidate-tools

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (6)
test/fixtures/drag-drop.html (1)

31-33: Consider also cancelling dragenter for broader browser compatibility.

Some browsers (notably older Firefox versions) require both dragenter and dragover to call e.preventDefault() for a drop target to accept drops. Since CI runs tests across multiple browsers, adding the dragenter handler is low-risk and defensive.

♻️ Proposed addition of dragenter handler
+    droppable.addEventListener('dragenter', (e) => {
+      e.preventDefault();
+    });
+
     droppable.addEventListener('dragover', (e) => {
       e.preventDefault();
     });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/fixtures/drag-drop.html` around lines 31 - 33, The drop target currently
calls e.preventDefault() only in the 'dragover' listener; add an analogous
'dragenter' listener on the same element
(droppable.addEventListener('dragenter', ...)) that calls e.preventDefault() to
ensure older browsers accept drops. Locate the existing
droppable.addEventListener('dragover', ...) and add a matching
droppable.addEventListener('dragenter', (e) => { e.preventDefault(); }) handler
to the same scope so tests run consistently across browsers.
.github/workflows/publish.yml (1)

7-27: Consider running tests before publishing.

The workflow installs dependencies but does not run npm test before npm publish. A failing test suite would still result in a broken release being published to npm.

Suggested addition
       - name: Install dependencies
         run: npm ci
 
+      - name: Run tests
+        run: npm test
+
       - name: Publish to npm
         run: npm publish --access public
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish.yml around lines 7 - 27, The publish job currently
installs dependencies then runs npm publish without verifying tests; add a step
in the publish job (between the "Install dependencies" step and the "Publish to
npm" step) that runs the test suite (e.g., run: npm test) so the workflow fails
on test failures before publishing; ensure the new step is named clearly (e.g.,
"Run tests") and uses the same job context so NODE_AUTH_TOKEN and installed deps
are available.
README.md (1)

16-19: Add a language identifier to the fenced code block.

Static analysis (markdownlint MD040) flags this code block as missing a language specifier. Since this is a plain URL, text is appropriate.

Suggested fix
 Paste into your browser address bar:
-```
+```text
 goose://extension?cmd=npx&arg=-y&arg=%40angiejones%2Fmcp-selenium&id=selenium-mcp&name=Selenium%20MCP&description=automates%20browser%20interactions
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @README.md around lines 16 - 19, Update the fenced code block that contains
the goose://extension URL so it includes a language identifier; change the
opening fence from totext to satisfy markdownlint MD040 and make it
explicit that the block is plain text (the block containing
"goose://extension?cmd=npx&arg=-y&arg=%40angiejones%2Fmcp-selenium…").


</details>

</blockquote></details>
<details>
<summary>AGENTS.md (1)</summary><blockquote>

`7-13`: **Add a language identifier to the file-map code block.**

Static analysis (markdownlint MD040) flags this block. `text` is appropriate here.

<details>
<summary>Suggested fix</summary>

````diff
-```
+```text
 src/lib/server.js      ← ALL server logic: tool definitions, state, helpers, cleanup
 src/index.js           ← Thin CLI wrapper, spawns server.js as child process
 test/mcp-client.mjs    ← Reusable MCP test client (JSON-RPC over stdio)
 test/*.test.mjs        ← Tests grouped by feature
 test/fixtures/*.html   ← HTML files loaded via file:// URLs in tests
 ```
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@AGENTS.md` around lines 7 - 13, Update the code block in AGENTS.md that lists
the file map (the block containing "src/lib/server.js ← ALL server logic: tool
definitions, state, helpers, cleanup" through "test/fixtures/*.html ← HTML files
loaded via file:// URLs in tests") by adding the language identifier "text"
after the opening backticks (i.e., change ``` to ```text) so markdownlint MD040
is satisfied; keep the block content unchanged aside from the language tag.
test/new-tools.test.mjs (2)

55-58: assert.ok(length > 0) only confirms a non-empty response; pin it to the fixture's known title.

The guideline requires asserting the expected DOM/system effect. Since interactions.html has a predictable <title>, asserting the exact value makes the test self-documenting and closes the gap between "something returned" and "the right thing returned."

♻️ Proposed fix
-      const result = await client.callTool('execute_script', { script: 'return document.title;' });
-      assert.ok(getResponseText(result).length > 0);
+      const result = await client.callTool('execute_script', { script: 'return document.title;' });
+      assert.equal(getResponseText(result), 'Interactions');  // match the actual <title> in interactions.html
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/new-tools.test.mjs` around lines 55 - 58, The test currently only checks
that getResponseText(result).length > 0; change it to assert the exact expected
title from the interactions.html fixture so the test verifies the correct DOM
effect. Locate the test using client.callTool('execute_script', { script:
'return document.title;' }) in new-tools.test.mjs and replace the loose length
assertion on getResponseText(result) with a strict equality assertion against
the known title string (the expected <title> value in interactions.html).

166-179: "window close" hard-asserts 2 windows exist, creating implicit dependency on the prior sibling test.

Line 169 (assert.equal(data.all.length, 2)) passes only when "window switch_latest after opening new tab" has already run and left the new tab open. If that test fails mid-execution (e.g., switch_latest throws), the close test will fail at the assertion with a confusing 2 !== 1 message rather than revealing the real cause.

Consider either adding the tab-open setup to this test's body or the before hook:

♻️ Proposed fix
     it('window close closes tab and switches back', async () => {
+      // Ensure a second window/tab is open before testing close
+      await client.callTool('execute_script', { script: "window.open('about:blank', '_blank');" });
       let result = await client.callTool('window', { action: 'list' });
       const data = JSON.parse(getResponseText(result));
       assert.equal(data.all.length, 2);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/new-tools.test.mjs` around lines 166 - 179, The test "window close
closes tab and switches back" currently assumes two windows exist by asserting
data.all.length === 2 (variable data from client.callTool('window', { action:
'list' })), creating an implicit dependency on another test; fix it by making
the test self-contained: before asserting, open a new tab (e.g., via
client.callTool('window', { action: 'open', ... }) or add a before hook that
ensures there are two windows), then re-run the list to get a deterministic
data.all array, proceed to switch to data.all[1], close it, and finally assert
the count decreased to 1; ensure any created tab is cleaned up so this test
doesn't depend on sibling tests or leave state behind.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/server.js`:
- Around line 14-17: The hardcoded version passed to new McpServer({ name: "MCP
Selenium", version: "1.0.0" }) is out of sync with package.json; update the code
to read the real package version (e.g., require or import the package.json and
use its version field) and pass that value to the McpServer constructor (keep
the McpServer call and server variable intact, just replace the string "1.0.0"
with the package.json-derived version).
- Around line 551-564: The call to driver.getAllWindowHandles() inside the
'close' case can throw after the last window is closed, preventing session
cleanup; modify the 'close' handling so you treat a failed getAllWindowHandles()
as an empty handles list (e.g., wrap getAllWindowHandles() in its own try/catch
and set handles = [] on error) and ensure the cleanup code that calls
driver.quit(), state.drivers.delete(sessionId), state.bidi.delete(sessionId),
and state.currentSession = null always runs when no handles remain; keep the
existing branch that switches to handles[0] when handles.length > 0 and only
perform the quit/delete cleanup when handles is empty or getting handles failed.

In `@test/new-tools.test.mjs`:
- Line 26: The test calls client.callTool('close_session') without the arguments
object; make it consistent with other tests by calling
client.callTool('close_session', {}) instead. Locate the invocation of
client.callTool('close_session') in the test/new-tools.test.mjs file and change
it to pass an empty object as the second parameter so the call matches other
tests (e.g., bidi.test.mjs) and avoids relying on JSON.stringify dropping
undefined.
- Around line 242-246: The "alert accept" test only asserts the server response
text — update the test that calls client.callTool('alert', { action: 'accept' })
to also verify the DOM effect by selecting the page element that indicates alert
acceptance (e.g., the element with id 'alert-result') and asserting its text
equals the expected value ("Alert accepted"); if the alerts fixture doesn't
currently update the DOM, add a minimal DOM indicator (an element like <div
id="alert-result">) and update the page script to set its text on alert
acceptance so the test can assert the UI change instead of relying solely on
getResponseText(result).

---

Nitpick comments:
In @.github/workflows/publish.yml:
- Around line 7-27: The publish job currently installs dependencies then runs
npm publish without verifying tests; add a step in the publish job (between the
"Install dependencies" step and the "Publish to npm" step) that runs the test
suite (e.g., run: npm test) so the workflow fails on test failures before
publishing; ensure the new step is named clearly (e.g., "Run tests") and uses
the same job context so NODE_AUTH_TOKEN and installed deps are available.

In `@AGENTS.md`:
- Around line 7-13: Update the code block in AGENTS.md that lists the file map
(the block containing "src/lib/server.js ← ALL server logic: tool definitions,
state, helpers, cleanup" through "test/fixtures/*.html ← HTML files loaded via
file:// URLs in tests") by adding the language identifier "text" after the
opening backticks (i.e., change ``` to ```text) so markdownlint MD040 is
satisfied; keep the block content unchanged aside from the language tag.

In `@README.md`:
- Around line 16-19: Update the fenced code block that contains the
goose://extension URL so it includes a language identifier; change the opening
fence from ``` to ```text to satisfy markdownlint MD040 and make it explicit
that the block is plain text (the block containing
"goose://extension?cmd=npx&arg=-y&arg=%40angiejones%2Fmcp-selenium…").

In `@test/fixtures/drag-drop.html`:
- Around line 31-33: The drop target currently calls e.preventDefault() only in
the 'dragover' listener; add an analogous 'dragenter' listener on the same
element (droppable.addEventListener('dragenter', ...)) that calls
e.preventDefault() to ensure older browsers accept drops. Locate the existing
droppable.addEventListener('dragover', ...) and add a matching
droppable.addEventListener('dragenter', (e) => { e.preventDefault(); }) handler
to the same scope so tests run consistently across browsers.

In `@test/new-tools.test.mjs`:
- Around line 55-58: The test currently only checks that
getResponseText(result).length > 0; change it to assert the exact expected title
from the interactions.html fixture so the test verifies the correct DOM effect.
Locate the test using client.callTool('execute_script', { script: 'return
document.title;' }) in new-tools.test.mjs and replace the loose length assertion
on getResponseText(result) with a strict equality assertion against the known
title string (the expected <title> value in interactions.html).
- Around line 166-179: The test "window close closes tab and switches back"
currently assumes two windows exist by asserting data.all.length === 2 (variable
data from client.callTool('window', { action: 'list' })), creating an implicit
dependency on another test; fix it by making the test self-contained: before
asserting, open a new tab (e.g., via client.callTool('window', { action: 'open',
... }) or add a before hook that ensures there are two windows), then re-run the
list to get a deterministic data.all array, proceed to switch to data.all[1],
close it, and finally assert the count decreased to 1; ensure any created tab is
cleaned up so this test doesn't depend on sibling tests or leave state behind.

Comment thread src/lib/server.js
Comment thread src/lib/server.js
Comment thread test/new-tools.test.mjs Outdated
Comment thread test/new-tools.test.mjs Outdated
- Read version from package.json instead of hardcoding 1.0.0
- Guard getAllWindowHandles() after last window close (session may be gone)
- Pass {} to close_session in test teardown for consistency
- Add alert-result DOM indicator to alerts fixture
- Verify DOM effect in alert accept test
- Remove stale comment about find_element history
- Rename new-tools.test.mjs → tools.test.mjs
@angiejones angiejones changed the title Refactor: consolidate 32 tools → 18 (closes #60) Refactor: consolidate 32 tools → 18 Feb 22, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@AGENTS.md`:
- Around line 7-13: The fenced code block containing the file map (lines
starting with "src/lib/server.js", "src/index.js", "test/mcp-client.mjs", etc.)
is missing a language identifier; update that opening ``` to ```text (or
```plaintext) so the block is recognized as plain text and the MD040 lint
warning is resolved—edit the block that lists src/lib/server.js, src/index.js,
test/mcp-client.mjs, test/*.test.mjs, and test/fixtures/*.html to include the
language specifier.

In `@test/tools.test.mjs`:
- Line 13: Top-level describe label is stale: rename the describe call that
currently reads describe('new-tools', () => { to describe('tools', () => { so
the test suite name matches the file tools.test.mjs and test-runner filtering;
update the string literal in the describe invocation (the describe('new-tools',
...) occurrence) to 'tools'.

Comment thread AGENTS.md Outdated
Comment thread test/tools.test.mjs Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
AGENTS.md (2)

41-58: Mention registerBidiTool() for diagnostic tools.

The "Adding a Tool" section only shows the generic server.tool() pattern. Agents adding a BiDi/diagnostic tool would copy that pattern instead of using the registerBidiTool() factory, duplicating handler logic.

📝 Suggested addition after line 57
 });

+For diagnostic (BiDi) tools — those that read consoleLogs, pageErrors, or networkLogs — use the registerBidiTool() factory instead of server.tool() directly. Do not copy-paste the BiDi handler boilerplate.

</details>



Based on learnings: "Use the `registerBidiTool()` factory function to register diagnostic tools (`get_console_logs`, `get_page_errors`, `get_network_logs`); do not copy-paste diagnostic tool handlers"

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @AGENTS.md around lines 41 - 58, The docs currently only show server.tool()
for adding tools which leads authors to copy BiDi/diagnostic handlers; update
the "Adding a Tool" section to mention and instruct using registerBidiTool() for
diagnostic tools (e.g., get_console_logs, get_page_errors, get_network_logs)
instead of server.tool(), and add a short note after the existing pattern
directing readers to use registerBidiTool() to avoid duplicating BiDi handler
boilerplate and ensure proper registration of consoleLogs/pageErrors/networkLogs
collectors.


</details>

---

`62-82`: **Document the `fixture()` helper in the Testing section.**

The Testing section lists fixture files and test modules but never tells an agent how to reference fixture HTML files. The `fixture()` helper from `mcp-client.mjs` is the designated way to resolve `test/fixtures/*.html` paths; omitting it risks agents hand-rolling path resolution and breaking portability.

<details>
<summary>📝 Suggested addition after line 72</summary>

```diff
 **Verify outcomes, not absence of errors.** If you click a button, check that the thing it did actually happened. If a test is failing, fix the code — never weaken the assertion.
+
+Use the `fixture(filename)` helper from `mcp-client.mjs` to resolve `file://` URLs for HTML fixtures:
+```js
+import { McpClient, fixture } from './mcp-client.mjs';
+const url = fixture('form.html'); // → file:///abs/path/to/test/fixtures/form.html
+```

Based on learnings: "Use the fixture() helper from mcp-client.mjs to resolve paths to HTML test fixture files in test/fixtures/"

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@AGENTS.md` around lines 62 - 82, Add documentation describing the fixture()
helper exported from mcp-client.mjs so agents know to use it to resolve test
fixture HTML paths; specifically state that tests should import fixture (and
optionally McpClient) from './mcp-client.mjs' and call fixture('form.html') to
obtain a file:// absolute URL for files under test/fixtures/, and include the
short usage example showing the import and fixture(...) call to resolve a
fixture path.
test/tools.test.mjs (1)

138-179: Window tests carry implicit sequential state dependencies.

Tests 2 ("switch_latest"), 3 ("switch switches back"), and 4 ("close closes tab") form a chain: test 2 opens a second window and stays on it; test 3 relies on two windows still being open; test 4 asserts data.all.length === 2 and targets data.all[1]. A mid-test failure in test 2 or 3 cascades into a misleading failure in subsequent tests.

Consider opening a fresh about:blank tab in the before of test 3/4, or closing the extra window in test 2's cleanup, so each test is self-contained.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/tools.test.mjs` around lines 138 - 179, The window tests depend on
shared browser state; make each test self-contained by ensuring any opened tab
is cleaned up or a fresh tab is created for the test: for the tests using
client.callTool('window', {...}) (notably the "window switch_latest", "window
switch switches back", and "window close closes tab" it blocks) either (A) open
a new about:blank tab via client.callTool('execute_script', { script:
"window.open('about:blank','_blank')" }) in a before hook and use that handle
for the test, or (B) ensure the test that opens a second window explicitly
closes it at the end (callTool('window', { action: 'close' })) so subsequent
tests start with a single window; update the tests that reference data.all[1],
switch, and close to use the created handle or rely on the cleaned state.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/tools.test.mjs`:
- Around line 55-58: The test "executes script and returns a string result"
currently only checks non-empty output; update it to assert the exact page title
by replacing the assert.ok(...) with assert.equal(getResponseText(result),
'<expected title>'); locate the test that calls
client.callTool('execute_script', { script: 'return document.title;' }) and use
getResponseText(result) with assert.equal to compare against the known title
string from interactions.html so the test verifies the exact expected value.

---

Nitpick comments:
In `@AGENTS.md`:
- Around line 41-58: The docs currently only show server.tool() for adding tools
which leads authors to copy BiDi/diagnostic handlers; update the "Adding a Tool"
section to mention and instruct using registerBidiTool() for diagnostic tools
(e.g., get_console_logs, get_page_errors, get_network_logs) instead of
server.tool(), and add a short note after the existing pattern directing readers
to use registerBidiTool() to avoid duplicating BiDi handler boilerplate and
ensure proper registration of consoleLogs/pageErrors/networkLogs collectors.
- Around line 62-82: Add documentation describing the fixture() helper exported
from mcp-client.mjs so agents know to use it to resolve test fixture HTML paths;
specifically state that tests should import fixture (and optionally McpClient)
from './mcp-client.mjs' and call fixture('form.html') to obtain a file://
absolute URL for files under test/fixtures/, and include the short usage example
showing the import and fixture(...) call to resolve a fixture path.

In `@test/tools.test.mjs`:
- Around line 138-179: The window tests depend on shared browser state; make
each test self-contained by ensuring any opened tab is cleaned up or a fresh tab
is created for the test: for the tests using client.callTool('window', {...})
(notably the "window switch_latest", "window switch switches back", and "window
close closes tab" it blocks) either (A) open a new about:blank tab via
client.callTool('execute_script', { script:
"window.open('about:blank','_blank')" }) in a before hook and use that handle
for the test, or (B) ensure the test that opens a second window explicitly
closes it at the end (callTool('window', { action: 'close' })) so subsequent
tests start with a single window; update the tests that reference data.all[1],
switch, and close to use the created handle or rely on the cleaned state.

Comment thread test/tools.test.mjs
@angiejones angiejones merged commit 7c690d0 into main Feb 22, 2026
4 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Feb 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refactor to use less tools

1 participant