Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 29 additions & 7 deletions tests/e2e/route-identity.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,39 @@ test('tapping the other label selects that route, without the pick menu', async
await expect(page.locator('.pick-menu')).toHaveCount(0);
});

// A point on the grey line's stroke that a tap really reaches. The middle of
// the path's bounding box is off the line as soon as the route bends, the
// middle of the line can sit under a label (which selects the same route, so
// the test would pass without touching the line), and the fit that frames the
// routes is animated: a point read mid-zoom has moved by the time the click
// lands. So: the first sample the line itself answers to, read until it holds.
async function pointOnGreyLine(page) {
const read = () => page.locator('path.route-alt').evaluate((path) => {
const m = path.getScreenCTM();
const len = path.getTotalLength();
for (let i = 1; i < 20; i++) {
const p = path.getPointAtLength((len * i) / 20);
const x = m.a * p.x + m.c * p.y + m.e;
const y = m.b * p.x + m.d * p.y + m.f;
if (document.elementFromPoint(x, y) === path) return { x, y };
}
return null;
});
let last = null;
await expect.poll(async () => {
const at = await read();
const held = at !== null && last !== null && at.x === last.x && at.y === last.y;
last = at;
return held;
}, { message: 'an uncovered point on the grey line, held still', intervals: [150] }).toBe(true);
return last;
}

test('tapping the grey line selects that route too', async ({ page }) => {
await search(page);
const target = other(await activeTab(page));

// A point on the stroke itself: the middle of the path's bounding box is off
// the line as soon as the route bends.
const at = await page.locator('path.route-alt').evaluate((path) => {
const p = path.getPointAtLength(path.getTotalLength() / 2);
const m = path.getScreenCTM();
return { x: m.a * p.x + m.c * p.y + m.e, y: m.b * p.x + m.d * p.y + m.f };
});
const at = await pointOnGreyLine(page);
await page.mouse.click(at.x, at.y);

await expectSelected(page, target);
Expand Down
30 changes: 26 additions & 4 deletions tests/e2e/scrubber-drawer-overlap.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,25 @@ async function gap(page) {
});
}

const drawerHeight = (page) =>
page.evaluate(() => document.getElementById('results').getBoundingClientRect().height);

// The gap once nothing moves. The drawer and the scrubber both get there
// through CSS transitions (0.32s in main.css), which a loaded runner can
// stretch past any fixed wait: a read mid-way says nothing, and polling for
// "gap >= 0" would pass on the first read, before the drawer has grown. So
// read until two reads in a row agree, and judge that one.
async function settledGap(page) {
let last = null;
await expect.poll(async () => {
const now = await gap(page);
const held = now === last;
last = now;
return held;
}, { message: 'drawer and scrubber at rest', intervals: [150] }).toBe(true);
return last;
}

// Both bottom-sheet viewports on purpose: from 900px up the drawer docks as a
// side panel with the scrubber inside it (main.css), where there is no top
// edge to be pushed under and no handle to expand. That layout has its own
Expand All @@ -78,9 +97,9 @@ for (const viewport of [

await page.click('#drawer-handle');
await expect(page.locator('#results')).toHaveClass(/expanded/);
await page.waitForTimeout(500); // let the 0.32s expand transition settle

expect(await gap(page)).toBeGreaterThanOrEqual(0);
expect(await settledGap(page)).toBeGreaterThanOrEqual(0);
const withoutNote = await drawerHeight(page);

// Scrub into the grazing window: this is what grows the drawer.
await page.locator('#scrubber-range').evaluate(el => {
Expand All @@ -89,9 +108,12 @@ for (const viewport of [
});

await expect(page.locator('#grazing-sun-note')).toHaveClass(/on/);
await page.waitForTimeout(300);

// Otherwise there is nothing for the scrubber to follow, and the check
// below passes whatever the code does.
await expect.poll(() => drawerHeight(page)).toBeGreaterThan(withoutNote);

// The regression: the drawer grew and the scrubber did not follow.
expect(await gap(page)).toBeGreaterThanOrEqual(0);
expect(await settledGap(page)).toBeGreaterThanOrEqual(0);
});
}
Loading