diff --git a/docs/api.md b/docs/api.md index 2ea97c9d45..31568e6903 100644 --- a/docs/api.md +++ b/docs/api.md @@ -520,8 +520,8 @@ Indicates that the browser is connected. - `hasTouch`<[boolean]> Specifies if viewport supports touch events. Defaults to `false` - `isLandscape` <[boolean]> Specifies if viewport is in landscape mode. Defaults to `false`. - `userAgent` Specific user agent to use in this page - - `mediaType` Changes the CSS media type of the page. The only allowed values are `'screen'`, `'print'` and `null`. Passing `null` disables CSS media emulation. - - `colorScheme` Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. + - `mediaType` Changes the CSS media type of the page. + - `colorScheme` Emulates `'prefers-colors-scheme'` media feature. - `javaScriptEnabled` Whether or not to enable or disable JavaScript in the page. Defaults to true. - `timezoneId` Changes the timezone of the page. See [ICU’s `metaZones.txt`](https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt?rcl=faee8bc70570192d82d2978a71e2a615788597d1) for a list of supported timezone IDs. - returns: <[Promise]<[BrowserContext]>> @@ -1325,7 +1325,7 @@ Shortcut for [page.mainFrame().focus(selector)](#framefocusselector). #### page.goBack([options]) - `options` <[Object]> Navigation parameters which might have the following properties: - `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. - - `waitUntil` <[string]|[Array]<[string]>> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either: + - `waitUntil` <"load"|"domcontentloaded"|"networkidle0"|"networkidle2"|[Array]<"load"|"domcontentloaded"|"networkidle0"|"networkidle2">> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either: - `load` - consider navigation to be finished when the `load` event is fired. - `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired. - `networkidle0` - consider navigation to be finished when there are no more than 0 network connections for at least `500` ms. @@ -1338,7 +1338,7 @@ Navigate to the previous page in history. #### page.goForward([options]) - `options` <[Object]> Navigation parameters which might have the following properties: - `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. - - `waitUntil` <[string]|[Array]<[string]>> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either: + - `waitUntil` <"load"|"domcontentloaded"|"networkidle0"|"networkidle2"|[Array]<"load"|"domcontentloaded"|"networkidle0"|"networkidle2">> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either: - `load` - consider navigation to be finished when the `load` event is fired. - `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired. - `networkidle0` - consider navigation to be finished when there are no more than 0 network connections for at least `500` ms. @@ -1352,7 +1352,7 @@ Navigate to the next page in history. - `url` <[string]> URL to navigate page to. The url should include scheme, e.g. `https://`. - `options` <[Object]> Navigation parameters which might have the following properties: - `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. - - `waitUntil` <[string]|[Array]<[string]>> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either: + - `waitUntil` <"load"|"domcontentloaded"|"networkidle0"|"networkidle2"|[Array]<"load"|"domcontentloaded"|"networkidle0"|"networkidle2">> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either: - `load` - consider navigation to be finished when the `load` event is fired. - `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired. - `networkidle0` - consider navigation to be finished when there are no more than 0 network connections for at least `500` ms. @@ -1417,7 +1417,7 @@ Page is guaranteed to have a main frame which persists during navigations. #### page.reload([options]) - `options` <[Object]> Navigation parameters which might have the following properties: - `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. - - `waitUntil` <[string]|[Array]<[string]>> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either: + - `waitUntil` <"load"|"domcontentloaded"|"networkidle0"|"networkidle2"|[Array]<"load"|"domcontentloaded"|"networkidle0"|"networkidle2">> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either: - `load` - consider navigation to be finished when the `load` event is fired. - `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired. - `networkidle0` - consider navigation to be finished when there are no more than 0 network connections for at least `500` ms. @@ -1477,7 +1477,7 @@ Toggles ignoring cache for each request based on the enabled state. By default, - `html` <[string]> HTML markup to assign to the page. - `options` <[Object]> Parameters which might have the following properties: - `timeout` <[number]> Maximum time in milliseconds for resources to load, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. - - `waitUntil` <[string]|[Array]<[string]>> When to consider setting markup succeeded, defaults to `load`. Given an array of event strings, setting content is considered to be successful after all events have been fired. Events can be either: + - `waitUntil` <"load"|"domcontentloaded"|"networkidle0"|"networkidle2"|[Array]<"load"|"domcontentloaded"|"networkidle0"|"networkidle2">> When to consider setting markup succeeded, defaults to `load`. Given an array of event strings, setting content is considered to be successful after all events have been fired. Events can be either: - `load` - consider setting content to be finished when the `load` event is fired. - `domcontentloaded` - consider setting content to be finished when the `DOMContentLoaded` event is fired. - `networkidle0` - consider setting content to be finished when there are no more than 0 network connections for at least `500` ms. @@ -1671,7 +1671,8 @@ Shortcut for [page.mainFrame().waitForFunction(pageFunction[, options[, ...args] #### page.waitForNavigation([options]) - `options` <[Object]> Navigation parameters which might have the following properties: - `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. - - `waitUntil` <[string]|[Array]<[string]>> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either: + - `url` <[string]|[RegExp]|[Function]> URL string, URL regex pattern or predicate receiving [URL] to match while waiting for the navigation. + - `waitUntil` <"load"|"domcontentloaded"|"networkidle0"|"networkidle2"|[Array]<"load"|"domcontentloaded"|"networkidle0"|"networkidle2">> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either: - `load` - consider navigation to be finished when the `load` event is fired. - `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired. - `networkidle0` - consider navigation to be finished when there are no more than 0 network connections for at least `500` ms. @@ -1693,7 +1694,7 @@ const [response] = await Promise.all([ Shortcut for [page.mainFrame().waitForNavigation(options)](#framewaitfornavigationoptions). #### page.waitForRequest(urlOrPredicate[, options]) -- `urlOrPredicate` <[string]|[Function]> A URL or predicate to wait for. +- `urlOrPredicate` Optional. Request URL string, regex or predicate receiving [Request] object. - `options` <[Object]> Optional waiting parameters - `timeout` <[number]> Maximum wait time in milliseconds, defaults to 30 seconds, pass `0` to disable the timeout. The default value can be changed by using the [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) method. - returns: <[Promise]<[Request]>> Promise which resolves to the matched request. @@ -1704,8 +1705,12 @@ const finalRequest = await page.waitForRequest(request => request.url() === 'htt return firstRequest.url(); ``` +```js +await page.waitForRequest(request => request.url().searchParams.get('foo') === 'bar' && request.url().searchParams.get('foo2') === 'bar2'); +``` + #### page.waitForResponse(urlOrPredicate[, options]) -- `urlOrPredicate` <[string]|[Function]> A URL or predicate to wait for. +- `urlOrPredicate` Optional. Request URL string, regex or predicate receiving [Response] object. - `options` <[Object]> Optional waiting parameters - `timeout` <[number]> Maximum wait time in milliseconds, defaults to 30 seconds, pass `0` to disable the timeout. The default value can be changed by using the [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) method. - returns: <[Promise]<[Response]>> Promise which resolves to the matched response. @@ -2473,7 +2478,7 @@ If there's no element matching `selector`, the method throws an error. - `url` <[string]> URL to navigate frame to. The url should include scheme, e.g. `https://`. - `options` <[Object]> Navigation parameters which might have the following properties: - `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. - - `waitUntil` <[string]|[Array]<[string]>> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either: + - `waitUntil` <"load"|"domcontentloaded"|"networkidle0"|"networkidle2"|[Array]<"load"|"domcontentloaded"|"networkidle0"|"networkidle2">> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either: - `load` - consider navigation to be finished when the `load` event is fired. - `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired. - `networkidle0` - consider navigation to be finished when there are no more than 0 network connections for at least `500` ms. @@ -2553,7 +2558,7 @@ frame.select('select#colors', { value: 'blue' }, { index: 2 }, 'red'); - `html` <[string]> HTML markup to assign to the page. - `options` <[Object]> Parameters which might have the following properties: - `timeout` <[number]> Maximum time in milliseconds for resources to load, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. - - `waitUntil` <[string]|[Array]<[string]>> When to consider setting markup succeeded, defaults to `load`. Given an array of event strings, setting content is considered to be successful after all events have been fired. Events can be either: + - `waitUntil` <"load"|"domcontentloaded"|"networkidle0"|"networkidle2"|[Array]<"load"|"domcontentloaded"|"networkidle0"|"networkidle2">> When to consider setting markup succeeded, defaults to `load`. Given an array of event strings, setting content is considered to be successful after all events have been fired. Events can be either: - `load` - consider setting content to be finished when the `load` event is fired. - `domcontentloaded` - consider setting content to be finished when the `DOMContentLoaded` event is fired. - `networkidle0` - consider setting content to be finished when there are no more than 0 network connections for at least `500` ms. @@ -2666,7 +2671,8 @@ await page.waitForFunction(selector => !!document.querySelector(selector), {}, s #### frame.waitForNavigation([options]) - `options` <[Object]> Navigation parameters which might have the following properties: - `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. - - `waitUntil` <[string]|[Array]<[string]>> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either: + - `url` <[string]|[RegExp]|[Function]> URL string, URL regex pattern or predicate receiving [URL] to match while waiting for the navigation. + - `waitUntil` <"load"|"domcontentloaded"|"networkidle0"|"networkidle2"|[Array]<"load"|"domcontentloaded"|"networkidle0"|"networkidle2">> When to consider navigation succeeded, defaults to `load`. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either: - `load` - consider navigation to be finished when the `load` event is fired. - `domcontentloaded` - consider navigation to be finished when the `DOMContentLoaded` event is fired. - `networkidle0` - consider navigation to be finished when there are no more than 0 network connections for at least `500` ms. @@ -3573,12 +3579,14 @@ const playwright = require('playwright'); [Object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object "Object" [Page]: #class-page "Page" [Promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise "Promise" +[RegExp]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp [Request]: #class-request "Request" [Response]: #class-response "Response" [Serializable]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description "Serializable" [Target]: #class-target "Target" [TimeoutError]: #class-timeouterror "TimeoutError" [UIEvent.detail]: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail "UIEvent.detail" +[URL]: https://nodejs.org/api/url.html [USKeyboardLayout]: ../lib/USKeyboardLayout.js "USKeyboardLayout" [UnixTime]: https://en.wikipedia.org/wiki/Unix_time "Unix Time" [Worker]: #class-worker "Worker" diff --git a/src/frames.ts b/src/frames.ts index d4bd5606e0..d1afc71b89 100644 --- a/src/frames.ts +++ b/src/frames.ts @@ -42,7 +42,7 @@ export type NavigateOptions = { waitUntil?: LifecycleEvent | LifecycleEvent[], }; -export type WaitForNavigationOptions = NavigateOptions & types.URLMatch; +export type WaitForNavigationOptions = NavigateOptions & { url?: types.URLMatch }; export type GotoOptions = NavigateOptions & { referer?: string, @@ -854,9 +854,9 @@ class LifecycleWatcher { private _navigationAbortedCallback: (err: Error) => void; private _maximumTimer: NodeJS.Timer; private _hasSameDocumentNavigation: boolean; - private _targetUrl?: string; - private _expectedDocumentId?: string; - private _urlMatch?: types.URLMatch; + private _targetUrl: string | undefined; + private _expectedDocumentId: string | undefined; + private _urlMatch: types.URLMatch | undefined; constructor(frame: Frame, options: WaitForNavigationOptions | undefined, supportUrlMatch: boolean) { options = options || {}; @@ -869,7 +869,7 @@ class LifecycleWatcher { throw new Error(`Unsupported waitUntil option ${String(event)}`); } if (supportUrlMatch) - this._urlMatch = options; + this._urlMatch = options.url; this._expectedLifecycle = waitUntil.slice(); this._frame = frame; this.sameDocumentNavigationPromise = new Promise(f => this._sameDocumentNavigationCompleteCallback = f); diff --git a/src/helper.ts b/src/helper.ts index 5b31ad862c..34bf507255 100644 --- a/src/helper.ts +++ b/src/helper.ts @@ -17,6 +17,7 @@ import * as debug from 'debug'; import * as types from './types'; +import * as kurl from 'url'; import { TimeoutError } from './errors'; export const debugError = debug(`playwright:error`); @@ -159,91 +160,20 @@ class Helper { } } - static stringMatches(s: string, match: string | RegExp, name: string): boolean { - if (helper.isString(match)) - return s === match; + static urlMatches(urlString: string, match: types.URLMatch | undefined): boolean { + if (match === undefined) + return true; + if (typeof match === 'string') + return match === urlString; if (match instanceof RegExp) - return match.test(s); - throw new Error(`url match field "${name}" must be a string or a RegExp, got ${typeof match}`); - } + return match.test(urlString); + assert(typeof match === 'function', 'url parameter should be string, RegExp or function'); - static searchParamsMatch(params: URLSearchParams, match: types.SearchParamsMatch, strict: boolean, name: string): boolean { - if (typeof match !== 'object' || match === null) - throw new Error(`url match field "${name}" must be an object, got ${typeof match}`); - const keys = new Set((params as any).keys()) as Set; - if (strict && keys.size !== Object.keys(match).length) - return false; - for (const key of keys) { - let expected = []; - if (key in match) { - let keyMatch = match[key]; - if (!Array.isArray(keyMatch)) - keyMatch = [keyMatch]; - expected = keyMatch; - } else if (!strict) { - continue; - } - const values = params.getAll(key); - if (strict && values.length !== expected.length) - return false; - for (const v of values) { - let found = false; - for (const e of expected) { - if (helper.stringMatches(v, e, name + '.' + key)) { - found = true; - break; - } - } - if (!found) - return false; - } - } - return true; - } - - static urlMatches(urlString: string, match: types.URLMatch): boolean { - let url; try { - url = new URL(urlString); + return match(new kurl.URL(urlString)); } catch (e) { - return urlString === match.url && - match.hash === undefined && - match.host === undefined && - match.hostname === undefined && - match.origin === undefined && - match.password === undefined && - match.pathname === undefined && - match.port === undefined && - match.protocol === undefined && - match.search === undefined && - match.searchParams === undefined && - match.username === undefined; } - if (match.url !== undefined && !helper.stringMatches(urlString, match.url, 'url')) - return false; - if (match.hash !== undefined && !helper.stringMatches(url.hash, match.hash, 'hash')) - return false; - if (match.host !== undefined && !helper.stringMatches(url.host, match.host, 'host')) - return false; - if (match.hostname !== undefined && !helper.stringMatches(url.hostname, match.hostname, 'hostname')) - return false; - if (match.origin !== undefined && !helper.stringMatches(url.origin, match.origin, 'origin')) - return false; - if (match.password !== undefined && !helper.stringMatches(url.password, match.password, 'password')) - return false; - if (match.pathname !== undefined && !helper.stringMatches(url.pathname, match.pathname, 'pathname')) - return false; - if (match.port !== undefined && !helper.stringMatches(url.port, match.port, 'port')) - return false; - if (match.protocol !== undefined && !helper.stringMatches(url.protocol, match.protocol, 'protocol')) - return false; - if (match.search !== undefined && !helper.stringMatches(url.search, match.search, 'search')) - return false; - if (match.username !== undefined && !helper.stringMatches(url.username, match.username, 'username')) - return false; - if (match.searchParams !== undefined && !helper.searchParamsMatch(url.searchParams, match.searchParams, !!match.strictSearchParams, 'searchParams')) - return false; - return true; + return false; } } diff --git a/src/input.ts b/src/input.ts index a3e23d2a4f..ce41b1cfab 100644 --- a/src/input.ts +++ b/src/input.ts @@ -406,5 +406,5 @@ export type FilePayload = { export type MediaType = 'screen' | 'print'; export const mediaTypes: Set = new Set(['screen', 'print']); -export type ColorScheme = 'dark' | 'light' | 'no-preference'; -export const mediaColorSchemes: Set = new Set(['dark', 'light', 'no-preference']); +export type ColorScheme = 'dark' | 'light'; +export const mediaColorSchemes: Set = new Set(['dark', 'light']); diff --git a/src/page.ts b/src/page.ts index e47ed8557b..24160c1159 100644 --- a/src/page.ts +++ b/src/page.ts @@ -308,21 +308,21 @@ export class Page extends EventEmitter { return helper.waitForEvent(this, event, (...args: any[]) => !!predicate(...args), timeout, this._disconnectedPromise); } - async waitForRequest(options: string | (types.URLMatch & types.TimeoutOptions) = {}): Promise { - if (helper.isString(options)) - options = { url: options }; + async waitForRequest(urlOrPredicate: string | RegExp | ((r: network.Request) => boolean), options: types.TimeoutOptions = {}): Promise { const { timeout = this._timeoutSettings.timeout() } = options; return helper.waitForEvent(this, Events.Page.Request, (request: network.Request) => { - return helper.urlMatches(request.url(), options as types.URLMatch); + if (helper.isString(urlOrPredicate) || urlOrPredicate instanceof RegExp) + return helper.urlMatches(request.url(), urlOrPredicate); + return urlOrPredicate(request); }, timeout, this._disconnectedPromise); } - async waitForResponse(options: string | (types.URLMatch & types.TimeoutOptions) = {}): Promise { - if (helper.isString(options)) - options = { url: options }; + async waitForResponse(urlOrPredicate: string | RegExp | ((r: network.Response) => boolean), options: types.TimeoutOptions = {}): Promise { const { timeout = this._timeoutSettings.timeout() } = options; return helper.waitForEvent(this, Events.Page.Response, (response: network.Response) => { - return helper.urlMatches(response.url(), options as types.URLMatch); + if (helper.isString(urlOrPredicate) || urlOrPredicate instanceof RegExp) + return helper.urlMatches(response.url(), urlOrPredicate); + return urlOrPredicate(response); }, timeout, this._disconnectedPromise); } diff --git a/src/types.ts b/src/types.ts index 930ca34c42..36878d0648 100644 --- a/src/types.ts +++ b/src/types.ts @@ -3,6 +3,7 @@ import * as js from './javascript'; import * as dom from './dom'; +import * as kurl from 'url'; type Boxed = { [Index in keyof Args]: Args[Index] | js.JSHandle }; type PageFunction = string | ((...args: Args) => R | Promise); @@ -50,19 +51,4 @@ export type Viewport = { hasTouch?: boolean; }; -export type SearchParamsMatch = { [key: string]: string | RegExp | (string | RegExp)[] }; -export type URLMatch = { - url?: string | RegExp, - hash?: string | RegExp, - host?: string | RegExp, - hostname?: string | RegExp, - origin?: string | RegExp, - password?: string | RegExp, - pathname?: string | RegExp, - port?: string | RegExp, - protocol?: string | RegExp, - search?: string | RegExp, - strictSearchParams?: boolean, - searchParams?: SearchParamsMatch, - username?: string | RegExp, -}; +export type URLMatch = string | RegExp | ((url: kurl.URL) => boolean); diff --git a/test/navigation.spec.js b/test/navigation.spec.js index ab7070f9ef..aa0d45eb9f 100644 --- a/test/navigation.spec.js +++ b/test/navigation.spec.js @@ -668,9 +668,9 @@ module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROME let response1 = null; const response1Promise = page.waitForNavigation({ url: /one-style\.html/ }).then(response => response1 = response); let response2 = null; - const response2Promise = page.waitForNavigation({ pathname: '/frame.html' }).then(response => response2 = response); + const response2Promise = page.waitForNavigation({ url: /\/frame.html/ }).then(response => response2 = response); let response3 = null; - const response3Promise = page.waitForNavigation({ searchParams: { 'foo': 'bar' }, strictSearchParams: true }).then(response => response3 = response); + const response3Promise = page.waitForNavigation({ url: url => url.searchParams.get('foo') === 'bar' }).then(response => response3 = response); expect(response1).toBe(null); expect(response2).toBe(null); expect(response3).toBe(null); diff --git a/test/page.spec.js b/test/page.spec.js index c963484672..ac732d894a 100644 --- a/test/page.spec.js +++ b/test/page.spec.js @@ -325,7 +325,7 @@ module.exports.describe = function({testRunner, expect, headless, playwright, FF it('should work with no timeout', async({page, server}) => { await page.goto(server.EMPTY_PAGE); const [request] = await Promise.all([ - page.waitForRequest({url: server.PREFIX + '/digits/2.png', timeout: 0}), + page.waitForRequest(server.PREFIX + '/digits/2.png', {timeout: 0}), page.evaluate(() => setTimeout(() => { fetch('/digits/1.png'); fetch('/digits/2.png'); @@ -337,81 +337,13 @@ module.exports.describe = function({testRunner, expect, headless, playwright, FF it('should work with url match', async({page, server}) => { await page.goto(server.EMPTY_PAGE); const [request] = await Promise.all([ - page.waitForRequest({ url: /digits\/\d\.png/ }), + page.waitForRequest(/digits\/\d\.png/), page.evaluate(() => { fetch('/digits/1.png'); }) ]); expect(request.url()).toBe(server.PREFIX + '/digits/1.png'); }); - it('should work with pathname match', async({page, server}) => { - await page.goto(server.EMPTY_PAGE); - const [request] = await Promise.all([ - page.waitForRequest({ pathname: '/digits/2.png' }), - page.evaluate(() => { - fetch('/digits/1.png'); - fetch('/digits/2.png'); - fetch('/digits/3.png'); - }) - ]); - expect(request.url()).toBe(server.PREFIX + '/digits/2.png'); - }); - it('should work with multiple matches', async({page, server}) => { - await page.goto(server.EMPTY_PAGE); - const [request] = await Promise.all([ - page.waitForRequest({ pathname: '/digits/2.png', url: /\d\.png/, port: String(server.PORT) }), - page.evaluate(() => { - fetch('/digits/1.png'); - fetch('/digits/2.png'); - fetch('/digits/3.png'); - }) - ]); - expect(request.url()).toBe(server.PREFIX + '/digits/2.png'); - }); - it('should work with strict search params match', async({page, server}) => { - await page.goto(server.EMPTY_PAGE); - const [request] = await Promise.all([ - page.waitForRequest({ searchParams: { 'foo': [/^baz$/, 'bar'], 'bar': 'foo' }, strictSearchParams: true }), - page.evaluate(() => { - fetch('/digits/2.png?foo=bar&foo=baz&bar=foo&key=value'); - fetch('/digits/1.png?foo=bar&bar=foo'); - fetch('/digits/4.png?foo=bar&bar=foo&foo=baz'); - fetch('/digits/3.png?bar=foo'); - }) - ]); - expect(request.url()).toBe(server.PREFIX + '/digits/4.png?foo=bar&bar=foo&foo=baz'); - }); - it('should work with relaxed search params match', async({page, server}) => { - await page.goto(server.EMPTY_PAGE); - const [request] = await Promise.all([ - page.waitForRequest({ searchParams: { 'foo': ['bar', /^baz$/], 'bar': 'foo' }, url: /\.png/ }), - page.evaluate(() => { - fetch('/digits/1.png?key=value&foo=something'); - fetch('/digits/2.png?foo=baz'); - }) - ]); - expect(request.url()).toBe(server.PREFIX + '/digits/2.png?foo=baz'); - }); - it('should throw for incorrect match', async({page, server}) => { - await page.goto(server.EMPTY_PAGE); - const [error] = await Promise.all([ - page.waitForRequest({ url: null }).catch(e => e), - page.evaluate(() => { - fetch('/digits/1.png'); - }) - ]); - expect(error.message).toBe('url match field "url" must be a string or a RegExp, got object'); - }); - it('should throw for incorrect searchParams match', async({page, server}) => { - await page.goto(server.EMPTY_PAGE); - const [error] = await Promise.all([ - page.waitForRequest({ searchParams: { 'foo': 123 }, url: /\.png/ }).catch(e => e), - page.evaluate(() => { - fetch('/digits/1.png?foo=bar'); - }) - ]); - expect(error.message).toBe('url match field "searchParams.foo" must be a string or a RegExp, got number'); - }); }); describe('Page.waitForResponse', function() { @@ -453,7 +385,7 @@ module.exports.describe = function({testRunner, expect, headless, playwright, FF it('should work with no timeout', async({page, server}) => { await page.goto(server.EMPTY_PAGE); const [response] = await Promise.all([ - page.waitForResponse({ url: server.PREFIX + '/digits/2.png', timeout: 0 }), + page.waitForResponse(server.PREFIX + '/digits/2.png', { timeout: 0 }), page.evaluate(() => setTimeout(() => { fetch('/digits/1.png'); fetch('/digits/2.png'); @@ -462,18 +394,6 @@ module.exports.describe = function({testRunner, expect, headless, playwright, FF ]); expect(response.url()).toBe(server.PREFIX + '/digits/2.png'); }); - it('should work with multiple matches', async({page, server}) => { - await page.goto(server.EMPTY_PAGE); - const [response] = await Promise.all([ - page.waitForResponse({ pathname: '/digits/2.png', url: /\d\.png/, port: String(server.PORT) }), - page.evaluate(() => { - fetch('/digits/1.png'); - fetch('/digits/2.png'); - fetch('/digits/3.png'); - }) - ]); - expect(response.url()).toBe(server.PREFIX + '/digits/2.png'); - }); }); describe('Page.exposeFunction', function() {