URL matching
A page object knows its own URL, so its navigation helper can go there and wait for it. This page explains how the URL
parts are checked, how fullUrl is made, and how a page whose URL varies is matched. How to set a page object’s URL is
on URLs and navigation.
The checks
Section titled “The checks”A page object’s baseUrl and urlPath are each a string or a RegExp. The constructor checks the strings with the
helpers in src/helpers/url.ts:
baseUrl: an origin, whichnew URLparses with a host and nothing after it but an optional/. Playwright resolves a path that starts with/against the origin of itsbaseURL, dropping any path the base had, and a scheme-lesslocalhost:9000parses as a URL with the schemelocalhost:; both are rejected so that no page object is built on a base that resolves differently than it reads.urlPath:""or a string that starts with exactly one/;//shop.example/xwould name another host.- neither a string nor a RegExp, usually an unset environment variable: rejected, because it would build a page object that matches nothing.
fullUrl
Section titled “fullUrl”composeFullUrl makes the page’s identity:
- Two strings:
new URL(urlPath, baseUrl).href, the resolution Playwright applies topage.goto(path)againstbaseURL, and the form the browser reports:https://shop.example/for an empty path,/s%C3%B8kfor/søk. - A RegExp in either part: a
UrlMatcher.
UrlMatcher
Section titled “UrlMatcher”A UrlMatcher is a function from a URL to a boolean, with base, path, test() and toString(). It tests the two
parts of a URL apart:
- the base against
url.origin: a RegExp as written, a string by equality with its own origin; - the path against
pathname + search + hash: a RegExp as written, a string by equality with the formnew URLgives it.
Each RegExp is used with its own flags, and its lastIndex is reset before each test, so a g or y flag cannot make
a second test start where the first stopped. No anchors are added or removed.
In 2.x, the two parts were joined into one RegExp, which made a base RegExp match up to the exact character where the
path began, dropped the flags, and broke a ^ on the path. Testing the parts apart uses the seam the URL parser already
provides, and a base such as /identity-provider/ matches any host that contains it.
Playwright’s waitForURL, toHaveURL and route accept a URL predicate, so the matcher is passed to them as it is.
The navigation helper builds a matcher for every page object, a string fullUrl included, and waits with it: a page
is matched in the form the browser reports, so /søk matches the percent-encoded URL the browser shows.
Alternatives weighed
Section titled “Alternatives weighed”- One composed RegExp with a filler between the parts. The base would have to match up to the exact character
where the path begins, so a base such as
/identity-provider/would never match. - A
RegExpsubclass asfullUrl. Playwright sends a RegExp to the browser as its source and flags, so the subclass’s own matching would never run. - An option to ignore the query. One rule, identical to Playwright’s
toHaveURL, keepsexpectThisPageandexpectAnotherPageexact opposites; a page whose query varies has a RegExp path instead. - Literal types for the URL parts. They catch only a malformed literal, which the constructor check catches at the same moment, and they make every value from the environment need a cast.