mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-15 06:02:57 +03:00
api: remove ExecutionContext from api (#290)
In the current state, it is superseeded by Frame and JSHandle.
This commit is contained in:
parent
58cd8210b0
commit
7750db97fe
@ -125,7 +125,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
|
|||||||
if (error.message.includes('Object couldn\'t be returned by value'))
|
if (error.message.includes('Object couldn\'t be returned by value'))
|
||||||
return {result: {type: 'undefined'}};
|
return {result: {type: 'undefined'}};
|
||||||
|
|
||||||
if (error.message.endsWith('Cannot find context with specified id') || error.message.endsWith('Inspected target navigated or closed'))
|
if (error.message.endsWith('Cannot find context with specified id') || error.message.endsWith('Inspected target navigated or closed') || error.message.endsWith('Execution context was destroyed.'))
|
||||||
throw new Error('Execution context was destroyed, most likely because of a navigation.');
|
throw new Error('Execution context was destroyed, most likely because of a navigation.');
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@ -140,7 +140,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
|
|||||||
for (const property of response.result) {
|
for (const property of response.result) {
|
||||||
if (!property.enumerable)
|
if (!property.enumerable)
|
||||||
continue;
|
continue;
|
||||||
result.set(property.name, handle.executionContext()._createHandle(property.value));
|
result.set(property.name, handle._context._createHandle(property.value));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ export { ElementHandle } from '../dom';
|
|||||||
export { TimeoutError } from '../errors';
|
export { TimeoutError } from '../errors';
|
||||||
export { Frame } from '../frames';
|
export { Frame } from '../frames';
|
||||||
export { Keyboard, Mouse } from '../input';
|
export { Keyboard, Mouse } from '../input';
|
||||||
export { ExecutionContext, JSHandle } from '../javascript';
|
export { JSHandle } from '../javascript';
|
||||||
export { Request, Response } from '../network';
|
export { Request, Response } from '../network';
|
||||||
export { Browser } from './Browser';
|
export { Browser } from './Browser';
|
||||||
export { BrowserContext } from '../browserContext';
|
export { BrowserContext } from '../browserContext';
|
||||||
|
@ -85,10 +85,6 @@ export class Worker extends EventEmitter {
|
|||||||
return this._url;
|
return this._url;
|
||||||
}
|
}
|
||||||
|
|
||||||
async executionContext(): Promise<js.ExecutionContext> {
|
|
||||||
return this._executionContextPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
evaluate: types.Evaluate = async (pageFunction, ...args) => {
|
evaluate: types.Evaluate = async (pageFunction, ...args) => {
|
||||||
return (await this._executionContextPromise).evaluate(pageFunction, ...args as any);
|
return (await this._executionContextPromise).evaluate(pageFunction, ...args as any);
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ export class ConsoleMessage {
|
|||||||
|
|
||||||
text(): string {
|
text(): string {
|
||||||
if (this._text === undefined)
|
if (this._text === undefined)
|
||||||
this._text = this._args.map(arg => arg.executionContext()._delegate.handleToString(arg, false /* includeType */)).join(' ');
|
this._text = this._args.map(arg => arg._context._delegate.handleToString(arg, false /* includeType */)).join(' ');
|
||||||
return this._text;
|
return this._text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +87,10 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
|||||||
this._page = context.frame()._page;
|
this._page = context.frame()._page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frame(): frames.Frame {
|
||||||
|
return this._context.frame();
|
||||||
|
}
|
||||||
|
|
||||||
asElement(): ElementHandle<T> | null {
|
asElement(): ElementHandle<T> | null {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
|
|||||||
return context._createHandle(payload.result);
|
return context._createHandle(payload.result);
|
||||||
|
|
||||||
function rewriteError(error) : never {
|
function rewriteError(error) : never {
|
||||||
if (error.message.includes('Failed to find execution context with id'))
|
if (error.message.includes('Failed to find execution context with id') || error.message.includes('Execution context was destroyed!'))
|
||||||
throw new Error('Execution context was destroyed, most likely because of a navigation.');
|
throw new Error('Execution context was destroyed, most likely because of a navigation.');
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
@ -119,7 +119,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
|
|||||||
});
|
});
|
||||||
const result = new Map();
|
const result = new Map();
|
||||||
for (const property of response.properties)
|
for (const property of response.properties)
|
||||||
result.set(property.name, handle.executionContext()._createHandle(property.value));
|
result.set(property.name, handle._context._createHandle(property.value));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ export { Browser } from './Browser';
|
|||||||
export { BrowserContext } from '../browserContext';
|
export { BrowserContext } from '../browserContext';
|
||||||
export { BrowserFetcher } from '../browserFetcher';
|
export { BrowserFetcher } from '../browserFetcher';
|
||||||
export { Dialog } from '../dialog';
|
export { Dialog } from '../dialog';
|
||||||
export { ExecutionContext, JSHandle } from '../javascript';
|
export { JSHandle } from '../javascript';
|
||||||
export { ElementHandle } from '../dom';
|
export { ElementHandle } from '../dom';
|
||||||
export { Accessibility } from './features/accessibility';
|
export { Accessibility } from './features/accessibility';
|
||||||
export { Interception } from './features/interception';
|
export { Interception } from './features/interception';
|
||||||
|
@ -354,10 +354,6 @@ export class Frame {
|
|||||||
return this._context('utility');
|
return this._context('utility');
|
||||||
}
|
}
|
||||||
|
|
||||||
executionContext(): Promise<dom.FrameExecutionContext> {
|
|
||||||
return this._mainContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
evaluateHandle: types.EvaluateHandle = async (pageFunction, ...args) => {
|
evaluateHandle: types.EvaluateHandle = async (pageFunction, ...args) => {
|
||||||
const context = await this._mainContext();
|
const context = await this._mainContext();
|
||||||
return context.evaluateHandle(pageFunction, ...args as any);
|
return context.evaluateHandle(pageFunction, ...args as any);
|
||||||
@ -632,7 +628,7 @@ export class Frame {
|
|||||||
const values = value === undefined ? [] : Array.isArray(value) ? value : [value];
|
const values = value === undefined ? [] : Array.isArray(value) ? value : [value];
|
||||||
const context = await this._utilityContext();
|
const context = await this._utilityContext();
|
||||||
const adoptedValues = await Promise.all(values.map(async value => {
|
const adoptedValues = await Promise.all(values.map(async value => {
|
||||||
if (value instanceof dom.ElementHandle && value.executionContext() !== context) {
|
if (value instanceof dom.ElementHandle && value._context !== context) {
|
||||||
const adopted = this._page._delegate.adoptElementHandle(value, context);
|
const adopted = this._page._delegate.adoptElementHandle(value, context);
|
||||||
toDispose.push(adopted);
|
toDispose.push(adopted);
|
||||||
return adopted;
|
return adopted;
|
||||||
|
@ -47,10 +47,6 @@ export class JSHandle<T = any> {
|
|||||||
this._remoteObject = remoteObject;
|
this._remoteObject = remoteObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
executionContext(): ExecutionContext {
|
|
||||||
return this._context;
|
|
||||||
}
|
|
||||||
|
|
||||||
evaluate: types.EvaluateOn<T> = (pageFunction, ...args) => {
|
evaluate: types.EvaluateOn<T> = (pageFunction, ...args) => {
|
||||||
return this._context.evaluate(pageFunction, this, ...args);
|
return this._context.evaluate(pageFunction, this, ...args);
|
||||||
}
|
}
|
||||||
|
@ -174,8 +174,7 @@ export class Page extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
evaluateHandle: types.EvaluateHandle = async (pageFunction, ...args) => {
|
evaluateHandle: types.EvaluateHandle = async (pageFunction, ...args) => {
|
||||||
const context = await this.mainFrame().executionContext();
|
return this.mainFrame().evaluateHandle(pageFunction, ...args as any);
|
||||||
return context.evaluateHandle(pageFunction, ...args as any);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$eval: types.$Eval = (selector, pageFunction, ...args) => {
|
$eval: types.$Eval = (selector, pageFunction, ...args) => {
|
||||||
|
@ -261,7 +261,7 @@ export class ExecutionContextDelegate implements js.ExecutionContextDelegate {
|
|||||||
for (const property of response.properties) {
|
for (const property of response.properties) {
|
||||||
if (!property.enumerable)
|
if (!property.enumerable)
|
||||||
continue;
|
continue;
|
||||||
result.set(property.name, handle.executionContext()._createHandle(property.value));
|
result.set(property.name, handle._context._createHandle(property.value));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ export class FrameManager implements PageDelegate {
|
|||||||
else if (type === 'timing')
|
else if (type === 'timing')
|
||||||
derivedType = 'timeEnd';
|
derivedType = 'timeEnd';
|
||||||
|
|
||||||
const mainFrameContext = await this._page.mainFrame().executionContext();
|
const mainFrameContext = await this._page.mainFrame()._mainContext();
|
||||||
const handles = (parameters || []).map(p => {
|
const handles = (parameters || []).map(p => {
|
||||||
let context: dom.FrameExecutionContext | null = null;
|
let context: dom.FrameExecutionContext | null = null;
|
||||||
if (p.objectId) {
|
if (p.objectId) {
|
||||||
|
@ -5,7 +5,7 @@ export { TimeoutError } from '../errors';
|
|||||||
export { Browser } from './Browser';
|
export { Browser } from './Browser';
|
||||||
export { BrowserContext } from '../browserContext';
|
export { BrowserContext } from '../browserContext';
|
||||||
export { BrowserFetcher } from '../browserFetcher';
|
export { BrowserFetcher } from '../browserFetcher';
|
||||||
export { ExecutionContext, JSHandle } from '../javascript';
|
export { JSHandle } from '../javascript';
|
||||||
export { ElementHandle } from '../dom';
|
export { ElementHandle } from '../dom';
|
||||||
export { Frame } from '../frames';
|
export { Frame } from '../frames';
|
||||||
export { Mouse, Keyboard } from '../input';
|
export { Mouse, Keyboard } from '../input';
|
||||||
|
@ -67,11 +67,11 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||||||
expect(log.args().length).toBe(4);
|
expect(log.args().length).toBe(4);
|
||||||
expect(await (await log.args()[3].getProperty('origin')).jsonValue()).toBe('null');
|
expect(await (await log.args()[3].getProperty('origin')).jsonValue()).toBe('null');
|
||||||
});
|
});
|
||||||
it('should have an execution context', async function({page}) {
|
it('should evaluate', async function({page}) {
|
||||||
const workerCreatedPromise = new Promise(x => page.workers.once('workercreated', x));
|
const workerCreatedPromise = new Promise(x => page.workers.once('workercreated', x));
|
||||||
await page.evaluate(() => new Worker(`data:text/javascript,console.log(1)`));
|
await page.evaluate(() => new Worker(`data:text/javascript,console.log(1)`));
|
||||||
const worker = await workerCreatedPromise;
|
const worker = await workerCreatedPromise;
|
||||||
expect(await (await worker.executionContext()).evaluate('1+1')).toBe(2);
|
expect(await worker.evaluate('1+1')).toBe(2);
|
||||||
});
|
});
|
||||||
it('should report errors', async function({page}) {
|
it('should report errors', async function({page}) {
|
||||||
const errorPromise = new Promise(x => page.on('pageerror', x));
|
const errorPromise = new Promise(x => page.on('pageerror', x));
|
||||||
|
@ -83,7 +83,7 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||||||
location.reload();
|
location.reload();
|
||||||
return new Promise(() => {});
|
return new Promise(() => {});
|
||||||
}).catch(e => error = e);
|
}).catch(e => error = e);
|
||||||
expect(error.message).toContain('Protocol error');
|
expect(error.message).toContain('navigation');
|
||||||
});
|
});
|
||||||
it('should await promise', async({page, server}) => {
|
it('should await promise', async({page, server}) => {
|
||||||
const result = await page.evaluate(() => Promise.resolve(8 * 7));
|
const result = await page.evaluate(() => Promise.resolve(8 * 7));
|
||||||
@ -227,13 +227,15 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
});
|
});
|
||||||
it('should throw a nice error after a navigation', async({page, server}) => {
|
it('should throw a nice error after a navigation', async({page, server}) => {
|
||||||
const executionContext = await page.mainFrame().executionContext();
|
const errorPromise = page.evaluate(() => new Promise(f => window.__resolve = f)).catch(e => e);
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForNavigation(),
|
page.waitForNavigation(),
|
||||||
executionContext.evaluate(() => window.location.reload())
|
page.evaluate(() => {
|
||||||
|
window.location.reload();
|
||||||
|
setTimeout(() => window.__resolve(42), 1000);
|
||||||
|
})
|
||||||
]);
|
]);
|
||||||
const error = await executionContext.evaluate(() => null).catch(e => e);
|
const error = await errorPromise;
|
||||||
expect(error.message).toContain('navigation');
|
expect(error.message).toContain('navigation');
|
||||||
});
|
});
|
||||||
it.skip(FFOX)('should not throw an error when evaluation does a navigation', async({page, server}) => {
|
it.skip(FFOX)('should not throw an error when evaluation does a navigation', async({page, server}) => {
|
||||||
|
@ -22,33 +22,6 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||||||
const {it, fit, xit} = testRunner;
|
const {it, fit, xit} = testRunner;
|
||||||
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
|
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
|
||||||
|
|
||||||
describe('Frame.executionContext', function() {
|
|
||||||
it('should work', async({page, server}) => {
|
|
||||||
await page.goto(server.EMPTY_PAGE);
|
|
||||||
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
|
||||||
expect(page.frames().length).toBe(2);
|
|
||||||
const [frame1, frame2] = page.frames();
|
|
||||||
const context1 = await frame1.executionContext();
|
|
||||||
const context2 = await frame2.executionContext();
|
|
||||||
expect(context1).toBeTruthy();
|
|
||||||
expect(context2).toBeTruthy();
|
|
||||||
expect(context1 !== context2).toBeTruthy();
|
|
||||||
expect(context1.frame()).toBe(frame1);
|
|
||||||
expect(context2.frame()).toBe(frame2);
|
|
||||||
|
|
||||||
await Promise.all([
|
|
||||||
context1.evaluate(() => window.a = 1),
|
|
||||||
context2.evaluate(() => window.a = 2)
|
|
||||||
]);
|
|
||||||
const [a1, a2] = await Promise.all([
|
|
||||||
context1.evaluate(() => window.a),
|
|
||||||
context2.evaluate(() => window.a)
|
|
||||||
]);
|
|
||||||
expect(a1).toBe(1);
|
|
||||||
expect(a2).toBe(2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Frame.evaluateHandle', function() {
|
describe('Frame.evaluateHandle', function() {
|
||||||
it('should work', async({page, server}) => {
|
it('should work', async({page, server}) => {
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
@ -66,6 +39,24 @@ module.exports.addTests = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
|
|||||||
await frame1.evaluate(() => 7 * 8).catch(e => error = e);
|
await frame1.evaluate(() => 7 * 8).catch(e => error = e);
|
||||||
expect(error.message).toContain('Execution Context is not available in detached frame');
|
expect(error.message).toContain('Execution Context is not available in detached frame');
|
||||||
});
|
});
|
||||||
|
it('should be isolated between frames', async({page, server}) => {
|
||||||
|
await page.goto(server.EMPTY_PAGE);
|
||||||
|
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||||
|
expect(page.frames().length).toBe(2);
|
||||||
|
const [frame1, frame2] = page.frames();
|
||||||
|
expect(frame1 !== frame2).toBeTruthy();
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
frame1.evaluate(() => window.a = 1),
|
||||||
|
frame2.evaluate(() => window.a = 2)
|
||||||
|
]);
|
||||||
|
const [a1, a2] = await Promise.all([
|
||||||
|
frame1.evaluate(() => window.a),
|
||||||
|
frame2.evaluate(() => window.a)
|
||||||
|
]);
|
||||||
|
expect(a1).toBe(1);
|
||||||
|
expect(a2).toBe(2);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Frame Management', function() {
|
describe('Frame Management', function() {
|
||||||
|
@ -146,14 +146,17 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
|||||||
expect(await page.evaluate(() => !!window.opener)).toBe(false);
|
expect(await page.evaluate(() => !!window.opener)).toBe(false);
|
||||||
expect(await popup.evaluate(() => !!window.opener)).toBe(true);
|
expect(await popup.evaluate(() => !!window.opener)).toBe(true);
|
||||||
});
|
});
|
||||||
it('should work with fake-clicking target=_blank and rel=noopener', async({page, server}) => {
|
it.skip(FFOX)('should work with fake-clicking target=_blank and rel=noopener', async({page, server}) => {
|
||||||
|
// TODO: FFOX sends events for "one-style.html" request to both pages.
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
await page.setContent('<a target=_blank rel=noopener href="/one-style.html">yo</a>');
|
await page.setContent('<a target=_blank rel=noopener href="/one-style.html">yo</a>');
|
||||||
const [popup] = await Promise.all([
|
const [popup] = await Promise.all([
|
||||||
new Promise(x => page.once('popup', x)),
|
page.waitForEvent('popup'),
|
||||||
page.$eval('a', a => a.click()),
|
page.$eval('a', a => a.click()),
|
||||||
]);
|
]);
|
||||||
expect(await page.evaluate(() => !!window.opener)).toBe(false);
|
expect(await page.evaluate(() => !!window.opener)).toBe(false);
|
||||||
|
// TODO: At this point popup might still have about:blank as the current document.
|
||||||
|
// FFOX is slow enough to trigger this. We should do something about popups api.
|
||||||
expect(await popup.evaluate(() => !!window.opener)).toBe(false);
|
expect(await popup.evaluate(() => !!window.opener)).toBe(false);
|
||||||
});
|
});
|
||||||
it('should work with clicking target=_blank and rel=noopener', async({page, server}) => {
|
it('should work with clicking target=_blank and rel=noopener', async({page, server}) => {
|
||||||
@ -381,7 +384,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
|||||||
it('should work with relaxed search params match', async({page, server}) => {
|
it('should work with relaxed search params match', async({page, server}) => {
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
const [request] = await Promise.all([
|
const [request] = await Promise.all([
|
||||||
page.waitForRequest({ searchParams: { 'foo': ['bar', /^baz$/], 'bar': 'foo' } }),
|
page.waitForRequest({ searchParams: { 'foo': ['bar', /^baz$/], 'bar': 'foo' }, url: /\.png/ }),
|
||||||
page.evaluate(() => {
|
page.evaluate(() => {
|
||||||
fetch('/digits/1.png?key=value&foo=something');
|
fetch('/digits/1.png?key=value&foo=something');
|
||||||
fetch('/digits/2.png?foo=baz');
|
fetch('/digits/2.png?foo=baz');
|
||||||
@ -402,7 +405,7 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
|||||||
it('should throw for incorrect searchParams match', async({page, server}) => {
|
it('should throw for incorrect searchParams match', async({page, server}) => {
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
const [error] = await Promise.all([
|
const [error] = await Promise.all([
|
||||||
page.waitForRequest({ searchParams: { 'foo': 123 } }).catch(e => e),
|
page.waitForRequest({ searchParams: { 'foo': 123 }, url: /\.png/ }).catch(e => e),
|
||||||
page.evaluate(() => {
|
page.evaluate(() => {
|
||||||
fetch('/digits/1.png?foo=bar');
|
fetch('/digits/1.png?foo=bar');
|
||||||
})
|
})
|
||||||
|
@ -252,7 +252,7 @@ module.exports.addTests = function({testRunner, expect, product, playwright, FFO
|
|||||||
await otherFrame.evaluate(addElement, 'div');
|
await otherFrame.evaluate(addElement, 'div');
|
||||||
await page.evaluate(addElement, 'div');
|
await page.evaluate(addElement, 'div');
|
||||||
const eHandle = await watchdog;
|
const eHandle = await watchdog;
|
||||||
expect(eHandle.executionContext().frame()).toBe(page.mainFrame());
|
expect(eHandle.frame()).toBe(page.mainFrame());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should run in specified frame', async({page, server}) => {
|
it('should run in specified frame', async({page, server}) => {
|
||||||
@ -264,7 +264,7 @@ module.exports.addTests = function({testRunner, expect, product, playwright, FFO
|
|||||||
await frame1.evaluate(addElement, 'div');
|
await frame1.evaluate(addElement, 'div');
|
||||||
await frame2.evaluate(addElement, 'div');
|
await frame2.evaluate(addElement, 'div');
|
||||||
const eHandle = await waitForSelectorPromise;
|
const eHandle = await waitForSelectorPromise;
|
||||||
expect(eHandle.executionContext().frame()).toBe(frame2);
|
expect(eHandle.frame()).toBe(frame2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw when frame is detached', async({page, server}) => {
|
it('should throw when frame is detached', async({page, server}) => {
|
||||||
@ -415,7 +415,7 @@ module.exports.addTests = function({testRunner, expect, product, playwright, FFO
|
|||||||
await frame1.evaluate(addElement, 'div');
|
await frame1.evaluate(addElement, 'div');
|
||||||
await frame2.evaluate(addElement, 'div');
|
await frame2.evaluate(addElement, 'div');
|
||||||
const eHandle = await waitForXPathPromise;
|
const eHandle = await waitForXPathPromise;
|
||||||
expect(eHandle.executionContext().frame()).toBe(frame2);
|
expect(eHandle.frame()).toBe(frame2);
|
||||||
});
|
});
|
||||||
it('should throw when frame is detached', async({page, server}) => {
|
it('should throw when frame is detached', async({page, server}) => {
|
||||||
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE);
|
||||||
|
Loading…
Reference in New Issue
Block a user