Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
156 commits
Select commit Hold shift + click to select a range
dc6ae1e
test(interaction): real touch input for browser interaction proofs
vjeux Oct 24, 2026
75fc6cb
fix(interaction): release only the lifted finger on a partial lift in…
vjeux Oct 24, 2026
0a07aa1
fix(interaction): join the proofs to test, keep their setup in scope,…
vjeux Oct 24, 2026
5f2ed50
fix(interaction): releaseVelocity measures from when the finger reach…
vjeux Oct 24, 2026
d3c13cc
test(interaction): curve sampling and deterministic storyboards
vjeux Oct 24, 2026
65c017e
fix(interaction): curves end before a held end value; rest judges pre…
vjeux Oct 24, 2026
d8af73a
fix(interaction): hold only running animations at their own offsets, …
vjeux Oct 24, 2026
2e170f5
fix(interaction): film from each animation's own offset, label sample…
vjeux Oct 25, 2026
04cbfc5
fix(interaction): waitForAnimation sees a short animation that ended …
vjeux Oct 25, 2026
d29981d
refactor(interaction): the storyboard layer moves to its own pull req…
vjeux Oct 25, 2026
beecc80
test(interaction): a second hold adds to the held set
vjeux Oct 25, 2026
4a6dfbe
test(interaction): deterministic storyboards
vjeux Oct 25, 2026
eec2404
test(interaction): a touch filmstrip's handler clock follows its pacing
vjeux Oct 25, 2026
0954697
test(interaction): frame evidence and the BottomSheet exemplar
vjeux Oct 24, 2026
6be18c6
test(interaction): make the busy-main-thread verdict robust to a load…
vjeux Oct 24, 2026
3f39b21
test(BottomSheet): pin the settle's easing and duration instead of re…
vjeux Oct 24, 2026
03eadf9
test(interaction): block after the frame's rendering update; rebase W…
vjeux Oct 25, 2026
ffc2bd4
Merge branch 'main' into interaction-harness-2-curves
vjeux Oct 25, 2026
e918a2f
Merge branch 'interaction-harness-2-curves' into uikit/f3-storyboards
vjeux Oct 25, 2026
79a1fed
Merge branch 'uikit/f3-storyboards' into interaction-harness-3-frames
vjeux Oct 25, 2026
8d0a829
test(interaction): a held animation the page cancels leaves the held set
vjeux Oct 25, 2026
cb37bd7
Merge branch 'interaction-harness-2-curves' into uikit/f3-storyboards
vjeux Oct 25, 2026
0b4d12b
Merge branch 'uikit/f3-storyboards' into interaction-harness-3-frames
vjeux Oct 25, 2026
a499860
docs(interaction): the touch filmstrip's clock limit names no missing…
vjeux Oct 25, 2026
212ec1d
Merge branch 'uikit/f3-storyboards' into interaction-harness-3-frames
vjeux Oct 25, 2026
b36bf63
docs(interaction): the touch filmstrip's clock limit names the screen…
vjeux Oct 25, 2026
91f8ddd
test(interaction): a hold stays where it was read
vjeux Oct 25, 2026
b5783ed
Merge branch 'interaction-harness-2-curves' into uikit/f3-storyboards
vjeux Oct 25, 2026
2a718ad
Merge branch 'uikit/f3-storyboards' into interaction-harness-3-frames
vjeux Oct 25, 2026
3f44fe9
test(interaction): a block never starts on a pending animation
vjeux Oct 25, 2026
bc744cb
test(interaction): the WebKit container keeps compiled shaders betwee…
vjeux Oct 25, 2026
f898984
Merge commit 'refs/f3/main' into interaction-harness-1-touch
vjeux Oct 25, 2026
824bc84
Merge branch 'interaction-harness-1-touch' into interaction-harness-2…
vjeux Oct 25, 2026
0e3e379
Merge branch 'interaction-harness-2-curves' into uikit/f3-storyboards
vjeux Oct 25, 2026
9716595
Merge branch 'uikit/f3-storyboards' into interaction-harness-3-frames
vjeux Oct 25, 2026
4538572
ci: the harness's typecheck runs through pnpm typecheck, once
vjeux Oct 25, 2026
26f2b98
test(interaction): a watch on first contact ignores what already runs
vjeux Oct 25, 2026
d8fbea2
Merge branch 'interaction-harness-1-touch' into interaction-harness-2…
vjeux Oct 25, 2026
5850e7a
test(interaction): a later hold never moves the first hold's times
vjeux Oct 25, 2026
c6d91e8
ci: pin the interaction routing's fail-closed edges by running them
vjeux Oct 25, 2026
15a1a76
Merge branch 'interaction-harness-1-touch' into interaction-harness-2…
vjeux Oct 25, 2026
0a9e7bf
docs(interaction): seek and sample times count from the held origin
vjeux Oct 25, 2026
2438fc7
ci: a head cut before the interaction proofs passes with a notice
vjeux Oct 25, 2026
295c0da
Merge branch 'interaction-harness-1-touch' into interaction-harness-2…
vjeux Oct 25, 2026
eeef165
ci: a head cut before the interaction proofs passes with a notice
vjeux Oct 25, 2026
a9b2acf
fix(interaction): a watch keeps the start of an animation the page ca…
vjeux Oct 25, 2026
cf0ad08
chore(interaction): the WebKit container script moves up the stack
vjeux Oct 25, 2026
8afa44a
Merge branch 'interaction-harness-1-touch' into interaction-harness-2…
vjeux Oct 25, 2026
990fa36
chore(interaction): the BottomSheet detent exemplar leaves the harnes…
vjeux Oct 25, 2026
2642e06
fix(interaction): a storyboard retakes a photograph Chromium returns …
vjeux Oct 25, 2026
ca4fee0
test(interaction): pin what the long-task log sees; the cache test wa…
vjeux Oct 25, 2026
18b3bd3
docs(interaction): the storyboard retake waits two frames, three atte…
vjeux Oct 25, 2026
a68b352
test(interaction): the self-test films a cast window
vjeux Oct 25, 2026
44278bf
Merge branch 'interaction-harness-2-curves' into uikit/f3-storyboards
vjeux Oct 25, 2026
56d5de0
chore(interaction): the WebKit container script lands with the storyb…
vjeux Oct 25, 2026
cc613ef
Merge branch 'uikit/f3-storyboards' into interaction-harness-3-frames
vjeux Oct 25, 2026
618ed4e
Merge remote-tracking branch 'refs/remotes/origin/main' into interact…
vjeux Oct 25, 2026
37050d3
ci: the interaction jobs keep to the 15-minute budget and report thei…
vjeux Oct 25, 2026
cd141ab
Merge branch 'interaction-harness-1-touch' into interaction-harness-2…
vjeux Oct 25, 2026
9864ff8
Merge branch 'interaction-harness-2-curves' into uikit/f3-storyboards
vjeux Oct 25, 2026
fd1e7e1
Merge branch 'uikit/f3-storyboards' into interaction-harness-3-frames
vjeux Oct 25, 2026
71827fe
fix(interaction): the animation recorder stands down while a trace runs
vjeux Oct 25, 2026
ceaa552
fix(interaction): a trace still records CSS animations that start and…
vjeux Oct 25, 2026
b6cb3d8
Merge main (#8043 landed) into the curve sampling
cixzhang Oct 25, 2026
b9c5d7b
Merge branch 'uikit/f3-storyboards' into interaction-harness-3-frames
vjeux Oct 25, 2026
ee2e55e
Merge branch 'interaction-harness-3-frames' into uikit/f3-recorder-st…
vjeux Oct 25, 2026
7ee8fea
Merge branch 'interaction-harness-2-curves' into uikit/f3-storyboards
vjeux Oct 25, 2026
cd9e5cf
fix(interaction): curve samples stay true for percentage translates, …
cixzhang Oct 25, 2026
804b28e
fix(interaction): compareCurve fails a point it cannot compare
cixzhang Oct 25, 2026
19ef35c
fix(interaction): the busy-main-thread verdict judges the frames the …
vjeux Oct 25, 2026
fabf814
Merge branch 'interaction-harness-3-frames' into uikit/f3-recorder-st…
vjeux Oct 25, 2026
4f6dd9c
Merge main (#8462 curve oracles and #8053 landed) into the curve samp…
cixzhang Oct 26, 2026
2912517
Merge remote-tracking branch 'refs/remotes/fork/interaction-harness-2…
vjeux Oct 26, 2026
e5a32e1
Merge branch 'uikit/f3-storyboards' into interaction-harness-3-frames
vjeux Oct 26, 2026
f11367e
Merge branch 'interaction-harness-3-frames' into uikit/f3-recorder-st…
vjeux Oct 26, 2026
432ef44
fix(interaction): curve ends under a non-linear effect easing, and ro…
cixzhang Oct 26, 2026
8082d27
Merge remote-tracking branch 'refs/remotes/fork/interaction-harness-2…
vjeux Oct 26, 2026
c4e0f0d
Merge branch 'uikit/f3-storyboards' into interaction-harness-3-frames
vjeux Oct 26, 2026
fd9d0fa
Merge branch 'interaction-harness-3-frames' into uikit/f3-recorder-st…
vjeux Oct 26, 2026
5fafb08
fix(interaction): waitForRest stands down while a trace runs, as the …
vjeux Oct 26, 2026
0cc6d8e
fix(interaction): a held end is solved through a cubic-bézier easing,…
cixzhang Oct 26, 2026
e2da8b9
fix(interaction): judge a just-started animation from when it reaches…
vjeux Oct 26, 2026
e3ec220
Merge commit 'e2da8b9eba' into uikit/f3-recorder-standdown
vjeux Oct 26, 2026
fb3423f
fix(interaction): an animation reversed by reverse() reads to its ful…
cixzhang Oct 26, 2026
e2e775a
fix(interaction): a reverse()d animation is reported from its real st…
cixzhang Oct 26, 2026
6ef5fc3
fix(interaction): a traced waitForRest waits on the real timers, whic…
vjeux Oct 26, 2026
2efaf04
fix(interaction): a held run counts only when it reaches offset 1 and…
cixzhang Oct 26, 2026
7c8ab74
fix(interaction): the busy verdict reads the compositor's own frames …
vjeux Oct 26, 2026
8c39e7d
Merge commit '7c8ab74748' into uikit/f3-recorder-standdown
vjeux Oct 26, 2026
93d2efe
fix(interaction): a traced waitForRest looks for a few frames before …
vjeux Oct 26, 2026
ad21d14
test(interaction): held offsets against the runners' own start times
vjeux Oct 26, 2026
35b0f22
fix(interaction): a reversed run's progress counts from its end; wait…
vjeux Oct 26, 2026
a261384
fix(interaction): the busy verdict counts the frames a screencast del…
vjeux Oct 26, 2026
dd0cbfe
Merge commit 'a2613849a20b17740a8b786ccdaa1ae282f12177' into uikit/f3…
vjeux Oct 26, 2026
10ba166
fix(interaction): a run going backward is dated from when it began
cixzhang Oct 26, 2026
92bc9c2
fix(interaction): a finish read before its event goes through the rat…
cixzhang Oct 26, 2026
66d1919
fix(interaction): a traced waitForRest waits for a run going backward…
vjeux Oct 26, 2026
a2ac6f9
fix(interaction): waitForRest waits out a backward run's end delay an…
cixzhang Oct 26, 2026
1e242be
fix(interaction): a rendering trace reports DevTools-run tasks apart …
vjeux Oct 26, 2026
ab1afb2
Merge commit '1e242bed3ff02263f58be1488898c799b8cd6957' into uikit/f3…
vjeux Oct 26, 2026
efdffbe
refactor(interaction): the animation-state waits move to their own pu…
cixzhang Oct 26, 2026
c833823
feat(interaction): animation-state waits for interaction proofs
cixzhang Oct 26, 2026
2bcd5b2
docs(interaction): the waits read a run reversed before it starts; a …
cixzhang Oct 26, 2026
e8b0bb6
Merge main (#8044 landed) into the animation-state waits
cixzhang Oct 26, 2026
4eac57c
Merge #8505 (e8b0bb62: main with #8044, plus the animation-state wait…
cixzhang Oct 26, 2026
772a4b5
Merge #8348 (main with #8044 and #8505's waits) into the frame evidence
cixzhang Oct 26, 2026
7d946d2
Merge #8045 (main with #8044 and #8505's waits) into the recorder sta…
cixzhang Oct 26, 2026
571f088
fix(interaction): openStory turns Storybook's highlight module off
vjeux Oct 26, 2026
4c41132
fix(interaction): a trace sets apart only the harness's own reads, ne…
vjeux Oct 26, 2026
9320644
fix(interaction): a wait keeps waiting while the action's animation i…
cixzhang Oct 26, 2026
156e4b3
test(interaction): openStory's highlight self-test runs in both engines
vjeux Oct 26, 2026
9d5c20a
fix(interaction): a traced waitForRest skips scroll- and view-timelin…
cixzhang Oct 26, 2026
b4234d7
Merge #8505 (9320644717: a wait keeps waiting while the action's anim…
vjeux Oct 26, 2026
cb907b7
fix(interaction): the busy verdict judges a sparse cast from its firs…
vjeux Oct 26, 2026
462d82c
fix(interaction): a scroll- or view-timeline animation does not hold …
cixzhang Oct 26, 2026
803e6d6
test(interaction): the long-task self-test judges the harness read, n…
vjeux Oct 26, 2026
fa8c8e2
Merge #8505 (462d82caaf: a scroll- or view-timeline animation does no…
vjeux Oct 26, 2026
1ffb20e
Merge branch 'interaction-harness-3-frames' into uikit/f3-recorder-st…
vjeux Oct 26, 2026
a9be409
fix(interaction): a scroll-driven animation at its end is not a finis…
cixzhang Oct 26, 2026
c84803b
Merge #8505 (a9be409b35: a scroll-driven animation at its end is not …
vjeux Oct 26, 2026
02ff48f
fix(interaction): a watch stamps after the newest entry, and an exit …
cixzhang Oct 26, 2026
528dd2d
fix(interaction): after an on-screen start, the busy verdict judges t…
vjeux Oct 26, 2026
e05cdd1
Merge #8505 (02ff48fafe: a watch stamps after the newest entry, and a…
vjeux Oct 26, 2026
d1b07a4
Merge #8045 (e05cdd163a, on #8505 02ff48fafe) into the recorder stand…
vjeux Oct 26, 2026
51688cd
fix(interaction): waitForAnimation and a watch's started() stand down…
vjeux Oct 26, 2026
93c611d
Merge main (#8505 landed) into the storyboards
cixzhang Oct 26, 2026
79aa498
Merge #8348 (main with #8505 landed) into the frame evidence
cixzhang Oct 26, 2026
63218c8
Merge #8045 (main with #8505 landed) into the recorder stand-down
cixzhang Oct 26, 2026
5ad1170
fix(interaction): the WebKit container runs as the invoking user unde…
cixzhang Oct 26, 2026
49460a6
docs(interaction): a traced waitForAnimation on a CSS @keyframes anim…
cixzhang Oct 26, 2026
38ea7d9
fix(interaction): rootless docker runs the WebKit container without -…
cixzhang Oct 26, 2026
7f0f5c4
docs(interaction): waitForAnimation's JSDoc names the CSS @keyframes …
vjeux Oct 26, 2026
5712c49
Merge #8348 (38ea7d9c: rootless docker, WebKit container user) into t…
cixzhang Oct 26, 2026
4045092
chore(interaction): move four instruments out of the frame evidence
cixzhang Oct 26, 2026
6762cc5
chore(interaction): move rendering traces and the long-task log out o…
cixzhang Oct 26, 2026
03058f6
chore(interaction): move the compositor presentation record out of th…
cixzhang Oct 26, 2026
bf5950f
feat(interaction): Chromium rendering traces, the compositor presenta…
cixzhang Oct 26, 2026
d12ed28
feat(interaction): cast filmstrips, rect sampling, a Storybook highli…
cixzhang Oct 26, 2026
61de06c
Merge #8549 (d12ed280: the frame evidence split into #8045, #8548 and…
cixzhang Oct 26, 2026
0906c65
feat(interaction): a rendering trace records why styles recalculated,…
vjeux Oct 26, 2026
3e3c4e7
Merge main (#8348 landed) into the frame evidence
cixzhang Oct 26, 2026
a7ffe6e
Merge #8045 (main with #8348 landed) into the rendering traces
cixzhang Oct 26, 2026
36abaa1
Merge #8548 (main with #8348 landed) into the instruments
cixzhang Oct 26, 2026
2931530
Merge #8549 (main with #8348 landed) into the recorder stand-down
cixzhang Oct 26, 2026
c43fd69
Merge #8548 (a7ffe6ecba: main with #8348 landed) into the trace inval…
vjeux Oct 26, 2026
66c651f
fix(interaction): a watch taken inside a trace right after a style ch…
cixzhang Oct 26, 2026
21ea4dc
Merge #8446 (66c651fd44: the recorder stand-down) into the trace inva…
vjeux Oct 26, 2026
5613501
docs(interaction): the README's evidence list and busy recipe match w…
cixzhang Oct 26, 2026
a149b9c
Merge #8045 (README evidence list and FR5 block) into the rendering t…
cixzhang Oct 26, 2026
852d55c
fix(interaction): readLongTasks fails closed, and the README lists ev…
cixzhang Oct 26, 2026
4099d7e
Merge #8548 (readLongTasks fails closed) into the instruments
cixzhang Oct 26, 2026
6ccd5b4
fix(interaction): castStoryboard takes no clip it would ignore
cixzhang Oct 26, 2026
40c6be3
Merge #8549 (castStoryboard's clip, readLongTasks fails closed, READM…
cixzhang Oct 26, 2026
87e516b
docs(interaction): a traced watch restyles its element; take it befor…
cixzhang Oct 26, 2026
e4f3c8d
Merge #8446 (87e516b545: readLongTasks fails closed, castStoryboard's…
vjeux Oct 26, 2026
707e7fe
docs(interaction): the module table keeps its base row; a paragraph d…
vjeux Oct 29, 2026
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
173 changes: 151 additions & 22 deletions internal/interaction-harness/README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion internal/interaction-harness/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.0.0",
"private": true,
"type": "module",
"description": "Internal: Playwright helpers for touch interaction and animation proofs (real touch input, curve sampling, storyboards). Never published.",
"description": "Internal: Playwright helpers for touch interaction and animation proofs (real touch input, frame evidence, curve sampling, storyboards). Never published.",
"main": "./src/index.ts",
"exports": {
".": "./src/index.ts",
Expand Down
26 changes: 26 additions & 0 deletions internal/interaction-harness/scripts/webkit-container.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,19 @@
* docker daemon the container runs as the invoking user (rootless podman and
* rootless docker already map it), so the `test-results/` it writes into the
* mounted checkout stay the host user's and the next host run can clear them.
*
* WebKit composites through Mesa's software GL in the image, which compiles
* each shader variant the first time a page draws it: 450–700 ms for the
* first frame of a blurred or newly animated layer, long enough for a short
* animation to end before it is ever presented. Mesa caches what it compiles,
* and the cache is kept on the host (`~/.cache/astryx-webkit-shaders/<image>`,
* or `ASTRYX_WEBKIT_SHADER_CACHE`), so a run starts with every shader an
* earlier run compiled instead of paying for them in its first tests.
*/
import {spawnSync} from 'node:child_process';
import fs from 'node:fs';
import {createRequire} from 'node:module';
import os from 'node:os';
import path from 'node:path';
import {fileURLToPath} from 'node:url';

Expand All @@ -42,6 +51,19 @@ if (engine == null) {
process.exit(1);
}
const args = process.argv.slice(2);
// Where the container sees the host's shader cache (see the header).
const containerShaderCache = '/astryx-shader-cache';
const shaderCache =
process.env.ASTRYX_WEBKIT_SHADER_CACHE ??
path.join(
os.homedir(),
'.cache',
'astryx-webkit-shaders',
image.replace(/[^\w.-]+/g, '_'),
);
fs.mkdirSync(shaderCache, {recursive: true});
// The harness self-test reads this marker inside the container.
fs.writeFileSync(path.join(shaderCache, 'ASTRYX-SHADER-CACHE'), `${image}\n`);
const env = [
'ASTRYX_STORYBOOK_DIR',
'ASTRYX_INTERACTION_EVIDENCE',
Expand Down Expand Up @@ -79,6 +101,10 @@ const command = [
'--ipc=host',
'-v',
`${root}:${root}`,
'-v',
`${shaderCache}:${containerShaderCache}`,
'-e',
`MESA_SHADER_CACHE_DIR=${containerShaderCache}`,
'-w',
root,
...env,
Expand Down
125 changes: 125 additions & 0 deletions internal/interaction-harness/src/busy.skip.fixture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.

/**
* @file busy.skip.fixture.ts
* @input One recorded busy-main-thread run in headless Chromium under
* parallel load: a compositor coast through a 566 ms block
* @output `frames`: the screencast frames the marker was tracked in, as
* [ms after the block started, y in CSS px, or null where the marker was not
* found]; `presented`: when the compositor presented each frame
* (`Display::FrameDisplayed`), ms after the block started; `block`: the
* block's span on the same clock. The screencast skipped frames at about
* +366 and +466 ms while the compositor kept presenting every 16.7 ms.
* @position Fixture for busy.test.ts
*/

export const block = {from: 0, to: 566.1};

export const frames: ReadonlyArray<readonly [number, number | null]> = [
[-1145.8, null],
[-1114, null],
[-1063.9, null],
[-1031.1, null],
[-996.6, null],
[-964.3, null],
[-930.7, null],
[-896.7, null],
[-864, null],
[-830.6, null],
[-797.8, null],
[-762.7, null],
[-731.3, null],
[-686.5, null],
[-680.8, null],
[-651, null],
[-634.1, null],
[-620.7, null],
[-615.8, null],
[-514.4, null],
[-495, null],
[-472.4, null],
[-465.3, null],
[-448.5, null],
[-430.3, null],
[-414.8, null],
[-398.3, null],
[-379.5, null],
[-364.2, null],
[-348.3, null],
[-330.6, null],
[-315, null],
[-297.6, null],
[-281.9, null],
[-265.1, null],
[-247.6, null],
[-230.8, null],
[-215.3, null],
[-198.6, null],
[-181, null],
[-165.3, null],
[-147.7, null],
[-132, null],
[-115.4, null],
[-98.5, null],
[-81.2, 504],
[-65.2, 500],
[-48.5, 496],
[-30.9, 491],
[-15.2, 487],
[1.3, 484],
[32.8, 480],
[49.8, 476],
[66.3, 473],
[82.8, 469],
[99.7, 466],
[116.1, 463],
[132.9, 460],
[149.5, 457],
[166.3, 454],
[182.9, 451],
[199.4, 448],
[216.2, 446],
[232.8, 443],
[249.4, 441],
[266.1, 438],
[282.7, 436],
[299.5, 434],
[316, 432],
[332.7, 430],
[349.5, 428],
[366.1, 426],
[433.1, 418],
[449.7, 417],
[466.2, 415],
[516.2, 411],
[532.8, 409],
[549.5, 408],
[566.2, 407],
[650.6, 401],
[666.2, 400],
[682.9, 399],
[699.6, 398],
[716.3, 397],
[816.1, 391],
[832.8, 391],
[849.5, 390],
[866.2, 389],
[882.9, 388],
[899.5, 388],
[916.1, 387],
[1033.8, 383],
[1050.1, 383],
[1066.7, 382],
[1083.3, 382],
[1099.5, 381],
[1117.3, 381],
[1134.2, 380],
[1149.5, 380],
];

export const presented: readonly number[] = [
-98.7, -81.3, -65.3, -48.7, -31.1, -15.3, 1.3, 32.5, 49.6, 66.1, 82.7, 99.6,
115.9, 132.6, 149.3, 166.1, 182.6, 199.3, 216, 232.6, 249.3, 266, 282.6,
299.2, 315.8, 332.6, 349.3, 366, 381.5, 398.3, 415.1, 432.9, 449.6, 466.1,
481.5, 498.3, 516, 532.6, 549.4, 566.1, 581.7, 598.4, 615, 631.6, 650.3, 666,
];
Loading