fix(ui): a looping pulse stops for reduced motion; the e2e waits for skeleton bones, not for any pulse
- Seven looping pulses (a running job's dot, the scheduler's progress bar, a queued download, the download tray, a playlist upload, a channel's full-history action, the setup wizard's test mail) ran regardless of prefers-reduced-motion, which docs/DESIGN.md promises to respect: each is motion-safe now, held by a contract test. - The a11y suite's "settled" wait took every aria-hidden pulse for a loading skeleton, so the Scheduler legend's running dot, which pulses for good, kept it waiting until it timed out. A skeleton bone now says it is one (data-skeleton) and the wait looks for that.
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
import { readdirSync, readFileSync } from "node:fs";
|
||||
|
||||
import { expect, it } from "vitest";
|
||||
|
||||
// docs/DESIGN.md (Motion): `prefers-reduced-motion` is respected. A pulse that loops for as long as
|
||||
// something lasts — a running job's dot, a queued download, a skeleton bone — is the motion that rule
|
||||
// is about, and seven of them pulsed regardless. Each is `motion-safe:animate-pulse`, or pairs the
|
||||
// pulse with `motion-reduce:animate-none` on the same line.
|
||||
function sources(): Array<[string, string]> {
|
||||
const walk = (u: URL, prefix: string): Array<[string, string]> =>
|
||||
readdirSync(u, { withFileTypes: true }).flatMap((e) => {
|
||||
if (e.isDirectory()) return walk(new URL(`${e.name}/`, u), `${prefix}${e.name}/`);
|
||||
if (!/\.tsx?$/.test(e.name) || e.name.includes(".test.")) return [];
|
||||
return [
|
||||
[`${prefix}${e.name}`, readFileSync(new URL(e.name, u), "utf-8")] as [string, string],
|
||||
];
|
||||
});
|
||||
return walk(new URL("../", import.meta.url), "");
|
||||
}
|
||||
|
||||
it("every looping pulse stops for a reader who asked for less motion", () => {
|
||||
const unguarded = sources().flatMap(([name, src]) =>
|
||||
src
|
||||
.split("\n")
|
||||
.map((line, i) => [line, i + 1] as const)
|
||||
.filter(
|
||||
([line]) =>
|
||||
/(?<!motion-safe:)\banimate-pulse\b/.test(line) &&
|
||||
!line.includes("motion-reduce:animate-none"),
|
||||
)
|
||||
.map(([, n]) => `${name}:${n}`),
|
||||
);
|
||||
expect(unguarded).toEqual([]);
|
||||
});
|
||||
Reference in New Issue
Block a user