feat(ExecutionContext): introduce ExecutionContext.frame() (#1972)

This patch introduces ExecutionContext.frame() that returns Frame
associated with this Execution Context.

This allows to associate console messages with the originating frame,
if any.
This commit is contained in:
Andrey Lushnikov 2018-02-13 14:02:44 -08:00 committed by GitHub
parent 885c93a927
commit ae22ef30b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 13 deletions

View File

@ -167,6 +167,7 @@
- [class: ExecutionContext](#class-executioncontext) - [class: ExecutionContext](#class-executioncontext)
* [executionContext.evaluate(pageFunction, ...args)](#executioncontextevaluatepagefunction-args) * [executionContext.evaluate(pageFunction, ...args)](#executioncontextevaluatepagefunction-args)
* [executionContext.evaluateHandle(pageFunction, ...args)](#executioncontextevaluatehandlepagefunction-args) * [executionContext.evaluateHandle(pageFunction, ...args)](#executioncontextevaluatehandlepagefunction-args)
* [executionContext.frame()](#executioncontextframe)
* [executionContext.queryObjects(prototypeHandle)](#executioncontextqueryobjectsprototypehandle) * [executionContext.queryObjects(prototypeHandle)](#executioncontextqueryobjectsprototypehandle)
- [class: JSHandle](#class-jshandle) - [class: JSHandle](#class-jshandle)
* [jsHandle.asElement()](#jshandleaselement) * [jsHandle.asElement()](#jshandleaselement)
@ -2041,6 +2042,11 @@ await aHandle.dispose();
await resultHandle.dispose(); await resultHandle.dispose();
``` ```
#### executionContext.frame()
- returns: <?[Frame]> Frame associated with this execution context.
> **NOTE** Not every execution context is associated with a frame. For example, workers and extensions have execution contexts that are not associated with frames.
#### executionContext.queryObjects(prototypeHandle) #### executionContext.queryObjects(prototypeHandle)
- `prototypeHandle` <[JSHandle]> A handle to the object prototype. - `prototypeHandle` <[JSHandle]> A handle to the object prototype.
- returns: <[JSHandle]> A handle to an array of objects with this prototype - returns: <[JSHandle]> A handle to an array of objects with this prototype

View File

@ -21,17 +21,22 @@ class ExecutionContext {
* @param {!Puppeteer.CDPSession} client * @param {!Puppeteer.CDPSession} client
* @param {!Object} contextPayload * @param {!Object} contextPayload
* @param {function(*):!JSHandle} objectHandleFactory * @param {function(*):!JSHandle} objectHandleFactory
* @param {?Puppeteer.Frame} frame
*/ */
constructor(client, contextPayload, objectHandleFactory) { constructor(client, contextPayload, objectHandleFactory, frame) {
this._client = client; this._client = client;
this._frame = frame;
this._contextId = contextPayload.id; this._contextId = contextPayload.id;
const auxData = contextPayload.auxData || {isDefault: true};
this._frameId = auxData.frameId || null;
this._isDefault = !!auxData.isDefault;
this._objectHandleFactory = objectHandleFactory; this._objectHandleFactory = objectHandleFactory;
} }
/**
* @return {?Puppeteer.Frame}
*/
frame() {
return this._frame;
}
/** /**
* @param {Function|string} pageFunction * @param {Function|string} pageFunction
* @param {...*} args * @param {...*} args

View File

@ -154,11 +154,11 @@ class FrameManager extends EventEmitter {
} }
_onExecutionContextCreated(contextPayload) { _onExecutionContextCreated(contextPayload) {
const context = new ExecutionContext(this._client, contextPayload, this.createJSHandle.bind(this, contextPayload.id)); const frameId = contextPayload.auxData && contextPayload.auxData.isDefault ? contextPayload.auxData.frameId : null;
const frame = frameId ? this._frames.get(frameId) : null;
const context = new ExecutionContext(this._client, contextPayload, this.createJSHandle.bind(this, contextPayload.id), frame);
this._contextIdToContext.set(contextPayload.id, context); this._contextIdToContext.set(contextPayload.id, context);
if (frame)
const frame = context._frameId ? this._frames.get(context._frameId) : null;
if (frame && context._isDefault)
frame._setDefaultContext(context); frame._setDefaultContext(context);
} }
@ -166,9 +166,8 @@ class FrameManager extends EventEmitter {
* @param {!ExecutionContext} context * @param {!ExecutionContext} context
*/ */
_removeContext(context) { _removeContext(context) {
const frame = context._frameId ? this._frames.get(context._frameId) : null; if (context.frame())
if (frame && context._isDefault) context.frame()._setDefaultContext(null);
frame._setDefaultContext(null);
} }
/** /**

View File

@ -152,7 +152,8 @@ describe('Puppeteer', function() {
expect(response.ok()).toBe(true); expect(response.ok()).toBe(true);
expect(response.securityDetails()).toBeTruthy(); expect(response.securityDetails()).toBeTruthy();
expect(response.securityDetails().protocol()).toBe('TLS 1.2'); expect(response.securityDetails().protocol()).toBe('TLS 1.2');
browser.close(); await page.close();
await browser.close();
}); });
it('should reject all promises when browser is closed', async() => { it('should reject all promises when browser is closed', async() => {
const browser = await puppeteer.launch(defaultBrowserOptions); const browser = await puppeteer.launch(defaultBrowserOptions);
@ -647,6 +648,8 @@ describe('Page', function() {
expect(context1).toBeTruthy(); expect(context1).toBeTruthy();
expect(context2).toBeTruthy(); expect(context2).toBeTruthy();
expect(context1 !== context2).toBeTruthy(); expect(context1 !== context2).toBeTruthy();
expect(context1.frame()).toBe(frame1);
expect(context2.frame()).toBe(frame2);
await Promise.all([ await Promise.all([
context1.evaluate(() => window.a = 1), context1.evaluate(() => window.a = 1),