-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Description
🚀 Feature Request
Request
I would like all native events to be supported by codegen on all elements.
However, that might be too much to maintain and of course there are custom events and custom elements.
Proposal
Expose a way for the dev to hook into what codegen does, the events that are subscribed to the DOM and what they output.
If so it might be useful to expose the generic codegen impl so dev can register it themselves and override parts of it (e.g. a dev not wanting the default click cmd to be emitted because they are emitting something else such as a dblclick)
This could be done by registering a component in playwright.config
or on the browser context as a fixture for example.
I have been looking at the source code and gathered some entry points, I am willing to contribute.
Code
async _enableRecorder(params: { |
export class Recorder implements InstrumentationListener { |
export class CodeGenerator extends EventEmitter { |
private async _performAction(frame: Frame, action: actions.Action) { |
private _generateActionCall(subject: string, action: Action): string { |
Example
// playwright code
abstract class CodeGenEventHandler {
private _generator;
emit(code: string[]) {
this._generator.append(...code);
}
resloveLocator(event) {
return 'resolved_locator';
}
abstract install(window: Window): void;
}
// playwright.config.ts
import { registerCodeGenEventHandler, CodeGenEventHandler } from 'playwright'
registerCodeGenEventHandler(MyCodeGenEventHandler);
class MyCodeGenEventHandler extends CodeGenEventHandler {
someState: boolean;
install(window: Window) {
window.addEventListener('dragstart', this.dragStart);
window.addEventListener('dragend', this.dragStart);
window.addEventListener('pointerdown', this.pointerDown);
window.addEventListener('pointerup', this.pointerDown);
}
dragStart = (e: DragEvent) => {
this.someState = true;
};
dragEnd = (e: DragEvent) => {
this.emit(['await page.dragAndDrop(this.resolveLocator(e), ...);']);
};
pointerDown = (e: PointerEvent) => {
this.someState = false;
};
pointerUp = (e: PointerEvent) => {
this.emit([
'await page.mouse.down(...);',
'await page.mouse.move(...);',
'await page.mouse.up(...);',
]);
};
}
Motivation
I love playwright, it is super powerful.
Codegen itself makes writing tests so simple that it becomes fun.
Without codegen writing tests is not easy nor fun.
Having to obtain event data (e.g. pointer position) etc. adds a lot of friction.
Furthermore, codegen itself interferes with its locator overlay if the events are not handled by it making it impossible to use it to extract useful data such as locator, pointer position etc.
Supporting this feature will make codegen limitless and will not require additional maintenance.
An attempt to provide a codegen distant ancestor (hacked it up): fabricjs/fabric.js#9350
Another related request: #28474