feat: #3608867 Add a browser_navigate tool for stateful, multi-page browser navigation.

This MR implements the browser_navigate AI Agent tool proposed in #3608867.

What / Why

browser_preview opens each page in a throwaway browser, so it cannot walk a multi-page flow (open a Drupal Canvas page, go back, go forward, reload) and it re-establishes login on every call. An AI agent verifying a build across several pages loses its session and its navigation history between calls.

This adds a stateful navigation runner that persists the browser session (cookies via Playwright storageState) and a navigation history stack in a per-user state file between calls, so goto / back / forward / reload (and interactions: click / type / scroll / wait / resize) work across separate tool invocations, with login established only once.

Changes

  • scripts/browser-navigate.mjs (new): restores storageState + history from a state file, performs one action, saves state back, returns url/title/text/console/screenshot/history/index/canGoBack/canGoForward.
  • src/PlaywrightRunner.php: added navigate() + navigateScriptPath() — resolves goto URLs with the same same-host guard as capture(), runs the script per acting user, saves the screenshot as a managed file.
  • src/Plugin/AiFunctionCall/BrowserNavigate.php (new): the #[FunctionCall] tool, one action JSON argument, same use ai playwright permission gate as browser_preview.

Testing

Verified locally end-to-end: goto -> goto -> back -> forward -> reload keeps an authenticated session and correct history across separate process calls; each step saves a screenshot file. phpcs (Drupal + DrupalPractice) is clean.

AI-Generated: Yes (Used Claude Code to implement the runner/tool and verify locally; human-reviewed before pushing.)

Update: page-verification actions

Extends the browser_navigate action DSL so an agent can check whether the current page did a good job, not just look at it, and decide whether to fix it. New actions, each returning a pass/fail with a detail string in the result:

  • assertText / assertNoText — text present/absent on the page.
  • assertVisible / assertHidden — element visibility by selector.
  • assertCount — expected number of matches for a selector.
  • assertUrl — current URL matches/contains the expected value.
  • assertNoConsoleErrors — no console.error entries since the last action.
  • A dependency-free a11y check for WCAG basics: missing alt text, controls without an accessible name, unlabelled form fields, skipped heading levels.

Changes: scripts/browser-navigate.mjs, src/PlaywrightRunner.php, src/Plugin/AiFunctionCall/BrowserNavigate.php.

AI-Generated: Yes (Used Claude Code, human-reviewed)

Hardening: audit-driven fixes

A follow-up audit of the browser_navigate runner found a few robustness issues; this update (ed4cbb7) fixes them:

  • Close the browser on error paths — a failure used to skip the finally (via process.exit) and orphan a headless Chromium process on every failed call.
  • Bound each smartSettle wait by the remaining time budget instead of timeout:0, which Playwright treats as wait-forever and could hang the tool on a live/chatty page.
  • Cap the navigation history stack at 50 entries so the per-user state file and response payload stay bounded over a long session.
  • assertCount now rejects a missing/non-numeric count instead of silently comparing against NaN.
  • Clamp a stale/corrupt saved history index into range immediately on load, so it can't drive page.goto(undefined).

AI-Generated: Yes (Used Claude Code to implement and verify the hardening fixes; human-reviewed before pushing.)

Checkpoints

  • File an issue about this project
  • Addition/Change/Update/Fix to this project
  • Testing to ensure no regression
  • Automated unit/functional testing coverage
  • Developer Documentation support on feature change/addition
  • User Guide Documentation support on feature change/addition
  • UX/UI designer responsibilities
  • Accessibility and Readability
  • Reviewed by a human
  • Code review by maintainers
  • Full testing and approval
  • Credit contributors
  • Review with the product owner
  • Update Release Notes
  • Release
Edited by Rajab Natshah

Merge request reports

Loading
Loading