feat(inspector): add keyboard shortcuts (#12014) (#15326)

This commit is contained in:
jfgreffier 2022-07-07 20:25:48 +02:00 committed by GitHub
parent a41a25e07b
commit efec0261a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 88 additions and 40 deletions

View File

@ -146,7 +146,7 @@ If actionability can't be reached, it'll show action as pending:
<img width="712" alt="Pending action" src="https://user-images.githubusercontent.com/883973/108614840-e6e3e500-73b2-11eb-998f-0cf31b2aa9a2.png"></img>
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`):
<center><img width="98" alt="Stepping toolbar" src="https://user-images.githubusercontent.com/883973/108614389-f9f4b600-73ae-11eb-8df2-8d9ce9da5d5c.png"></img></center>

View File

@ -85,6 +85,27 @@ export const Recorder: React.FC<RecorderProps> = ({
}
}, [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 <div className='recorder'>
<Toolbar>
<ToolbarButton icon='record' title='Record' toggled={mode === 'recording'} onClick={() => {
@ -93,13 +114,13 @@ export const Recorder: React.FC<RecorderProps> = ({
<ToolbarButton icon='files' title='Copy' disabled={!source || !source.text} onClick={() => {
copy(source.text);
}}></ToolbarButton>
<ToolbarButton icon='debug-continue' title='Resume' disabled={!paused} onClick={() => {
<ToolbarButton icon='debug-continue' title='Resume (F8)' disabled={!paused} onClick={() => {
window.dispatch({ event: 'resume' });
}}></ToolbarButton>
<ToolbarButton icon='debug-pause' title='Pause' disabled={paused} onClick={() => {
<ToolbarButton icon='debug-pause' title='Pause (F8)' disabled={paused} onClick={() => {
window.dispatch({ event: 'pause' });
}}></ToolbarButton>
<ToolbarButton icon='debug-step-over' title='Step over' disabled={!paused} onClick={() => {
<ToolbarButton icon='debug-step-over' title='Step over (F10)' disabled={!paused} onClick={() => {
window.dispatch({ event: 'step' });
}}></ToolbarButton>
<div style={{ flex: 'auto' }}></div>

View File

@ -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 }) => {

View File

@ -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('<button>Submit</button>');
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);