diff --git a/packages/playwright-core/src/server/injected/recorder/recorder.ts b/packages/playwright-core/src/server/injected/recorder/recorder.ts index c255a14b08..757b413704 100644 --- a/packages/playwright-core/src/server/injected/recorder/recorder.ts +++ b/packages/playwright-core/src/server/injected/recorder/recorder.ts @@ -205,7 +205,7 @@ class InspectTool implements RecorderTool { class RecordActionTool implements RecorderTool { private _recorder: Recorder; - private _performingAction = false; + private _performingAction: actions.PerformOnRecordAction | null = null; private _hoveredModel: HighlightModel | null = null; private _hoveredElement: HTMLElement | null = null; private _activeModel: HighlightModel | null = null; @@ -508,9 +508,15 @@ class RecordActionTool implements RecorderTool { private _actionInProgress(event: Event): boolean { // If Playwright is performing action for us, bail. - if (this._performingAction) + const isKeyEvent = event instanceof KeyboardEvent; + if (this._performingAction?.name === 'press' && isKeyEvent && event.key === this._performingAction.key) return true; - // Consume as the first thing. + + const isMouseOrPointerEvent = event instanceof MouseEvent || event instanceof PointerEvent; + if (isMouseOrPointerEvent && (this._performingAction?.name === 'click' || this._performingAction?.name === 'check' || this._performingAction?.name === 'uncheck')) + return true; + + // Consume event if action is not being executed. consumeEvent(event); return false; } @@ -534,9 +540,9 @@ class RecordActionTool implements RecorderTool { this._hoveredModel = null; this._activeModel = null; this._recorder.updateHighlight(null, false); - this._performingAction = true; + this._performingAction = action; void this._recorder.performAction(action).then(() => { - this._performingAction = false; + this._performingAction = null; // If that was a keyboard action, it similarly requires new selectors for active model. this._onFocus(false); diff --git a/tests/library/inspector/cli-codegen-1.spec.ts b/tests/library/inspector/cli-codegen-1.spec.ts index 00fe3d6802..d825ed6e93 100644 --- a/tests/library/inspector/cli-codegen-1.spec.ts +++ b/tests/library/inspector/cli-codegen-1.spec.ts @@ -413,7 +413,7 @@ await page.GetByRole(AriaRole.Textbox).PressAsync("Shift+Enter");`); expect(messages[0].text()).toBe('press'); }); - test('should update selected element after pressing Tab', async ({ openRecorder }) => { + test('should update selected element after pressing Tab', async ({ openRecorder, browserName, codegenMode }) => { const { page, recorder } = await openRecorder(); await recorder.setContentAndWait(` @@ -429,6 +429,9 @@ await page.GetByRole(AriaRole.Textbox).PressAsync("Shift+Enter");`); await page.keyboard.press('Tab'); await recorder.waitForOutput('JavaScript', 'Tab'); await page.keyboard.type('barfoo321'); + // I can't explain it atm, first character is being consumed for no apparent reason. + if (browserName === 'webkit' && codegenMode === 'trace-events') + await page.waitForTimeout(1000); await recorder.waitForOutput('JavaScript', 'barfoo321'); const text = recorder.sources().get('JavaScript')!.text; diff --git a/tests/library/inspector/cli-codegen-2.spec.ts b/tests/library/inspector/cli-codegen-2.spec.ts index 11355008e1..0a130e0936 100644 --- a/tests/library/inspector/cli-codegen-2.spec.ts +++ b/tests/library/inspector/cli-codegen-2.spec.ts @@ -427,7 +427,7 @@ await page1.GotoAsync("about:blank?foo");`); page.click('button'), recorder.waitForOutput('JavaScript', '.click(') ]); - expect(messages).toEqual(['mousedown', 'mouseup', 'click']); + await expect.poll(() => messages).toEqual(['mousedown', 'mouseup', 'click']); }); test('should update hover model on action', async ({ openRecorder }) => {