diff --git a/docs/src/inspector.md b/docs/src/inspector.md index 978b83deb8..7c1dd46cf6 100644 --- a/docs/src/inspector.md +++ b/docs/src/inspector.md @@ -146,7 +146,7 @@ If actionability can't be reached, it'll show action as pending: Pending action -You can step over each action using the "Step over" action or resume script without further pauses: +You can step over each action using the "Step over" action (keyboard shortcut: `F10`) or resume script without further pauses (`F8`):
Stepping toolbar
diff --git a/packages/recorder/src/recorder.tsx b/packages/recorder/src/recorder.tsx index d40cf16a56..ff20979e95 100644 --- a/packages/recorder/src/recorder.tsx +++ b/packages/recorder/src/recorder.tsx @@ -85,6 +85,27 @@ export const Recorder: React.FC = ({ } }, [focusSelectorInput, selectorInputRef]); + React.useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + switch (event.key) { + case 'F8': + event.preventDefault(); + if (paused) + window.dispatch({ event: 'resume' }); + else + window.dispatch({ event: 'pause' }); + break; + case 'F10': + event.preventDefault(); + if (paused) + window.dispatch({ event: 'step' }); + break; + } + }; + document.addEventListener('keydown', handleKeyDown); + return () => document.removeEventListener('keydown', handleKeyDown); + }, [paused]); + return
{ @@ -93,13 +114,13 @@ export const Recorder: React.FC = ({ { copy(source.text); }}> - { + { window.dispatch({ event: 'resume' }); }}> - { + { window.dispatch({ event: 'pause' }); }}> - { + { window.dispatch({ event: 'step' }); }}>
diff --git a/tests/library/inspector/console-api.spec.ts b/tests/library/inspector/console-api.spec.ts index 2b35a6384c..b065eb9fba 100644 --- a/tests/library/inspector/console-api.spec.ts +++ b/tests/library/inspector/console-api.spec.ts @@ -29,9 +29,9 @@ it.beforeEach(async ({ page, recorderPageGetter }) => { it.afterEach(async ({ recorderPageGetter }) => { const recorderPage = await recorderPageGetter(); - recorderPage.click('[title=Resume]').catch(() => {}); + recorderPage.click('[title="Resume (F8)"]').catch(() => {}); await scriptPromise; - recorderPage.click('[title=Resume]').catch(() => {}); + recorderPage.click('[title="Resume (F8)"]').catch(() => {}); }); it('should support playwright.$, playwright.$$', async ({ page }) => { diff --git a/tests/library/inspector/pause.spec.ts b/tests/library/inspector/pause.spec.ts index af8f221b5a..d152d2697b 100644 --- a/tests/library/inspector/pause.spec.ts +++ b/tests/library/inspector/pause.spec.ts @@ -38,7 +38,7 @@ it.describe('pause', () => { return; try { const recorderPage = await recorderPageGetter(); - recorderPage.click('[title=Resume]').catch(() => {}); + recorderPage.click('[title="Resume (F8)"]').catch(() => {}); } catch (e) { // Some tests close context. } @@ -49,7 +49,16 @@ it.describe('pause', () => { await page.pause(); })(); const recorderPage = await recorderPageGetter(); - await recorderPage.click('[title=Resume]'); + await recorderPage.click('[title="Resume (F8)"]'); + await scriptPromise; + }); + + it('should pause and resume the script with keyboard shortcut', async ({ page, recorderPageGetter }) => { + const scriptPromise = (async () => { + await page.pause(); + })(); + const recorderPage = await recorderPageGetter(); + await recorderPage.keyboard.press('F8'); await scriptPromise; }); @@ -71,7 +80,7 @@ it.describe('pause', () => { await page.pause(); })(); const recorderPage = await recorderPageGetter(); - await recorderPage.click('[title=Resume]'); + await recorderPage.click('[title="Resume (F8)"]'); await scriptPromise; }); @@ -82,7 +91,7 @@ it.describe('pause', () => { const recorderPage = await recorderPageGetter(); const source = await recorderPage.textContent('.source-line-paused .source-code'); expect(source).toContain('page.pause()'); - await recorderPage.click('[title=Resume]'); + await recorderPage.click('[title="Resume (F8)"]'); await scriptPromise; }); @@ -94,9 +103,9 @@ it.describe('pause', () => { const recorderPage = await recorderPageGetter(); const source = await recorderPage.textContent('.source-line-paused'); expect(source).toContain('page.pause(); // 1'); - await recorderPage.click('[title=Resume]'); + await recorderPage.click('[title="Resume (F8)"]'); await recorderPage.waitForSelector('.source-line-paused:has-text("page.pause(); // 2")'); - await recorderPage.click('[title=Resume]'); + await recorderPage.click('[title="Resume (F8)"]'); await scriptPromise; }); @@ -110,10 +119,28 @@ it.describe('pause', () => { const source = await recorderPage.textContent('.source-line-paused'); expect(source).toContain('page.pause();'); - await recorderPage.click('[title="Step over"]'); + await recorderPage.click('[title="Step over (F10)"]'); await recorderPage.waitForSelector('.source-line-paused :has-text("page.click")'); - await recorderPage.click('[title=Resume]'); + await recorderPage.click('[title="Resume (F8)"]'); + await scriptPromise; + }); + + it('should step with keyboard shortcut', async ({ page, recorderPageGetter }) => { + await page.setContent(''); + const scriptPromise = (async () => { + await page.pause(); + await page.click('button'); + })(); + const recorderPage = await recorderPageGetter(); + const source = await recorderPage.textContent('.source-line-paused'); + expect(source).toContain('page.pause();'); + + await recorderPage.keyboard.press('F10'); + await recorderPage.waitForSelector('.source-line-paused :has-text("page.click")'); + await recorderPage.isEnabled('[title="Resume (F8)"]'); + + await recorderPage.keyboard.press('F8'); await scriptPromise; }); @@ -125,7 +152,7 @@ it.describe('pause', () => { await page.click('button'); })(); const recorderPage = await recorderPageGetter(); - await recorderPage.click('[title="Step over"]'); + await recorderPage.click('[title="Step over (F10)"]'); const { x, y } = await actionPointPromise; const button = await page.waitForSelector('button'); @@ -137,7 +164,7 @@ it.describe('pause', () => { expect(Math.abs(x1 - x) < 2).toBeTruthy(); expect(Math.abs(y1 - y) < 2).toBeTruthy(); - await recorderPage.click('[title=Resume]'); + await recorderPage.click('[title="Resume (F8)"]'); await scriptPromise; }); @@ -149,9 +176,9 @@ it.describe('pause', () => { await page.pause(); // 2 })(); const recorderPage = await recorderPageGetter(); - await recorderPage.click('[title="Resume"]'); + await recorderPage.click('[title="Resume (F8)"]'); await recorderPage.waitForSelector('.source-line-paused:has-text("page.pause(); // 2")'); - await recorderPage.click('[title=Resume]'); + await recorderPage.click('[title="Resume (F8)"]'); await scriptPromise; }); @@ -163,14 +190,14 @@ it.describe('pause', () => { await page.pause(); // 2 })(); const recorderPage = await recorderPageGetter(); - await recorderPage.click('[title="Resume"]'); + await recorderPage.click('[title="Resume (F8)"]'); await recorderPage.waitForSelector('.source-line-paused:has-text("page.pause(); // 2")'); expect(await sanitizeLog(recorderPage)).toEqual([ 'page.pause- XXms', 'page.click(button)- XXms', 'page.pause', ]); - await recorderPage.click('[title="Resume"]'); + await recorderPage.click('[title="Resume (F8)"]'); await scriptPromise; }); @@ -186,7 +213,7 @@ it.describe('pause', () => { await page.pause(); // 2 })(); const recorderPage = await recorderPageGetter(); - await recorderPage.click('[title="Resume"]'); + await recorderPage.click('[title="Resume (F8)"]'); await recorderPage.waitForSelector('.source-line-paused:has-text("page.pause(); // 2")'); expect(await sanitizeLog(recorderPage)).toEqual([ 'page.pause- XXms', @@ -194,7 +221,7 @@ it.describe('pause', () => { 'tracing.stop- XXms', 'page.pause', ]); - await recorderPage.click('[title="Resume"]'); + await recorderPage.click('[title="Resume (F8)"]'); await scriptPromise; }); @@ -206,14 +233,14 @@ it.describe('pause', () => { await page.pause(); // 2 })(); const recorderPage = await recorderPageGetter(); - await recorderPage.click('[title="Resume"]'); + await recorderPage.click('[title="Resume (F8)"]'); await recorderPage.waitForSelector('.source-line-paused:has-text("page.pause(); // 2")'); expect(await sanitizeLog(recorderPage)).toEqual([ 'page.pause- XXms', 'expect.toHaveText(button)- XXms', 'page.pause', ]); - await recorderPage.click('[title="Resume"]'); + await recorderPage.click('[title="Resume (F8)"]'); await scriptPromise; }); @@ -227,10 +254,10 @@ it.describe('pause', () => { ]); })(); const recorderPage = await recorderPageGetter(); - await recorderPage.click('[title="Step over"]'); + await recorderPage.click('[title="Step over (F10)"]'); await recorderPage.waitForSelector('.source-line-paused:has-text("page.click")'); await recorderPage.waitForSelector('.source-line-running:has-text("page.waitForEvent")'); - await recorderPage.click('[title="Resume"]'); + await recorderPage.click('[title="Resume (F8)"]'); await scriptPromise; }); @@ -245,7 +272,7 @@ it.describe('pause', () => { await page.pause(); // 2 })(); const recorderPage = await recorderPageGetter(); - await recorderPage.click('[title="Resume"]'); + await recorderPage.click('[title="Resume (F8)"]'); await recorderPage.waitForSelector('.source-line-paused:has-text("page.pause(); // 2")'); expect(await sanitizeLog(recorderPage)).toEqual([ 'page.pause- XXms', @@ -253,7 +280,7 @@ it.describe('pause', () => { 'page.click(button)- XXms', 'page.pause', ]); - await recorderPage.click('[title="Resume"]'); + await recorderPage.click('[title="Resume (F8)"]'); await scriptPromise; }); @@ -264,7 +291,7 @@ it.describe('pause', () => { await page.isChecked('button'); })().catch(e => e); const recorderPage = await recorderPageGetter(); - await recorderPage.click('[title="Resume"]'); + await recorderPage.click('[title="Resume (F8)"]'); await recorderPage.waitForSelector('.source-line-error'); expect(await sanitizeLog(recorderPage)).toEqual([ 'page.pause- XXms', @@ -287,7 +314,7 @@ it.describe('pause', () => { ]); })(); const recorderPage = await recorderPageGetter(); - await recorderPage.click('[title="Step over"]'); + await recorderPage.click('[title="Step over (F10)"]'); await recorderPage.waitForSelector('.source-line-paused:has-text("page.pause")'); await recorderPage.waitForSelector('.source-line-error:has-text("page.waitForEvent")'); expect(await sanitizeLog(recorderPage)).toEqual([ @@ -297,7 +324,7 @@ it.describe('pause', () => { 'error: Timeout 1ms exceeded while waiting for event \"console\"', 'page.pause', ]); - await recorderPage.click('[title="Resume"]'); + await recorderPage.click('[title="Resume (F8)"]'); await scriptPromise; }); @@ -307,9 +334,9 @@ it.describe('pause', () => { await page.close(); })(); const recorderPage = await recorderPageGetter(); - await recorderPage.click('[title="Step over"]'); + await recorderPage.click('[title="Step over (F10)"]'); await recorderPage.waitForSelector('.source-line-paused:has-text("page.close();")'); - await recorderPage.click('[title=Resume]'); + await recorderPage.click('[title="Resume (F8)"]'); await scriptPromise; }); @@ -319,10 +346,10 @@ it.describe('pause', () => { await page.context().close(); })(); const recorderPage = await recorderPageGetter(); - await recorderPage.click('[title="Step over"]'); + await recorderPage.click('[title="Step over (F10)"]'); await recorderPage.waitForSelector('.source-line-paused:has-text("page.context().close();")'); // Next line can throw because closing context also closes the inspector page. - await recorderPage.click('[title=Resume]').catch(e => {}); + await recorderPage.click('[title="Resume (F8)"]').catch(e => {}); await scriptPromise; }); @@ -339,7 +366,7 @@ it.describe('pause', () => { const button = await page.$('text=Submit'); const box2 = await button.boundingBox(); expect(roundBox(box1)).toEqual(roundBox(box2)); - await recorderPage.click('[title=Resume]'); + await recorderPage.click('[title="Resume (F8)"]'); await scriptPromise; }); @@ -358,13 +385,13 @@ it.describe('pause', () => { })(); const recorderPage = await recorderPageGetter(); await recorderPage.waitForSelector(`.source-line-paused:has-text("page.pause")`); - await recorderPage.click('[title="Step over"]'); + await recorderPage.click('[title="Step over (F10)"]'); await recorderPage.waitForSelector(`.source-line-paused:has-text("press('Enter')")`); - await recorderPage.click('[title="Step over"]'); + await recorderPage.click('[title="Step over (F10)"]'); await recorderPage.waitForSelector(`.source-line-paused:has-text("press('A')")`); - await recorderPage.click('[title="Step over"]'); + await recorderPage.click('[title="Step over (F10)"]'); await recorderPage.waitForSelector(`.source-line-paused:has-text("press('Shift+A')")`); - await recorderPage.click('[title=Resume]'); + await recorderPage.click('[title="Resume (F8)"]'); await scriptPromise; const log = await page.evaluate(() => (window as any).log);