Skip to content

Dispatch route events to the handler that registered them - #182

Open
Mir-Zairan wants to merge 5 commits into
playwright-php:mainfrom
Mir-Zairan:fix/route-handler-chain
Open

Mir-Zairan wants to merge 5 commits into
playwright-php:mainfrom
Mir-Zairan:fix/route-handler-chain

Conversation

@Mir-Zairan

@Mir-Zairan Mir-Zairan commented Oct 1, 2026 •

Copy link
Copy Markdown

With more than one route() handler, every PHP handler runs on every request, so two handlers answer the same request and whichever is first wins. Playwright runs only the newest matching route, and fallback() hands the request to the next one.

This makes route() work that way on pages and contexts. Each registration gets an id that the server sends back with its route events, so only that handler runs. The server now handles fallback(), which used to hang until it timed out. Route ids no longer clash between pages and contexts. unroute($url, $handler) removes only that handler.

Behaviour change: the newest route answers, and a handler must call fallback(), not continue(), to let an older route answer.

New functional tests cover the chain from page to page, page to context, and context to the network, plus unroute. All of them failed before this change. playwright-php/playwright-symfony#59 makes its kernel route work with this.

Route::fallback() sent route.fallback, but the server never registered it,
so the request was left unanswered until it timed out. Pass it on to
Playwright's own fallback so the next matching route or the network answers.
Every page route event ran all handlers added with route(), so the oldest
handler answered, unrelated patterns ran and fallback() never reached an
older route. Each registration now carries its own id through the server.
…trations

Page routes counted ids on a copy of the route counter, so a page route and a
context route could both be route_1 and answer each other's requests. Route
registrations now live with the other server maps, are dropped when their page
or context closes, and a failed route() no longer leaves its handler behind.
Context routes ran the oldest handler whose fnmatch() pattern matched, so the
newest route never answered, fallback() could not reach an older route and
unroute() with a handler dropped every route on the URL. They now use the same
per-registration ids as page routes.
A rejected context route stayed registered, and a context closed with its
browser kept its route registrations on the server. Route events with a bad
handlerId now fall back on pages and contexts alike instead of hanging or throwing.
@codecov

codecov Bot commented Oct 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Mir-Zairan added a commit to Mir-Zairan/playwright-symfony that referenced this pull request Oct 1, 2026
Temporary: CI needs playwright-php/playwright#182 to run the new route tests. Drop this commit and raise the constraint once that fix is released.
@Mir-Zairan

Copy link
Copy Markdown
Author

@smnandre Kindly review the PR, thanks!

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.

1 participant