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:
-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`):
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('Submit ');
+ 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);