Skip to content

Commit

Permalink
feat(codegen): slider support
Browse files Browse the repository at this point in the history
  • Loading branch information
ruifigueira committed Jan 30, 2024
1 parent 14f94fc commit 505499c
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@ class RecordActionTool implements RecorderTool {
}

onClick(event: MouseEvent) {
// in webkit, when clicking a range input, event target is the body element and not the input itself.
// So we check the hovered element instead, and if it is a range input, we skip click handling
if (isRangeInput(this._hoveredElement))
return;
if (this._shouldIgnoreMouseEvent(event))
return;
if (this._actionInProgress(event))
Expand Down Expand Up @@ -317,6 +321,17 @@ class RecordActionTool implements RecorderTool {
return;
}

if (isRangeInput(target)) {
this._recorder.delegate.recordAction?.({
name: 'fill',
// must use hoveredModel instead of activeModel for it to work in webkit
selector: this._hoveredModel!.selector,
signals: [],
text: target.value,
});
return;
}

if (['INPUT', 'TEXTAREA'].includes(target.nodeName) || target.isContentEditable) {
if (target.nodeName === 'INPUT' && ['checkbox', 'radio'].includes((target as HTMLInputElement).type.toLowerCase())) {
// Checkbox is handled in click, we can't let input trigger on checkbox - that would mean we dispatched click events while recording.
Expand Down Expand Up @@ -414,7 +429,7 @@ class RecordActionTool implements RecorderTool {
const nodeName = target.nodeName;
if (nodeName === 'SELECT' || nodeName === 'OPTION')
return true;
if (nodeName === 'INPUT' && ['date'].includes((target as HTMLInputElement).type))
if (nodeName === 'INPUT' && ['date', 'range'].includes((target as HTMLInputElement).type))
return true;
return false;
}
Expand Down Expand Up @@ -1216,6 +1231,13 @@ function asCheckbox(node: Node | null): HTMLInputElement | null {
return ['checkbox', 'radio'].includes(inputElement.type) ? inputElement : null;
}

function isRangeInput(node: Node | null): node is HTMLInputElement {
if (!node || node.nodeName !== 'INPUT')
return false;
const inputElement = node as HTMLInputElement;
return inputElement.type.toLowerCase() === 'range';
}

function addEventListener(target: EventTarget, eventName: string, listener: EventListener, useCapture?: boolean): () => void {
target.addEventListener(eventName, listener, useCapture);
const remove = () => {
Expand Down
39 changes: 39 additions & 0 deletions tests/library/inspector/cli-codegen-1.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -746,4 +746,43 @@ await page.GetByText("Click me").ClickAsync(new LocatorClickOptions
Button = MouseButton.Middle,
});`);
});

test('should record slider', async ({ page, openRecorder }) => {
const recorder = await openRecorder();

await recorder.setContentAndWait(`<input type="range" min="0" max="10" value="5">`);

const dragSlider = async () => {
const { x, y, width, height } = await page.locator('input').boundingBox();
await page.mouse.move(x + width / 2, y + height / 2);
await page.mouse.down();
await page.mouse.move(x + width, y + height / 2);
await page.mouse.up();
};

const [sources] = await Promise.all([
recorder.waitForOutput('JavaScript', 'fill'),
dragSlider(),
]);

await expect(page.locator('input')).toHaveValue('10');

expect(sources.get('JavaScript')!.text).not.toContain(`
await page.getByRole('slider').click();`);

expect(sources.get('JavaScript')!.text).toContain(`
await page.getByRole('slider').fill('10');`);

expect.soft(sources.get('Python')!.text).toContain(`
page.get_by_role("slider").fill("10")`);

expect.soft(sources.get('Python Async')!.text).toContain(`
await page.get_by_role("slider").fill("10")`);

expect.soft(sources.get('Java')!.text).toContain(`
page.getByRole(AriaRole.SLIDER).fill("10")`);

expect.soft(sources.get('C#')!.text).toContain(`
await page.GetByRole(AriaRole.Slider).FillAsync("10");`);
});
});

0 comments on commit 505499c

Please sign in to comment.