mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
fix(page): execute frame.waitFor{Selector,XPath} in secondary world (#3856)
This patch starts executing frame.waitForSelector and frame.waitForXPath in secondary world. As a result, websites that mutate page global context (e.g. removing global MutationObserver) don't break Puppeteer's behavior. Fixes #609
This commit is contained in:
@@ -173,6 +173,22 @@ class ExecutionContext {
|
||||
});
|
||||
return createJSHandle(this, response.objects);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Puppeteer.ElementHandle} elementHandle
|
||||
* @return {Promise<Puppeteer.ElementHandle>}
|
||||
*/
|
||||
async _adoptElementHandle(elementHandle) {
|
||||
assert(elementHandle.executionContext() !== this, 'Cannot adopt handle that already belongs to this execution context');
|
||||
assert(this._world, 'Cannot adopt handle without DOMWorld');
|
||||
const nodeInfo = await this._client.send('DOM.describeNode', {
|
||||
objectId: elementHandle._remoteObject.objectId,
|
||||
});
|
||||
const {object} = await this._client.send('DOM.resolveNode', {
|
||||
backendNodeId: nodeInfo.node.backendNodeId,
|
||||
});
|
||||
return /** @type {Puppeteer.ElementHandle}*/(createJSHandle(this, object));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {ExecutionContext, EVALUATION_SCRIPT_URL};
|
||||
|
||||
@@ -608,8 +608,14 @@ class Frame {
|
||||
* @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options
|
||||
* @return {!Promise<?Puppeteer.ElementHandle>}
|
||||
*/
|
||||
waitForSelector(selector, options) {
|
||||
return this._mainWorld.waitForSelector(selector, options);
|
||||
async waitForSelector(selector, options) {
|
||||
const handle = await this._secondaryWorld.waitForSelector(selector, options);
|
||||
if (!handle)
|
||||
return null;
|
||||
const mainExecutionContext = await this._mainWorld.executionContext();
|
||||
const result = await mainExecutionContext._adoptElementHandle(handle);
|
||||
await handle.dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -617,8 +623,14 @@ class Frame {
|
||||
* @param {!{visible?: boolean, hidden?: boolean, timeout?: number}=} options
|
||||
* @return {!Promise<?Puppeteer.ElementHandle>}
|
||||
*/
|
||||
waitForXPath(xpath, options) {
|
||||
return this._mainWorld.waitForXPath(xpath, options);
|
||||
async waitForXPath(xpath, options) {
|
||||
const handle = await this._secondaryWorld.waitForXPath(xpath, options);
|
||||
if (!handle)
|
||||
return null;
|
||||
const mainExecutionContext = await this._mainWorld.executionContext();
|
||||
const result = await mainExecutionContext._adoptElementHandle(handle);
|
||||
await handle.dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user