Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(range): remove gesture flakiness #29241

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
111 changes: 81 additions & 30 deletions core/src/components/range/test/range-events.e2e.ts
Expand Up @@ -7,10 +7,7 @@ import { configs, dragElementBy, test } from '@utils/test/playwright';
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
test.describe(title('range: events:'), () => {
test.describe('range: knob events', () => {
/**
* The mouse events are flaky on CI
*/
test.fixme('should emit start/end events', async ({ page }) => {
test('should emit start/end events', async ({ page }) => {
/**
* Requires padding to prevent the knob from being clipped.
* If it's clipped, then the value might be one off.
Expand All @@ -31,23 +28,34 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>

const rangeEl = page.locator('ion-range');

await dragElementBy(rangeEl, page, 300, 0);
await page.waitForChanges();

/**
* dragElementBy defaults to starting the drag from the middle of the el,
* so the start value should jump to 50 despite the range defaulting to 20.
* Verify both events fire if range is dragged.
*/
expect(rangeStart).toHaveReceivedEventDetail({ value: 50 });
await dragElementBy(rangeEl, page, 180);

await rangeStart.next();
await rangeEnd.next();

// Once the knob is dragged, the start event should fire with
// the initial value.
expect(rangeStart).toHaveReceivedEventDetail({ value: 20 });
// Once the knob is released, the end event should fire with
// the final value.
expect(rangeEnd).toHaveReceivedEventDetail({ value: 100 });

/**
* Verify both events fire if range is clicked without dragging.
* Verify both events fire if range is tapped without dragging.
*/
await dragElementBy(rangeEl, page, 0, 0);
await page.waitForChanges();

expect(rangeStart).toHaveReceivedEventDetail({ value: 50 });
await rangeStart.next();
await rangeEnd.next();

// Once the tap is released, the start event should fire with
// the initial value.
expect(rangeStart).toHaveReceivedEventDetail({ value: 100 });
// Once the tap is released, the end event should fire with
// the final value.
expect(rangeEnd).toHaveReceivedEventDetail({ value: 50 });
});

Expand Down Expand Up @@ -100,18 +108,39 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
expect(rangeEndSpy.length).toBe(1);
});

// TODO FW-2873
test.skip('should not scroll when the knob is swiped', async ({ page, skip }) => {
test('should not scroll when the knob is swiped', async ({ page, skip }) => {
skip.browser('webkit', 'mouse.wheel is not available in WebKit');

await page.goto(`/src/components/range/test/basic`, config);
/**
* Requires padding to prevent the knob from being clipped.
* If it's clipped, then the value might be one off.
* For example, if the knob is clipped on the right, then the value
* will be 99 instead of 100.
*
* The ion-content is also required to be taller than the viewport
* to allow for scrolling.
*/
await page.setContent(
`
<style>
ion-content {
--padding-start: 20px;
--padding-end: 20px;
}
</style>
<ion-content style="padding: 0 20px; height: 2000px;">
<ion-range aria-label="Range"></ion-range>
</ion-content>
`,
config
);

const knobEl = page.locator('ion-range#stacked-range .range-knob-handle');
const rangeEl = page.locator('ion-range');
const scrollEl = page.locator('ion-content .inner-scroll');

expect(await scrollEl.evaluate((el: HTMLElement) => el.scrollTop)).toEqual(0);

await dragElementBy(knobEl, page, 30, 0, undefined, undefined, false);
await dragElementBy(rangeEl, page, 100, 0, undefined, undefined, false);

/**
* Do not use scrollToBottom() or other scrolling methods
Expand Down Expand Up @@ -151,14 +180,26 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
expect(ionChangeSpy).toHaveReceivedEventTimes(0);
});

// TODO FW-2873
test.skip('should emit when the knob is released', async ({ page }) => {
await page.setContent(`<ion-range aria-label="range"></ion-range>`, config);
test('should emit when the knob is released', async ({ page }) => {
/**
* Requires padding to prevent the knob from being clipped.
* If it's clipped, then the value might be one off.
* For example, if the knob is clipped on the right, then the value
* will be 99 instead of 100.
*/
await page.setContent(
`
<div style="padding: 0 20px">
<ion-range aria-label="Range"></ion-range>
</div>
`,
config
);

const rangeHandle = page.locator('ion-range .range-knob-handle');
const rangeEl = page.locator('ion-range');
const ionChangeSpy = await page.spyOnEvent('ionChange');

await dragElementBy(rangeHandle, page, 100, 0);
await dragElementBy(rangeEl, page, 100);

await ionChangeSpy.next();

Expand Down Expand Up @@ -196,16 +237,26 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
});

test.describe('ionInput', () => {
// TODO(FW-2873) Enable this test when touch events/gestures are better supported in Playwright
test.skip('should emit when the knob is dragged', async ({ page }) => {
await page.setContent(`<ion-range aria-label="range"></ion-range>`, config);
test('should emit when the knob is dragged', async ({ page }) => {
/**
* Requires padding to prevent the knob from being clipped.
* If it's clipped, then the value might be one off.
* For example, if the knob is clipped on the right, then the value
* will be 99 instead of 100.
*/
await page.setContent(
`
<div style="padding: 0 20px">
<ion-range aria-label="range"></ion-range>
</div>
`,
config
);

const rangeHandle = page.locator('ion-range .range-knob-handle');
const rangeEl = page.locator('ion-range');
const ionInputSpy = await page.spyOnEvent('ionInput');

await rangeHandle.hover();

await dragElementBy(rangeHandle, page, 100, 0, undefined, undefined, false);
await dragElementBy(rangeEl, page, 100);

await ionInputSpy.next();

Expand Down