mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix: strict mode on page.* methods on context level (#8324)
This commit is contained in:
parent
356d69ae3f
commit
96a9a26f9f
@ -936,7 +936,7 @@ export class Frame extends SdkObject {
|
|||||||
private async _retryWithProgressIfNotConnected<R>(
|
private async _retryWithProgressIfNotConnected<R>(
|
||||||
progress: Progress,
|
progress: Progress,
|
||||||
selector: string,
|
selector: string,
|
||||||
strict: boolean,
|
strict: boolean | undefined,
|
||||||
action: (handle: dom.ElementHandle<Element>) => Promise<R | 'error:notconnected'>): Promise<R> {
|
action: (handle: dom.ElementHandle<Element>) => Promise<R | 'error:notconnected'>): Promise<R> {
|
||||||
const info = this._page.parseSelector(selector, { strict });
|
const info = this._page.parseSelector(selector, { strict });
|
||||||
while (progress.isRunning()) {
|
while (progress.isRunning()) {
|
||||||
@ -965,28 +965,28 @@ export class Frame extends SdkObject {
|
|||||||
selector: string, options: types.TimeoutOptions & types.StrictOptions,
|
selector: string, options: types.TimeoutOptions & types.StrictOptions,
|
||||||
action: (progress: Progress, handle: dom.ElementHandle<Element>) => Promise<R | 'error:notconnected'>): Promise<R> {
|
action: (progress: Progress, handle: dom.ElementHandle<Element>) => Promise<R | 'error:notconnected'>): Promise<R> {
|
||||||
return controller.run(async progress => {
|
return controller.run(async progress => {
|
||||||
return this._retryWithProgressIfNotConnected(progress, selector, !!options.strict, handle => action(progress, handle));
|
return this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => action(progress, handle));
|
||||||
}, this._page._timeoutSettings.timeout(options));
|
}, this._page._timeoutSettings.timeout(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
async click(metadata: CallMetadata, selector: string, options: types.MouseClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
|
async click(metadata: CallMetadata, selector: string, options: types.MouseClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
return controller.run(async progress => {
|
return controller.run(async progress => {
|
||||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, !!options.strict, handle => handle._click(progress, options)));
|
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._click(progress, options)));
|
||||||
}, this._page._timeoutSettings.timeout(options));
|
}, this._page._timeoutSettings.timeout(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
async dblclick(metadata: CallMetadata, selector: string, options: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
async dblclick(metadata: CallMetadata, selector: string, options: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
return controller.run(async progress => {
|
return controller.run(async progress => {
|
||||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, !!options.strict, handle => handle._dblclick(progress, options)));
|
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._dblclick(progress, options)));
|
||||||
}, this._page._timeoutSettings.timeout(options));
|
}, this._page._timeoutSettings.timeout(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
async dragAndDrop(metadata: CallMetadata, source: string, target: string, options: types.DragActionOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
async dragAndDrop(metadata: CallMetadata, source: string, target: string, options: types.DragActionOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
await controller.run(async progress => {
|
await controller.run(async progress => {
|
||||||
await dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, !!options.strict, async handle => {
|
await dom.assertDone(await this._retryWithProgressIfNotConnected(progress, source, options.strict, async handle => {
|
||||||
return handle._retryPointerAction(progress, 'move and down', false, async point => {
|
return handle._retryPointerAction(progress, 'move and down', false, async point => {
|
||||||
await this._page.mouse.move(point.x, point.y);
|
await this._page.mouse.move(point.x, point.y);
|
||||||
await this._page.mouse.down();
|
await this._page.mouse.down();
|
||||||
@ -996,7 +996,7 @@ export class Frame extends SdkObject {
|
|||||||
timeout: progress.timeUntilDeadline(),
|
timeout: progress.timeUntilDeadline(),
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
await dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, !!options.strict, async handle => {
|
await dom.assertDone(await this._retryWithProgressIfNotConnected(progress, target, options.strict, async handle => {
|
||||||
return handle._retryPointerAction(progress, 'move and up', false, async point => {
|
return handle._retryPointerAction(progress, 'move and up', false, async point => {
|
||||||
await this._page.mouse.move(point.x, point.y);
|
await this._page.mouse.move(point.x, point.y);
|
||||||
await this._page.mouse.up();
|
await this._page.mouse.up();
|
||||||
@ -1012,14 +1012,14 @@ export class Frame extends SdkObject {
|
|||||||
async tap(metadata: CallMetadata, selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
|
async tap(metadata: CallMetadata, selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) {
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
return controller.run(async progress => {
|
return controller.run(async progress => {
|
||||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, !!options.strict, handle => handle._tap(progress, options)));
|
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._tap(progress, options)));
|
||||||
}, this._page._timeoutSettings.timeout(options));
|
}, this._page._timeoutSettings.timeout(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
async fill(metadata: CallMetadata, selector: string, value: string, options: types.NavigatingActionWaitOptions & { force?: boolean }) {
|
async fill(metadata: CallMetadata, selector: string, value: string, options: types.NavigatingActionWaitOptions & { force?: boolean }) {
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
return controller.run(async progress => {
|
return controller.run(async progress => {
|
||||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, !!options.strict, handle => handle._fill(progress, value, options)));
|
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._fill(progress, value, options)));
|
||||||
}, this._page._timeoutSettings.timeout(options));
|
}, this._page._timeoutSettings.timeout(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1123,49 +1123,49 @@ export class Frame extends SdkObject {
|
|||||||
async hover(metadata: CallMetadata, selector: string, options: types.PointerActionOptions & types.PointerActionWaitOptions = {}) {
|
async hover(metadata: CallMetadata, selector: string, options: types.PointerActionOptions & types.PointerActionWaitOptions = {}) {
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
return controller.run(async progress => {
|
return controller.run(async progress => {
|
||||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, !!options.strict, handle => handle._hover(progress, options)));
|
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._hover(progress, options)));
|
||||||
}, this._page._timeoutSettings.timeout(options));
|
}, this._page._timeoutSettings.timeout(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectOption(metadata: CallMetadata, selector: string, elements: dom.ElementHandle[], values: types.SelectOption[], options: types.NavigatingActionWaitOptions & types.ForceOptions = {}): Promise<string[]> {
|
async selectOption(metadata: CallMetadata, selector: string, elements: dom.ElementHandle[], values: types.SelectOption[], options: types.NavigatingActionWaitOptions & types.ForceOptions = {}): Promise<string[]> {
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
return controller.run(async progress => {
|
return controller.run(async progress => {
|
||||||
return await this._retryWithProgressIfNotConnected(progress, selector, !!options.strict, handle => handle._selectOption(progress, elements, values, options));
|
return await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._selectOption(progress, elements, values, options));
|
||||||
}, this._page._timeoutSettings.timeout(options));
|
}, this._page._timeoutSettings.timeout(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
async setInputFiles(metadata: CallMetadata, selector: string, files: channels.ElementHandleSetInputFilesParams['files'], options: types.NavigatingActionWaitOptions = {}): Promise<void> {
|
async setInputFiles(metadata: CallMetadata, selector: string, files: channels.ElementHandleSetInputFilesParams['files'], options: types.NavigatingActionWaitOptions = {}): Promise<void> {
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
return controller.run(async progress => {
|
return controller.run(async progress => {
|
||||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, !!options.strict, handle => handle._setInputFiles(progress, files, options)));
|
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._setInputFiles(progress, files, options)));
|
||||||
}, this._page._timeoutSettings.timeout(options));
|
}, this._page._timeoutSettings.timeout(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
async type(metadata: CallMetadata, selector: string, text: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) {
|
async type(metadata: CallMetadata, selector: string, text: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) {
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
return controller.run(async progress => {
|
return controller.run(async progress => {
|
||||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, !!options.strict, handle => handle._type(progress, text, options)));
|
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._type(progress, text, options)));
|
||||||
}, this._page._timeoutSettings.timeout(options));
|
}, this._page._timeoutSettings.timeout(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
async press(metadata: CallMetadata, selector: string, key: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) {
|
async press(metadata: CallMetadata, selector: string, key: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) {
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
return controller.run(async progress => {
|
return controller.run(async progress => {
|
||||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, !!options.strict, handle => handle._press(progress, key, options)));
|
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._press(progress, key, options)));
|
||||||
}, this._page._timeoutSettings.timeout(options));
|
}, this._page._timeoutSettings.timeout(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
async check(metadata: CallMetadata, selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
async check(metadata: CallMetadata, selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
return controller.run(async progress => {
|
return controller.run(async progress => {
|
||||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, !!options.strict, handle => handle._setChecked(progress, true, options)));
|
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._setChecked(progress, true, options)));
|
||||||
}, this._page._timeoutSettings.timeout(options));
|
}, this._page._timeoutSettings.timeout(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
async uncheck(metadata: CallMetadata, selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
async uncheck(metadata: CallMetadata, selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) {
|
||||||
const controller = new ProgressController(metadata, this);
|
const controller = new ProgressController(metadata, this);
|
||||||
return controller.run(async progress => {
|
return controller.run(async progress => {
|
||||||
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, !!options.strict, handle => handle._setChecked(progress, false, options)));
|
return dom.assertDone(await this._retryWithProgressIfNotConnected(progress, selector, options.strict, handle => handle._setChecked(progress, false, options)));
|
||||||
}, this._page._timeoutSettings.timeout(options));
|
}, this._page._timeoutSettings.timeout(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,6 +35,12 @@ it.describe('strict context mode', () => {
|
|||||||
expect(error.message).toContain('strict mode violation');
|
expect(error.message).toContain('strict mode violation');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should fail page.click in strict mode', async ({ page }) => {
|
||||||
|
await page.setContent(`<button>button1</button><button>target</button>`);
|
||||||
|
const error = await page.click('button').catch(e => e);
|
||||||
|
expect(error.message).toContain('strict mode violation');
|
||||||
|
});
|
||||||
|
|
||||||
it('should opt out of strict mode', async ({ page }) => {
|
it('should opt out of strict mode', async ({ page }) => {
|
||||||
await page.setContent(`<span>span1</span><div><span>target</span></div>`);
|
await page.setContent(`<span>span1</span><div><span>target</span></div>`);
|
||||||
expect(await page.textContent('span', { strict: false })).toBe('span1');
|
expect(await page.textContent('span', { strict: false })).toBe('span1');
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user