fix(recorder): address custom context menus (#31634)
This commit is contained in:
parent
3cb41739a0
commit
e06481a332
|
|
@ -259,6 +259,28 @@ class RecordActionTool implements RecorderTool {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onContextMenu(event: MouseEvent) {
|
||||||
|
// the 'contextmenu' event is triggered by a right-click or equivalent action,
|
||||||
|
// and it prevents the click event from firing for that action, so we always
|
||||||
|
// convert 'contextmenu' into a right-click.
|
||||||
|
if (this._shouldIgnoreMouseEvent(event))
|
||||||
|
return;
|
||||||
|
if (this._actionInProgress(event))
|
||||||
|
return;
|
||||||
|
if (this._consumedDueToNoModel(event, this._hoveredModel))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this._performAction({
|
||||||
|
name: 'click',
|
||||||
|
selector: this._hoveredModel!.selector,
|
||||||
|
position: positionForEvent(event),
|
||||||
|
signals: [],
|
||||||
|
button: 'right',
|
||||||
|
modifiers: 0,
|
||||||
|
clickCount: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onPointerDown(event: PointerEvent) {
|
onPointerDown(event: PointerEvent) {
|
||||||
if (this._shouldIgnoreMouseEvent(event))
|
if (this._shouldIgnoreMouseEvent(event))
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -559,6 +559,60 @@ await page.GetByLabel("Coun\\"try").ClickAsync();`);
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should consume contextmenu events, despite a custom context menu', async ({ page, openRecorder }) => {
|
||||||
|
const recorder = await openRecorder();
|
||||||
|
|
||||||
|
await recorder.setContentAndWait(`
|
||||||
|
<button>Right click me.</button>
|
||||||
|
<div id="menu" style="display: none; position: absolute;">
|
||||||
|
<button>Menu option 1</button>
|
||||||
|
<button>Menu option 2</button>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
const button = document.querySelector('button');
|
||||||
|
button.addEventListener('contextmenu', e => {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log('right-clicked');
|
||||||
|
|
||||||
|
// show custom context menu
|
||||||
|
const menu = document.getElementById("menu");
|
||||||
|
menu.style.display = "block";
|
||||||
|
menu.style.left = \`\${e.pageX}px\`;
|
||||||
|
menu.style.top = \`\${e.pageY}px\`;
|
||||||
|
});
|
||||||
|
const log = [];
|
||||||
|
for (const eventName of ['mousedown', 'mousemove', 'mouseup', 'pointerdown', 'pointermove', 'pointerup', 'click', 'contextmenu']) {
|
||||||
|
button.addEventListener(eventName, e => log.push('button: ' + e.type));
|
||||||
|
menu.addEventListener(eventName, e => log.push('menu: ' + e.type));
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
`);
|
||||||
|
|
||||||
|
await recorder.hoverOverElement('button');
|
||||||
|
expect(await page.evaluate('log')).toEqual(['button: pointermove', 'button: mousemove']);
|
||||||
|
|
||||||
|
const [message] = await Promise.all([
|
||||||
|
page.waitForEvent('console', msg => msg.type() !== 'error'),
|
||||||
|
recorder.waitForOutput('JavaScript', `button: 'right'`),
|
||||||
|
recorder.trustedClick({ button: 'right' }),
|
||||||
|
]);
|
||||||
|
expect(message.text()).toBe('right-clicked');
|
||||||
|
expect(await page.evaluate('log')).toEqual([
|
||||||
|
// hover
|
||||||
|
'button: pointermove',
|
||||||
|
'button: mousemove',
|
||||||
|
// trusted right click
|
||||||
|
'button: pointerup',
|
||||||
|
'button: pointermove',
|
||||||
|
'button: mousemove',
|
||||||
|
'button: pointerdown',
|
||||||
|
'button: mousedown',
|
||||||
|
'button: contextmenu',
|
||||||
|
'menu: pointerup',
|
||||||
|
'menu: mouseup'
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
test('should assert value', async ({ openRecorder }) => {
|
test('should assert value', async ({ openRecorder }) => {
|
||||||
const recorder = await openRecorder();
|
const recorder = await openRecorder();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -186,9 +186,9 @@ class Recorder {
|
||||||
await this.page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
await this.page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
async trustedClick() {
|
async trustedClick(options?: { button?: 'left' | 'right' | 'middle' }) {
|
||||||
await this.page.mouse.down();
|
await this.page.mouse.down(options);
|
||||||
await this.page.mouse.up();
|
await this.page.mouse.up(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async focusElement(selector: string): Promise<string> {
|
async focusElement(selector: string): Promise<string> {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue