diff --git a/docs/api.md b/docs/api.md index 6f77b22c5b..9df72c0ced 100644 --- a/docs/api.md +++ b/docs/api.md @@ -614,6 +614,7 @@ page.removeListener('request', logRequest); - [page.exposeFunction(name, playwrightFunction)](#pageexposefunctionname-playwrightfunction) - [page.fill(selector, value[, options])](#pagefillselector-value-options) - [page.focus(selector[, options])](#pagefocusselector-options) +- [page.frame(options)](#pageframeoptions) - [page.frames()](#pageframes) - [page.goBack([options])](#pagegobackoptions) - [page.goForward([options])](#pagegoforwardoptions) @@ -1170,6 +1171,14 @@ If there's no element matching `selector`, the method throws an error. Shortcut for [page.mainFrame().focus(selector)](#framefocusselector). +#### page.frame(options) +- `options` <[Object]> + - `name` <[string]> frame name specified in the `iframe`'s `name` attribute + - `url` <[string]|[RegExp]|[Function]> A glob pattern, regex pattern or predicate receiving frame's `url` as a [URL] object. +- returns: <[Frame]> frame matching the criteria. + +Returns frame matching the specified criteria. Either `name` or `url` must be specified. + #### page.frames() - returns: <[Array]<[Frame]>> An array of all frames attached to the page. diff --git a/src/page.ts b/src/page.ts index 8564948d3f..d56045e2ce 100644 --- a/src/page.ts +++ b/src/page.ts @@ -206,6 +206,15 @@ export class Page extends platform.EventEmitter { return this._frameManager.mainFrame(); } + frame(options: { name?: string, url?: types.URLMatch }): frames.Frame | null { + assert(options.name || options.url, 'Either name or url matcher should be specified'); + return this.frames().find(f => { + if (options.name) + return f.name() === options.name; + return platform.urlMatches(f.url(), options.url); + }) || null; + } + frames(): frames.Frame[] { return this._frameManager.frames(); } diff --git a/test/page.spec.js b/test/page.spec.js index 4ebb48f32e..096832f539 100644 --- a/test/page.spec.js +++ b/test/page.spec.js @@ -1120,4 +1120,29 @@ module.exports.describe = function({testRunner, expect, headless, playwright, FF expect(page.context()).toBe(context); }); }); + + describe('Page.frame', function() { + it('should respect name', async function({page, server}) { + await page.setContent(` + empty.html + + `); + expect(page.frame({ name: 'bogus' })).toBe(null); + const frame = page.frame({ name: 'target' }); + expect(frame).toBeTruthy(); + await Promise.all([ + frame.waitForNavigation(), + page.click('a') + ]); + expect(frame.url()).toBe(server.EMPTY_PAGE); + }); + it('should respect url', async function({page, server}) { + await page.setContent(` + empty.html target=target>empty.html + + `); + expect(page.frame({ url: /bogus/ })).toBe(null); + expect(page.frame({ url: /empty/ }).url()).toBe(server.EMPTY_PAGE); + }); + }); };