From 321a873d8aff237e78e77f59a95e799ee4ecc16e Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Wed, 27 Jan 2021 15:57:28 -0800 Subject: [PATCH] fix(codegen): add timeout to our actions, catch errors (#5188) --- src/server/supplements/injected/recorder.ts | 2 +- .../supplements/recorder/codeGenerator.ts | 5 +++ src/server/supplements/recorderSupplement.ts | 34 +++++++++++-------- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/server/supplements/injected/recorder.ts b/src/server/supplements/injected/recorder.ts index 1d613818c623e..9cf4fb0268f91 100644 --- a/src/server/supplements/injected/recorder.ts +++ b/src/server/supplements/injected/recorder.ts @@ -608,7 +608,7 @@ export class Recorder { private async _performAction(action: actions.Action) { this._performingAction = true; - await window.playwrightRecorderPerformAction(action); + await window.playwrightRecorderPerformAction(action).catch(e => {}); this._performingAction = false; // Action could have changed DOM, update hovered model selectors. diff --git a/src/server/supplements/recorder/codeGenerator.ts b/src/server/supplements/recorder/codeGenerator.ts index 4f8b349b7db92..c9da6ce253123 100644 --- a/src/server/supplements/recorder/codeGenerator.ts +++ b/src/server/supplements/recorder/codeGenerator.ts @@ -64,6 +64,11 @@ export class CodeGenerator { this._currentAction = action; } + performedActionFailed(action: ActionInContext) { + if (this._currentAction === action) + this._currentAction = undefined; + } + didPerformAction(actionInContext: ActionInContext) { const { action, pageAlias } = actionInContext; let eraseLastAction = false; diff --git a/src/server/supplements/recorderSupplement.ts b/src/server/supplements/recorderSupplement.ts index 56f4820d656c4..7b7d4a4c4d5e4 100644 --- a/src/server/supplements/recorderSupplement.ts +++ b/src/server/supplements/recorderSupplement.ts @@ -194,21 +194,27 @@ export class RecorderSupplement { action }; this._generator.willPerformAction(actionInContext); - if (action.name === 'click') { - const { options } = toClickOptions(action); - await frame.click(controller, action.selector, options); - } - if (action.name === 'press') { - const modifiers = toModifiers(action.modifiers); - const shortcut = [...modifiers, action.key].join('+'); - await frame.press(controller, action.selector, shortcut); + try { + const kActionTimeout = 5000; + if (action.name === 'click') { + const { options } = toClickOptions(action); + await frame.click(controller, action.selector, { ...options, timeout: kActionTimeout }); + } + if (action.name === 'press') { + const modifiers = toModifiers(action.modifiers); + const shortcut = [...modifiers, action.key].join('+'); + await frame.press(controller, action.selector, shortcut, { timeout: kActionTimeout }); + } + if (action.name === 'check') + await frame.check(controller, action.selector, { timeout: kActionTimeout }); + if (action.name === 'uncheck') + await frame.uncheck(controller, action.selector, { timeout: kActionTimeout }); + if (action.name === 'select') + await frame.selectOption(controller, action.selector, [], action.options.map(value => ({ value })), { timeout: kActionTimeout }); + } catch (e) { + this._generator.performedActionFailed(actionInContext); + return; } - if (action.name === 'check') - await frame.check(controller, action.selector); - if (action.name === 'uncheck') - await frame.uncheck(controller, action.selector); - if (action.name === 'select') - await frame.selectOption(controller, action.selector, [], action.options.map(value => ({ value }))); const timer = setTimeout(() => { actionInContext.committed = true; this._timers.delete(timer);