Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat(oop iframes)!: integrate OOP iframes with the frame manager (#7556)
This pull request to adds better support for OOP iframes (see #2548)

The current problem with OOP iframes is that they are moved to a different target. Because of this, the previous versions of Puppeteer pretty much ignored them.
This change extends the FrameManager to already take OOP iframes into account and hides the fact that those frames are actually in different targets.
Further work needs to be done to also make the NetworkManager aware of these and to make sure that settings like emulations etc. are also properly passed down to the new targets.
  • Loading branch information
jschfflr committed Oct 28, 2021
1 parent 0d6e688 commit 4d9dc8c
Show file tree
Hide file tree
Showing 8 changed files with 542 additions and 123 deletions.
28 changes: 28 additions & 0 deletions docs/api.md
Expand Up @@ -195,6 +195,7 @@
* [page.viewport()](#pageviewport)
* [page.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])](#pagewaitforselectororfunctionortimeout-options-args)
* [page.waitForFileChooser([options])](#pagewaitforfilechooseroptions)
* [page.waitForFrame(urlOrPredicate[, options])](#pagewaitforframeurlorpredicate-options)
* [page.waitForFunction(pageFunction[, options[, ...args]])](#pagewaitforfunctionpagefunction-options-args)
* [page.waitForNavigation([options])](#pagewaitfornavigationoptions)
* [page.waitForNetworkIdle([options])](#pagewaitfornetworkidleoptions)
Expand Down Expand Up @@ -269,6 +270,7 @@
* [frame.goto(url[, options])](#framegotourl-options)
* [frame.hover(selector)](#framehoverselector)
* [frame.isDetached()](#frameisdetached)
* [frame.isOOPFrame()](#frameisoopframe)
* [frame.name()](#framename)
* [frame.parentFrame()](#frameparentframe)
* [frame.select(selector, ...values)](#frameselectselector-values)
Expand Down Expand Up @@ -385,6 +387,7 @@
- [class: CDPSession](#class-cdpsession)
* [cdpSession.connection()](#cdpsessionconnection)
* [cdpSession.detach()](#cdpsessiondetach)
* [cdpSession.id()](#cdpsessionid)
* [cdpSession.send(method[, ...paramArgs])](#cdpsessionsendmethod-paramargs)
- [class: Coverage](#class-coverage)
* [coverage.startCSSCoverage([options])](#coveragestartcsscoverageoptions)
Expand Down Expand Up @@ -2769,6 +2772,19 @@ await fileChooser.accept(['/tmp/myfile.pdf']);
> **NOTE** “File picker” refers to the operating system’s file selection UI that lets you browse to a folder and select file(s) to be shared with the web app. It’s not the “Save file” dialog.
#### page.waitForFrame(urlOrPredicate[, options])

- `urlOrPredicate` <[string]|[Function]> A URL or predicate to wait for.
- `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]<[Frame]>> Promise which resolves to the matched frame.

```js
const frame = await page.waitForFrame(async (frame) => {
return frame.name() === 'Test';
});
```

#### page.waitForFunction(pageFunction[, options[, ...args]])

- `pageFunction` <[function]|[string]> Function to be evaluated in browser context
Expand Down Expand Up @@ -3833,6 +3849,12 @@ If there's no element matching `selector`, the method throws an error.

Returns `true` if the frame has been detached, or `false` otherwise.

#### frame.isOOPFrame()

- returns: <[boolean]>

Returns `true` if the frame is an OOP frame, or `false` otherwise.

#### frame.name()

- returns: <[string]>
Expand Down Expand Up @@ -5088,6 +5110,12 @@ Returns the underlying connection associated with the session. Can be used to ob
Detaches the cdpSession from the target. Once detached, the cdpSession object won't emit any events and can't be used
to send messages.

#### cdpSession.id()

- returns: <[string]>

Returns the session's id.

#### cdpSession.send(method[, ...paramArgs])

- `method` <[string]> protocol method name
Expand Down
7 changes: 7 additions & 0 deletions src/common/Connection.ts
Expand Up @@ -350,6 +350,13 @@ export class CDPSession extends EventEmitter {
this._connection = null;
this.emit(CDPSessionEmittedEvents.Disconnected);
}

/**
* @internal
*/
id(): string {
return this._sessionId;
}
}

/**
Expand Down
8 changes: 7 additions & 1 deletion src/common/DOMWorld.ts
Expand Up @@ -37,6 +37,7 @@ import {
} from './EvalTypes.js';
import { isNode } from '../environment.js';
import { Protocol } from 'devtools-protocol';
import { CDPSession } from './Connection.js';

// predicateQueryHandler and checkWaitForOptions are declared here so that
// TypeScript knows about them when used in the predicate function below.
Expand Down Expand Up @@ -72,6 +73,7 @@ export interface PageBinding {
*/
export class DOMWorld {
private _frameManager: FrameManager;
private _client: CDPSession;
private _frame: Frame;
private _timeoutSettings: TimeoutSettings;
private _documentPromise?: Promise<ElementHandle> = null;
Expand All @@ -96,15 +98,19 @@ export class DOMWorld {
`${name}_${contextId}`;

constructor(
client: CDPSession,
frameManager: FrameManager,
frame: Frame,
timeoutSettings: TimeoutSettings
) {
// Keep own reference to client because it might differ from the FrameManager's
// client for OOP iframes.
this._client = client;
this._frameManager = frameManager;
this._frame = frame;
this._timeoutSettings = timeoutSettings;
this._setContext(null);
frameManager._client.on('Runtime.bindingCalled', (event) =>
this._client.on('Runtime.bindingCalled', (event) =>
this._onBindingCalled(event)
);
}
Expand Down

0 comments on commit 4d9dc8c

Please sign in to comment.