Skip to content

feat(test-app): add a Bluesky-depth heavy feed screen - #3884

Merged
thymikee merged 2 commits into
mainfrom
perf/heavy-feed-fixture
Oct 22, 2026
Merged

thymikee merged 2 commits into
mainfrom
perf/heavy-feed-fixture

Conversation

@thymikee

@thymikee thymikee commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds a JavaScript-only Heavy feed screen to the test app (Settings → Open heavy feed, open-heavy-feed). It reproduces the Bluesky 1.136 home feed shape: 30 nested containers, a virtualized list, and composite posts with image, link, quote, and quote-with-media embeds. Every level opts out of view flattening. The native tree is deeper than 65 levels. 6 files, no native change, so CI repacks the cached Release build.

Layer 1 of 3 for the nightly iOS perf suite (#1781 A3 un-park). The suite drives this screen.

Validation

Tested at d17b8ead56 (fixture JS equal to the measured build) on a dedicated iPhone 17 Pro simulator (iOS 27.0, Xcode 27.1) with the cached Release fixture repacked:

  • snapshot --raw: 308 nodes, max depth 64 (65 levels), truncated, served by the simulator AX bridge in ~230 ms.
  • Pinned XCTest tree backend: kAXErrorIllegalArgument, recovered by private AX after ~4.8 s, capped at depth 56 (private-ax/recovered/ax-rejected), 3/3 samples. This matches Bluesky.
  • On this screen, XCTest element queries fail, so longpress, swipe, and in-app back fail (see layer 2).
  • pnpm test-app:typecheck and oxlint pass. Gate receipt: pnpm check:affected --run --head 60cf336129 (stack head, includes this layer): passed, exactCommit: true; FAIL-OPEN full set, every local check passed; native, device, and coverage lanes are GitHub-authoritative..

CI: perf-nightly run 39679264668 (iOS 26.2, hosted M1) reproduced the same shape: raw 305 nodes at depth 64, pinned tree backend recovered by private AX after 5.2 s with ax-rejected.

🤖 Generated with Claude Code

A JavaScript-only route that reproduces a heavy React Native home feed: 30
nested containers above a virtualized list of composite posts with image,
link, quote, and quote-with-media embeds. Its native accessibility tree is
deeper than 65 levels, so XCTest tree capture fails with
kAXErrorIllegalArgument and recovers through private AX, as on Bluesky
1.136. Settings links to it with open-heavy-feed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Size Report

Metric Base Current Diff
Installed (including dependencies) 5.52 MB 5.52 MB 0 B
Package (unpacked) 5.52 MB 5.52 MB 0 B
Package (download) 1.67 MB 1.67 MB +1 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 24.2 ms 24.8 ms +0.5 ms
CLI --help 49.4 ms 49.7 ms +0.3 ms

@thymikee

Copy link
Copy Markdown
Member Author

The feed screen looks good, but one copied helper needs to go before merge, and the Apple Smoke Tests job at d17b8ea is still running.

clampInteger in HeavyFeedScreen.tsx is a character-for-character copy of the one in DeepTreeScreen.tsx, and TickerScreen.tsx:74 has a near copy too. Three parsers for fixture route params will drift apart, and the repo reuse rule treats duplicate helpers as blocking. Please keep one clampInteger in a shared test-app module (for example examples/test-app/src/route-params.ts), import it in all three screens, and delete the copies.

Not blocking, and you can take or leave it: the new button in SettingsScreen.tsx grows the Snapshot depth card by about 60pt, so every card below it moves down. The Maestro differential flows tap-retry-if-no-change.yaml and settle-after-tap.yaml tap open-inert-surface right after opening Settings, with no scroll (see #1299), so that button may now sit below the fold. That estimate comes from the styles, not from a device. It would help to confirm on an iPhone-size simulator that open-inert-surface is still hittable without scrolling, or to move the entry so it does not push the cards above it, for example as a deep link only like deep-tree. The conformance-differential CI job is not among this PR's checks.

Checks show the Apple Smoke Tests job still running, and the other checks pass, including the Linux and Android smoke jobs. I did not run the app or a simulator. The depth (more than 65), node counts and XCTest failure claims rest on your reports, and the README says about 360 nodes while you reported 305 and 308. There are no conflicts. Before merge, please share the clampInteger fix and show either that open-inert-surface still works without scrolling or that the Apple Smoke Tests job passes.

…eed card last

Review on #3884: HeavyFeedScreen, DeepTreeScreen and TickerScreen each
carried a copy of clampInteger; they now import it from route-params.ts.
The heavy feed entry moves to its own last Settings card so the cards
the Maestro differential flows tap without scrolling keep their
positions (#1299). The README node count now matches the measured
305-308 raw nodes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@thymikee

Copy link
Copy Markdown
Member Author

Addressed in dbab03f:

  • clampInteger: there is now one copy, in examples/test-app/src/route-params.ts. HeavyFeedScreen, DeepTreeScreen and TickerScreen import it, and their copies are deleted. Ticker used Number.isNaN, and the shared helper uses Number.isFinite. They behave the same, because parseInt never returns Infinity.
  • open-inert-surface: open-heavy-feed now sits in its own last Settings card. Every card above it keeps its old position, so the Maestro differential flows' unscrolled tap on open-inert-surface (scrollUntilVisible: agent-device fails to find an element real Maestro finds (layer-3 differential) #1299) sees the same layout as on main. A comment on the card records this constraint. The perf suite in feat(perf): time every iOS command against the fixture app #3885 reaches the button with scroll down --until, so the move doesn't affect it. Apple Smoke Tests also passed at d17b8ea.
  • README: it now says about 300 raw nodes, which matches the measured 305 and 308.

pnpm check:affected --run passes, and so does the test-app tsc.

@thymikee

Copy link
Copy Markdown
Member Author

The Lint failure at dbab03f comes from main: snapshot-route.test.ts is 1003 lines there (cap 1000). The fix is #3890. Once #3890 lands, this PR needs a re-run.

@thymikee

Copy link
Copy Markdown
Member Author

The earlier findings from d17b8ea are fixed at dbab03f, and I found no new code problems in this change.

The Lint, Typecheck & Package job fails on a different file: packages/platform-apple/src/snapshot-route.test.ts is over the 1000-line cap. This PR changes only examples/test-app files, so it does not touch that file. You say #3890 fixes it on main, so this failure is likely unrelated to your change. Please re-run the job once #3890 lands. No code change is needed.

I read the code but did not run the app or a simulator. The depth (more than 65 levels), the node counts, the XCTest kAXErrorIllegalArgument failure and the private-AX recovery rest on your report. I did not confirm on a device that open-inert-surface is still hittable without scrolling. The layout argument comes from the source. I also did not confirm that the Maestro differential flows pass, and the conformance-differential job is not among this PR's checks. I did not check whether another flow depends on Reset lab state or Diagnostics being the last Settings card, but I found no reference to open-heavy-feed outside the test app. Your claims that Apple Smoke Tests passed at d17b8ea and that pnpm check:affected passes are also unverified on my side.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Oct 22, 2026
@thymikee
thymikee merged commit 5f6dfb3 into main Oct 22, 2026
15 of 16 checks passed
@thymikee
thymikee deleted the perf/heavy-feed-fixture branch October 22, 2026 08:07
@github-actions

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-10-22 08:08 UTC

thymikee added a commit that referenced this pull request Oct 22, 2026
* origin/main:
  feat(test-app): add a Bluesky-depth heavy feed screen (#3884)
  fix(android): read a child that vanished mid-read as gone (#3901)
  feat(ios): route iPad Simulator snapshots through the host AX bridge (#3895)
thymikee added a commit that referenced this pull request Oct 22, 2026
* origin/main:
  feat(test-app): add a Bluesky-depth heavy feed screen (#3884)
  fix(android): read a child that vanished mid-read as gone (#3901)
  feat(ios): route iPad Simulator snapshots through the host AX bridge (#3895)
thymikee added a commit that referenced this pull request Oct 22, 2026
* origin/main:
  feat(test-app): add a Bluesky-depth heavy feed screen (#3884)
  fix(android): read a child that vanished mid-read as gone (#3901)
  feat(ios): route iPad Simulator snapshots through the host AX bridge (#3895)
thymikee added a commit that referenced this pull request Oct 22, 2026
* origin/main:
  feat(test-app): add a Bluesky-depth heavy feed screen (#3884)
  fix(android): read a child that vanished mid-read as gone (#3901)
  feat(ios): route iPad Simulator snapshots through the host AX bridge (#3895)
  Prepare shared resource ownership and selection for #3325 (#3887)
  refactor(kernel): track held execution locks in keyed-lock (#3879)
  perf(ios): ask a ready runner about surface hosts before spawning probes (#3877)
  fix(ios): keep the bridge while a surface host only lingers (#3873)
  perf(ios): synthesize taps on resolved in-app back controls (#3880)
  fix(macos): open a running app by its own path instead of its bundle id (#3889)
  fix(macos): accept mixed-case bundle ids in open (#3867)
  fix(macos-helper): scroll SwiftUI forms whose rows are scroll-area children (#3888)
thymikee added a commit that referenced this pull request Oct 22, 2026
#3885 was rebased onto main after #3884 merged. This merge takes its new head
with the Android layer's two commits replayed on it. Suite conflicts resolve to
the renamed suite.ts and suite-harness.ts: the pinned-tree capture moves to
home-reads (iOS only) and the Android one-shot step keeps its transport check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
thymikee added a commit that referenced this pull request Oct 22, 2026
* origin/main:
  feat(test-app): add a Bluesky-depth heavy feed screen (#3884)
  fix(android): read a child that vanished mid-read as gone (#3901)
  feat(ios): route iPad Simulator snapshots through the host AX bridge (#3895)
thymikee added a commit that referenced this pull request Oct 22, 2026
* origin/main:
  perf(ios): confirm fill focus from the tapped input before the keyboard (#3906)
  feat(perf): time every iOS command against the fixture app (#3885)
  fix(ios): stop the XCTest-channel penalty from re-arming itself (#3896)
  test(android): pin that a child vanishing mid-read reads as gone (#3905)
  ci: skip device smoke lanes when a PR changes no lane input (#3904)
  fix(ios): verify deep-tree back on the sole screen (#3894)
  fix(ios): synthesize long presses and the gesture viewport on deep trees (#3893)
  perf(ios): read each resolved text input through one snapshot (#3882)
  fix(gate): take the host validation lock for heavy gates (#3900)
  fix(logs): keep an early iOS simulator logs stop from hanging the session (#3892)
  fix(apple): clean the runner derived path the runner uses (#3897)
  test(provider-scenarios): open deadline scenarios without the test IME (#3903)
  test(host-kit): stub os.homedir for the exec-trace late-close test (#3898)
  feat(test-app): add a Bluesky-depth heavy feed screen (#3884)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant