diff --git a/src/server/frames.ts b/src/server/frames.ts index 09cccf4f67..295bc00c47 100644 --- a/src/server/frames.ts +++ b/src/server/frames.ts @@ -936,7 +936,7 @@ export class Frame extends SdkObject { private async _retryWithProgressIfNotConnected( progress: Progress, selector: string, - strict: boolean, + strict: boolean | undefined, action: (handle: dom.ElementHandle) => Promise): Promise { const info = this._page.parseSelector(selector, { strict }); while (progress.isRunning()) { @@ -965,28 +965,28 @@ export class Frame extends SdkObject { selector: string, options: types.TimeoutOptions & types.StrictOptions, action: (progress: Progress, handle: dom.ElementHandle) => Promise): Promise { 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)); } async click(metadata: CallMetadata, selector: string, options: types.MouseClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions) { const controller = new ProgressController(metadata, this); 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)); } async dblclick(metadata: CallMetadata, selector: string, options: types.MouseMultiClickOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { const controller = new ProgressController(metadata, this); 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)); } async dragAndDrop(metadata: CallMetadata, source: string, target: string, options: types.DragActionOptions & types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { const controller = new ProgressController(metadata, this); 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 => { await this._page.mouse.move(point.x, point.y); await this._page.mouse.down(); @@ -996,7 +996,7 @@ export class Frame extends SdkObject { 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 => { await this._page.mouse.move(point.x, point.y); 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) { const controller = new ProgressController(metadata, this); 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)); } async fill(metadata: CallMetadata, selector: string, value: string, options: types.NavigatingActionWaitOptions & { force?: boolean }) { const controller = new ProgressController(metadata, this); 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)); } @@ -1123,49 +1123,49 @@ export class Frame extends SdkObject { async hover(metadata: CallMetadata, selector: string, options: types.PointerActionOptions & types.PointerActionWaitOptions = {}) { const controller = new ProgressController(metadata, this); 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)); } async selectOption(metadata: CallMetadata, selector: string, elements: dom.ElementHandle[], values: types.SelectOption[], options: types.NavigatingActionWaitOptions & types.ForceOptions = {}): Promise { const controller = new ProgressController(metadata, this); 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)); } async setInputFiles(metadata: CallMetadata, selector: string, files: channels.ElementHandleSetInputFilesParams['files'], options: types.NavigatingActionWaitOptions = {}): Promise { const controller = new ProgressController(metadata, this); 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)); } async type(metadata: CallMetadata, selector: string, text: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) { const controller = new ProgressController(metadata, this); 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)); } async press(metadata: CallMetadata, selector: string, key: string, options: { delay?: number } & types.NavigatingActionWaitOptions = {}) { const controller = new ProgressController(metadata, this); 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)); } async check(metadata: CallMetadata, selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { const controller = new ProgressController(metadata, this); 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)); } async uncheck(metadata: CallMetadata, selector: string, options: types.PointerActionWaitOptions & types.NavigatingActionWaitOptions = {}) { const controller = new ProgressController(metadata, this); 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)); } diff --git a/tests/browsercontext-strict.spec.ts b/tests/browsercontext-strict.spec.ts index 9a9befa0cb..f35ad2f7d5 100644 --- a/tests/browsercontext-strict.spec.ts +++ b/tests/browsercontext-strict.spec.ts @@ -35,6 +35,12 @@ it.describe('strict context mode', () => { expect(error.message).toContain('strict mode violation'); }); + it('should fail page.click in strict mode', async ({ page }) => { + await page.setContent(``); + 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 }) => { await page.setContent(`span1
target
`); expect(await page.textContent('span', { strict: false })).toBe('span1');