Skip to content

fix(cache): a row of a windowed list is not keyed by its list's first rendered row; mobile benchmark re-recorded, Android strict - #998

Merged
okwasniewski merged 2 commits into
mainfrom
oskar/cache-orphans-mobile-strict
Oct 9, 2026
Merged

okwasniewski merged 2 commits into
mainfrom
oskar/cache-orphans-mobile-strict

Conversation

@okwasniewski

@okwasniewski okwasniewski commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

What and why

  • The 39 mobile recordings dated from Sep 23-24, before the Oct 3 replay policy bump (fix(cache): stop replays self-finalizing when the effect did not happen #732) and the key change in fix(cache): drop the engine version from the replay cache key #929. Every mobile agentic CI run missed all of them (20 missed / 21 missed on the last three merge queue runs) and called the model for every step.
  • Both platforms are re-recorded on a Mac: iPhone 17 Pro on the pinned iOS 26.5 runtime, Pixel 7 API 36 headless, against release builds made the way .github/actions/expo-app makes them. 20 Android entries, 21 iOS.
  • The Android agentic job runs with --strict-cache like the web one: a recording that no longer replays fails its step as REPLAY_STALE instead of spending model calls on every run.
  • iOS stays lenient. Three iOS recordings hand off on every replay, each an engine gap the README now names: Debounced Search (replay looks before the debounced results render, and relocation settles on the search field's wrapper, which reads "Benchmark Target" too), Choice Controls (the notes field's keyboard covers the Mushrooms checkbox and iOS drops it from the tree), Stripe PaymentSheet (the card form's fields are not in the tree after the Card tab is tapped). The other 18 replay.
  • The web benchmark cache kept 30 entries under the pre-fix(cache): drop the engine version from the replay cache key #929 key next to their re-keyed twins; the orphans go. Every one of the 30 has a live twin recorded for the same step.
  • One cache fix, found by the first strict Android run on this branch. The container key of a row inside an unnamed list was the list's first leaf text (containerKey, packages/e2e/src/agent/actions.ts). On Android a windowed list renders whichever rows are near the viewport, so that text is a scroll position: the Huge Virtualized List tap was recorded as tap group "Row 0512" in "Row 0500" and handed off whenever the window started at 0501, once locally and once in CI. A container whose first text sits in a twin of the row the node came up through is a list and keys nothing by that text; its own label still keys it. The four Android entries that carried such a key (Infinite Scroll List, Huge Virtualized List, Sticky Chrome Target, Product Catalog) are re-recorded. iOS entries carry no placement. Web entries are unaffected: strict web replays the same 26.
// packages/e2e/src/agent/actions.ts
const key = (namedAfterTwinOf(container, nodes.get(came)) ? undefined : firstLeafText(container)) ?? ownLabel(container);
flowchart LR
  A[mobile agentic job] --> B{platform}
  B -- android --> C[e2e run --strict-cache]
  C --> D{entry replays?}
  D -- yes --> E[replayed, no model call]
  D -- no --> F[REPLAY_STALE, job fails]
  B -- ios --> G[e2e run]
  G --> H{entry replays?}
  H -- yes --> E
  H -- no --> I[hand off to the model]
Loading

Verified

Ran it locally: yes

  • mobile-benchmark, Android, e2e run --target android-emulator --config e2e.agent.config.ts --strict-cache on Pixel_7_API_36 with the committed entries: 20 passed, 15 replayed · 2 handed off · 3 missed. The hand-offs and misses are swipes and run-time values, which the grammar does not record.
  • mobile-benchmark, iOS, same command without --strict-cache on two iPhone 17 Pro (26.5) simulators: 22 passed, 18 replayed; the three named above hand off. With --strict-cache those three fail as REPLAY_STALE on every run, which is why iOS is not strict yet.
  • web-benchmark, e2e run --config e2e.agent.config.ts --strict-cache with the pruned cache: 33 passed, 26 replayed · 2 handed off · 4 missed, the same summary main's web agent job has printed since Oct 5.
suite main this branch
android agent 20 missed 15 replayed · 2 handed off · 3 missed (strict)
ios agent 21 missed 18 replayed · 1 handed off · 3 handed off on known gaps
web agent 26 replayed · 2 handed off · 4 missed 26 replayed · 2 handed off · 4 missed

CI on this branch

  • web agent (strict): 33 passed, 26 replayed, same as main.
  • android agent (strict): 19 passed, 1 flaky, 15 replayed, Huge Virtualized List replayed. The flaky test was Login Form: a recorded action failed on the first attempt (REPLAY_STALE, action-failed, typing on the loaded emulator), and the --last-failed pass replayed it under strict and passed. An earlier run flaked on Gestures the same way: the replayed long-press completed, then the live agent's swipes were not accepted.
  • ios agent (lenient): 21 passed, 10 replayed. Besides the three gaps above, three entries hand off on the CI simulator only, now named in the README: Login Form (the CI simulator reads the route as the screen title Login Form, a Mac reads the back button's Benchmark Examples), Photo Picker (the recorded tap names the photo by its seed time), Permission Prompt (end state Microphone enabled does not show after replay). All six are engine or cache follow-ups; none is a stale recording.

The first strict Android run on this branch failed on Huge Virtualized List both passes; that was the placement key above, not scroll-until. With the fix, Android strict replays locally: 20 passed, 15 replayed · 2 handed off · 3 missed.

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

🟢 e2e web: 91 passed

All 91 tests in 41 files
Test Time
🟢 tests/aria-hidden-flow.e2e.ts · 2 passed 532ms
🟢 aria hidden flow › picks the Pro plan by its visible text and confirms it 362ms
🟢 aria hidden flow › another plan shows the error and keeps the picker open 170ms
🟢 tests/async-states.e2e.ts · 2 passed 7.1s
🟢 async states › reads the code off the transient toast and verifies it once the button enables 2.2s
🟢 async states › a wrong code is rejected after the toast has gone 4.9s
🟢 tests/canvas-only.e2e.ts · 2 passed 292ms
🟢 canvas only › taps square, circle, then diamond at their pixel coordinates 157ms
🟢 canvas only › a shape out of order paints the error and resets progress 135ms
🟢 tests/canvas-whiteboard.e2e.ts · 2 passed 450ms
🟢 canvas whiteboard › drags both shapes into their slots and saves 261ms
🟢 canvas whiteboard › bounces a shape off the wrong slot and refuses to save early 189ms
🟢 tests/cart-totals.e2e.ts · 2 passed 403ms
🟢 cart totals › increasing a quantity updates the line total but the order summary stays stale (planted bug) 219ms
🟢 cart totals › a quantity never drops below one 184ms
🟢 tests/checkout-review.e2e.ts · 1 passed 178ms
🟢 shows a raw greeting token and an undefined delivery date (planted bug), yet places the order 178ms
🟢 tests/context-menu-trap.e2e.ts · 2 passed 577ms
🟢 context menu trap › right-click opens nothing; the row menu renames the file 300ms
🟢 context menu trap › the decoy menu items refuse and keep the file 277ms
🟢 tests/control-inventory.e2e.ts · 8 passed 3.8s
🟢 control inventory › check sets the checkbox and the radio without flipping a set one 322ms
🟢 control inventory › check picks a radio the pick replaces with its summary 189ms
🟢 control inventory › a long press and a double click are told apart from a tap 1.0s
🟢 control inventory › the file menu opens on right-click only and Rename renames the file 286ms
🟢 control inventory › setInputFiles attaches files named from the project root 163ms
🟢 control inventory › the details view is left through the browser history 223ms
🟢 control inventory › scrollIntoView brings the footnote into view 198ms
🟢 control inventory › every exercise done shows the success message 1.4s
🟢 tests/css-content-ui.e2e.ts · 2 passed 366ms
🟢 css content ui › the tile labelled Ship it advances and confirming ships 174ms
🟢 css content ui › a wrong tile shows the CSS-rendered error and keeps the picker 192ms
🟢 tests/date-picker.e2e.ts · 2 passed 762ms
🟢 date picker › navigates three months ahead and books the required date 443ms
🟢 date picker › confirming without the exact date shows the error 319ms
🟢 tests/debounced-search.e2e.ts · 2 passed 2.9s
🟢 debounced search › a decoy one character off is refused 1.5s
🟢 debounced search › picking the exact item adds it to the cart 1.5s
🟢 tests/deferred-dialog.e2e.ts · 1 passed 1.1s
🟢 one submit opens one confirm, even when double-clicked 1.1s
🟢 tests/div-soup.e2e.ts · 2 passed 799ms
🟢 div soup › a wrong code is rejected 353ms
🟢 div soup › the right code grants access after the delete tile fixes a typo 446ms
🟢 tests/drag-and-drop.e2e.ts · 2 passed 665ms
🟢 drag and drop › an out-of-order item resets the dropzone 335ms
🟢 drag and drop › dropping Banana then Cherry passes 330ms
🟢 tests/filter-deep-link.e2e.ts · 2 passed 239ms
🟢 filter deep link › filtering writes the query to the URL 139ms
🟢 filter deep link › opening a shared link restores the filter 100ms
🟢 tests/gift-card-purchase.e2e.ts · 3 passed 642ms
🟢 gift card purchase › refuses to buy without an amount 209ms
🟢 gift card purchase › refuses a recipient without an at sign 213ms
🟢 gift card purchase › sends the gift card 220ms
🟢 tests/hover-menu.e2e.ts · 2 passed 462ms
🟢 hover menu › a decoy leaf is refused 215ms
🟢 hover menu › hovering Account, then Billing, reaches Redeem voucher 247ms
🟢 tests/iframe-form.e2e.ts · 2 passed 544ms
🟢 iframe form › a wrong code is refused by the host page 261ms
🟢 iframe form › the code read from one frame applies through the other 283ms
🟢 tests/image-only-ui.e2e.ts · 3 passed 485ms
🟢 image only ui › the icons have no names, so the bare svg locator is ambiguous 118ms
🟢 image only ui › a wrong icon shows the error image and keeps the icons 169ms
🟢 image only ui › tapping the star, then the heart, verifies the icons 198ms
🟢 tests/infinite-scroll.e2e.ts · 1 passed 4.6s
🟢 scrolls the feed until the Golden Ticket loads, then claims it 4.6s
🟢 tests/kanban-board.e2e.ts · 3 passed 792ms
🟢 kanban board › pointer drags move both cards into the goal layout 409ms
🟢 kanban board › a swipe along a path drags a card as well 162ms
🟢 kanban board › a plain tap moves nothing and the untouched board is rejected 221ms
🟢 tests/login-form.e2e.ts · 4 passed 985ms
🟢 login form › rejects a malformed email 265ms
🟢 login form › rejects a short password 215ms
🟢 login form › rejects an unknown account 234ms
🟢 login form › signs in and logs out 271ms
🟢 tests/lying-labels.e2e.ts · 4 passed 704ms
🟢 lying labels › the button whose accessible name says Pay now is the wrong one 173ms
🟢 lying labels › a text match for Pay now catches the decoy phrase too 123ms
🟢 lying labels › the field whose accessible name says Amount is the wrong one 191ms
🟢 lying labels › visible text drives the payment through 217ms
🟢 tests/native-dialogs.e2e.ts · 3 passed 559ms
🟢 native dialogs › answers the confirm, prompt, and alert chain 149ms
🟢 native dialogs › dismissing the confirm cancels the order 199ms
🟢 native dialogs › a wrong gift code is rejected 211ms
🟢 tests/newsletter-signup.e2e.ts · 1 passed 2.3s
🟢 subscribe renders no feedback and logs a TypeError (planted bug) 2.3s
🟢 tests/onboarding-wizard.e2e.ts · 5 passed 6.4s
🟢 onboarding wizard › back keeps what was typed and the brief comes back with it 372ms
🟢 onboarding wizard › the address step takes the brief through its bare-div dropdown 433ms
🟢 onboarding wizard › the profile step steers the calendar three decades back 1.6s
🟢 onboarding wizard › the preferences step flips the toggles the brief names and leaves the trap off 2.0s
🟢 onboarding wizard › the review step repeats the brief and finishes with the PIN 2.0s
🟢 tests/order-history.e2e.ts · 2 passed 1.6s
🟢 order history › overview and settings render their panels 241ms
🟢 order history › the orders tab never leaves its loading state (planted bug) 1.3s
🟢 tests/otp-auto-advance.e2e.ts · 3 passed 1.5s
🟢 otp auto-advance › focus advances with each digit and the full code verifies 531ms
🟢 otp auto-advance › backspace on an empty box clears and refocuses the previous one 192ms
🟢 otp auto-advance › a wrong code clears every box and starts over 826ms
🟢 tests/overlay-trap.e2e.ts · 1 passed 710ms
🟢 continues only after the banner and the overlay are gone 710ms
🟢 tests/playbook-cleanup.e2e.ts · 2 passed 661ms
🟢 playbook cleanup › deleting the draft removes it from an exact-name search 331ms
🟢 playbook cleanup › cancelling the dialog keeps the draft searchable 330ms
🟢 tests/price-sorting.e2e.ts · 3 passed 509ms
🟢 price sorting › opens in the featured order with sale prices struck through 139ms
🟢 price sorting › low to high sorts by the original price, not the paid one (planted bug) 182ms
🟢 price sorting › high to low is the same wrong order reversed (planted bug) 188ms
🟢 tests/product-reviews.e2e.ts · 1 passed 1.2s
🟢 the running-shoe page lists coffee-grinder reviews (planted bug) 1.2s
🟢 tests/promo-storefront.e2e.ts · 1 passed 1.4s
🟢 buys a deal once the promo chrome is out of the way 1.4s
🟢 tests/rich-text-editor.e2e.ts · 2 passed 525ms
🟢 rich text editor › bolding exactly the required word passes the check 273ms
🟢 rich text editor › bold that spills into the previous word fails the check 252ms
🟢 tests/saved-addresses.e2e.ts · 3 passed 613ms
🟢 saved addresses › adds an address and clears the form 222ms
🟢 saved addresses › ignores an add with an empty field 196ms
🟢 saved addresses › delete shows its toast but keeps the address, on retry too (planted bug) 195ms
🟢 tests/shadow-dom-form.e2e.ts · 2 passed 564ms
🟢 shadow DOM form › rejects a wrong access code 286ms
🟢 shadow DOM form › grants access with the code from the hint inside the root 278ms
🟢 tests/smoke.e2e.ts · 1 passed 344ms
🟢 home lists the scenarios and opens one 344ms
🟢 tests/stale-dom.e2e.ts · 1 passed 2.2s
🟢 taps the moving target three times across rebuilds of the list 2.2s
🟢 tests/sticky-chrome.e2e.ts · 1 passed 244ms
🟢 accepts the terms once the button clears the sticky footer 244ms
🟢 tests/virtualized-table.e2e.ts · 1 passed 1m 10s
🟢 scrolls the windowed table to the Golden Row and claims it 1m 10s
🟢 tests/wishlist.e2e.ts · 2 passed 1.6s
🟢 wishlist › saving toggles the button and the tab badge 294ms
🟢 wishlist › the wishlist tab renders the empty state despite the badge count (planted bug) 1.3s

e2e 0.18.0 · 2m 3s · web · run artifacts

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

🟢 e2e web agent: 33 passed

34 agent steps · 26 replayed from cache · 20 model calls · 76.4k tokens (91% cached) · $0.0036

All 33 tests in 5 files
Test Agent Time
🟢 tests-agent/control-inventory.e2e.ts · 7 passed 7 steps 7.7s
🟢 control inventory › check sets the checkbox and the radio 1 step 559ms
🟢 control inventory › check picks a radio the pick replaces with its summary 1 step 302ms
🟢 control inventory › a long press and a double click are chosen over a plain tap 1 step 962ms
🟢 control inventory › a right-click opens the file menu and Rename renames the file 1 step 2.5s
🟢 control inventory › upload attaches the named project files 1 step 2.5s
🟢 control inventory › back returns from the details view to the inventory 1 step 441ms
🟢 control inventory › scroll_to brings the footnote into view 1 step 390ms
🟢 tests-agent/login-form.e2e.ts · 1 passed 1 step 470ms
🟢 act signs in with the benchmark account 1 step 470ms
🟢 tests-agent/planted-bugs.e2e.ts · 3 passed 4 steps · 8 calls 12.4s
🟢 cart totals: a judgment catches the stale order summary 2 steps · 4 calls 6.2s
🟢 checkout review: a judgment catches the broken copy 1 step · 1 call 1.4s
🟢 wishlist: a judgment catches the lost saved items 1 step · 3 calls 4.8s
🟢 tests-agent/scenarios.e2e.ts · 21 passed 21 steps · 12 calls 2m 40s
🟢 act completes shadow-dom-form 1 step · 3 calls 4.6s
🟢 act completes lying-labels 1 step · 3 calls 4.5s
🟢 act completes iframe-form 1 step · 3 calls 11.5s
🟢 act completes infinite-scroll 1 step 5.5s
🟢 act completes virtualized-table 1 step 1m 42s
🟢 act completes overlay-trap 1 step 831ms
🟢 act completes sticky-chrome 1 step 810ms
🟢 act completes async-states 1 step · 3 calls 6.8s
🟢 act completes debounced-search 1 step 2.2s
🟢 act completes hover-menu 1 step 451ms
🟢 act completes drag-and-drop 1 step 412ms
🟢 act completes kanban-board 1 step 601ms
🟢 act completes context-menu-trap 1 step 2.6s
🟢 act completes stale-dom 1 step 413ms
🟢 act completes otp-auto-advance 1 step 697ms
🟢 act completes date-picker 1 step 766ms
🟢 act completes rich-text-editor 1 step 9.9s
🟢 act completes playbook-cleanup 1 step 563ms
🟢 act completes promo-storefront 1 step 2.3s
🟢 act completes gift-card-purchase 1 step 2.4s
🟢 act filters the list and the URL carries the filter 1 step 201ms
🟢 tests-agent/unique-cache.e2e.ts · 1 passed 1 step 264ms
🟢 act adds an address with a run-unique label 1 step 264ms

e2e 0.18.0 · 3m 1s · web · run artifacts

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

🟢 e2e android agent: 1 flaky, 19 passed

24 agent steps · 15 replayed from cache · 34 model calls

⚠️ 1 flaky test passed on a retry

⚠️ act completes Login Form
tests-agent/scenarios.e2e.ts:257

REPLAY_STALE at step 5 of 5: agent.act "Complete this scenario as the screen instructs: log in with the given username and password", after 14.3s

the recording of this step no longer replays (action-failed), and cache.strict hands no step to the agent; re-record it with a read-write run without --strict-cache and commit the changed entry under .e2e/cache

  • Screen: dev.e2e.benchmark

Evidence: log

All 20 tests in 1 file
Test Agent Time
⚠️ tests-agent/scenarios.e2e.ts · 1 flaky, 19 passed 24 steps · 34 calls 5m 31s
⚠️ act completes Login Form (1 failed attempt first) 1 step 9.1s
🟢 act completes Infinite Scroll List 1 step 22.4s
🟢 act completes Modal Flow 1 step 8.0s
🟢 act completes Bottom Tabs 1 step 6.5s
🟢 act completes Text Input Variations 1 step 6.1s
🟢 act completes Broken Accessibility 2 steps · 5 calls 31.4s
🟢 act completes Vision Only 2 steps · 1 call 10.8s
🟢 act completes Gestures 1 step · 5 calls 22.6s
🟢 act completes Async States 1 step · 11 calls 36.2s
🟢 act completes Debounced Search 1 step 6.6s
🟢 act completes Huge Virtualized List 1 step 1m 3s
🟢 act completes Flattened Registration Form 2 steps · 1 call 10.4s
🟢 act completes Flattened Login 2 steps · 6 calls 28.3s
🟢 act completes Sticky Chrome Target 1 step 8.4s
🟢 act completes WebView Accessibility 1 step · 5 calls 16.4s
🟢 act completes Permission Prompt 1 step 6.1s
🟢 act completes Product Catalog 1 step 9.4s
🟢 act completes Error Recovery 1 step 9.0s
🟢 act completes Choice Controls 1 step 11.0s
🟢 act completes Sequential Onboarding 1 step 10.0s

e2e 0.18.0 · 6m 9s · android-emulator · run artifacts

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

🟢 e2e ios: 52 passed, 1 skipped

All 53 tests in 7 files
Test Time
⏭️ tests/controls.e2e.ts · 23 passed, 1 skipped 3m 17s
🟢 control inventory › a label query resolves a labeled text field 10.3s
🟢 control inventory › a labeled field answers name, display value, value reads, fill, and clear 21.5s
🟢 control inventory › a placeholder query and attribute reads find the field 6.1s
🟢 control inventory › a secure field takes a fill and denies value reads 10.7s
🟢 control inventory › press sends a character and Enter through the soft keyboard 8.1s
🟢 control inventory › a field autofocuses on mount and focus() moves the focus 10.8s
🟢 control inventory › toBeFocused follows the focus 9.6s
🟢 control inventory › a switch checks, unchecks, and reports its state 10.4s
🟢 control inventory › checkbox and radio roles answer getByRole, and a checkbox toggles by tap 9.4s
🟢 control inventory › checkbox and radio roles check, uncheck, and report their state 14.7s
🟢 control inventory › a radio group reports the checked option 9.4s
🟢 control inventory › buttons report disabled, enabled, and a state that arrives later 8.0s
🟢 control inventory › a display: none element is absent rather than hidden, its visible twin attached 7.6s
🟢 control inventory › a header answers its accessible name 4.2s
🟢 control inventory › a tab row answers count, all, texts, filters, positions, and switching 6.8s
🟢 control inventory › a list answers counts, list-form text, reads, and boxes in order 7.3s
⏭️ control inventory › a row contains its texts (skipped: React Native flattens a plain View out of the accessibility tree on both platforms: XCTest and the Android helper report a View with a testID as a leaf beside its children, so filter({ has }) and a query scoped to it match nothing; only Sc…)
🟢 control inventory › a long press lands as one 8.9s
🟢 control inventory › pointer verbs land at the point asked for 10.7s
🟢 control inventory › an ambiguous locator fails at once 9.1s
🟢 control inventory › screenshot, restart, and clearState reopen the app on its home list 12.1s
🟢 refusals › verbs a device never declares are refused before the engine 3ms
🟢 refusals › keys the soft keyboard cannot send are refused by the engine 685ms
🟢 refusals › a missing locator fails as not found once its timeout passes 1.1s
🟢 tests/device-fixture.e2e.ts · 9 passed 1m 19s
🟢 device fixture › setAppearance flips the color scheme the app reads 12.0s
🟢 device fixture › setOrientation rotates the window the app measures 9.3s
🟢 device fixture › the clipboard reads back what was written 7.4s
🟢 device fixture › home leaves the app, openApp brings it back where it was 7.8s
🟢 device fixture › closeApp then openApp relaunches on the home list 8.5s
🟢 device fixture › foregroundApp after closeApp reports the closed session as APP_NOT_OPEN 5.6s
🟢 device fixture › device.back pops the scenario 6.0s
🟢 device fixture › setLocation and clearLocation change what the app reads 11.7s
🟢 device fixture › enrollBiometrics and setBiometrics answer a biometric prompt 10.7s
🟢 tests/device.e2e.ts · 2 passed 55.1s
🟢 sequential onboarding echoes the exact values 42.5s
🟢 onboarding rejects a malformed email before advancing 12.6s
🟢 tests/flows-lists.e2e.ts · 7 passed 3m 33s
🟢 infinite scroll reaches the target item 27.2s
🟢 product catalog adds exactly two of the right variant 10.4s
🟢 gestures: long-press, then swipe left 9.8s
🟢 sticky chrome: accept below the fold, then continue 11.9s
🟢 async states: load, pull to refresh, claim through the toast 13.4s
🟢 huge virtualized list reaches row 512 2m 7s
🟢 web view coupon form applies the code shown on the page 13.0s
🟢 tests/flows.e2e.ts · 7 passed 1m 18s
🟢 text inputs unlock the submit button 15.9s
🟢 filled text inputs report their values 11.5s
🟢 modal flow confirms through the native alert 10.7s
🟢 bottom tabs act inside the last tab 8.0s
🟢 error recovery retries, then confirms the delete 10.1s
🟢 choice controls place the exact order 9.6s
🟢 debounced search selects the target once results arrive 12.3s
🟢 tests/login-form.e2e.ts · 3 passed 48.1s
🟢 login form › rejects a malformed email 12.9s
🟢 login form › rejects an unknown account 12.5s
🟢 login form › signs in and logs out 22.7s
🟢 tests/smoke.e2e.ts · 1 passed 10.7s
🟢 home lists the scenarios and opens one 10.7s

e2e 0.18.0 · 5m 48s · ios-simulator · run artifacts

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

🟢 e2e android: 54 passed, 1 skipped

All 55 tests in 7 files
Test Time
⏭️ tests/controls.e2e.ts · 24 passed, 1 skipped 3m 1s
🟢 control inventory › a label query resolves a labeled text field 24.7s
🟢 control inventory › a labeled field answers name, display value, value reads, fill, and clear 12.5s
🟢 control inventory › a placeholder query and attribute reads find the field 5.5s
🟢 control inventory › a secure field takes a fill and denies value reads 8.6s
🟢 control inventory › press sends a character and Enter through the soft keyboard 8.5s
🟢 control inventory › a field autofocuses on mount and focus() moves the focus 11.0s
🟢 control inventory › toBeFocused follows the focus 10.6s
🟢 control inventory › a switch checks, unchecks, and reports its state 9.8s
🟢 control inventory › checkbox and radio roles answer getByRole, and a checkbox toggles by tap 6.8s
🟢 control inventory › checkbox and radio roles check, uncheck, and report their state 11.8s
🟢 control inventory › a tab role answers getByRole 3.4s
🟢 control inventory › a radio group reports the checked option 8.6s
🟢 control inventory › buttons report disabled, enabled, and a state that arrives later 7.7s
🟢 control inventory › a display: none element is absent rather than hidden, its visible twin attached 6.6s
🟢 control inventory › a header answers its accessible name 3.3s
🟢 control inventory › a tab row answers count, all, texts, filters, positions, and switching 5.5s
🟢 control inventory › a list answers counts, list-form text, reads, and boxes in order 5.5s
⏭️ control inventory › a row contains its texts (skipped: React Native flattens a plain View out of the accessibility tree on both platforms: XCTest and the Android helper report a View with a testID as a leaf beside its children, so filter({ has }) and a query scoped to it match nothing; only Sc…)
🟢 control inventory › a long press lands as one 6.9s
🟢 control inventory › a double tap lands inside the 300 ms window 7.7s
🟢 control inventory › an ambiguous locator fails at once 5.1s
🟢 control inventory › screenshot, restart, and clearState reopen the app on its home list 9.9s
🟢 refusals › verbs a device never declares are refused before the engine 2ms
🟢 refusals › keys the soft keyboard cannot send are refused by the engine 108ms
🟢 refusals › a missing locator fails as not found once its timeout passes 1.4s
🟢 tests/device-fixture.e2e.ts · 8 passed 1m 0s
🟢 device fixture › setOrientation rotates the window the app measures 4.7s
🟢 device fixture › home leaves the app, openApp brings it back where it was 5.9s
🟢 device fixture › foregroundApp sees the home screen after home() 4.0s
🟢 device fixture › closeApp then openApp relaunches on the home list 6.2s
🟢 device fixture › foregroundApp after closeApp reports the closed session as APP_NOT_OPEN 3.9s
🟢 device fixture › device.back pops the scenario 4.8s
🟢 device fixture › setNetwork and setAirplaneMode change what the app sees 12.3s
🟢 device fixture › setLocation and clearLocation change what the app reads 18.7s
🟢 tests/device.e2e.ts · 4 passed 37.1s
🟢 permission prompt › allowing the system dialog enables the microphone 6.9s
🟢 permission prompt › a denied prompt recovers once the permission is granted outside 12.9s
🟢 sequential onboarding echoes the exact values 10.3s
🟢 onboarding rejects a malformed email before advancing 7.0s
🟢 tests/flows-lists.e2e.ts · 7 passed 2m 10s
🟢 infinite scroll reaches the target item 18.4s
🟢 product catalog adds exactly two of the right variant 9.5s
🟢 gestures: long-press, then swipe left 7.9s
🟢 gestures: double-tap completes the flow 9.2s
🟢 sticky chrome: accept below the fold, then continue 10.8s
🟢 async states: load, pull to refresh, claim through the toast 11.5s
🟢 huge virtualized list reaches row 512 1m 3s
🟢 tests/flows.e2e.ts · 7 passed 50.9s
🟢 text inputs unlock the submit button 6.5s
🟢 filled text inputs report their values 5.8s
🟢 modal flow confirms through the native alert 7.5s
🟢 bottom tabs act inside the last tab 6.0s
🟢 error recovery retries, then confirms the delete 8.1s
🟢 choice controls place the exact order 8.5s
🟢 debounced search selects the target once results arrive 8.6s
🟢 tests/login-form.e2e.ts · 3 passed 29.6s
🟢 login form › rejects a malformed email 8.7s
🟢 login form › rejects an unknown account 8.3s
🟢 login form › signs in and logs out 12.5s
🟢 tests/smoke.e2e.ts · 1 passed 5.4s
🟢 home lists the scenarios and opens one 5.4s

e2e 0.18.0 · 8m 16s · android-emulator · run artifacts

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

🟢 e2e ios agent: 2 flaky, 19 passed, 1 skipped

25 agent steps · 10 replayed from cache · 73 model calls · 700.4k tokens (77% cached) · $0.0576

⚠️ 2 flaky tests passed on a retry

⚠️ act completes Login Form
tests-agent/scenarios.e2e.ts:266

ASSERTION_FAILED at step 6 of 6: expect.toHaveText getByTestId("success-message"), after 5.0s

  • Expected: text "Logged in successfully"
  • Observed: no node (0 matches)
  • Screen: dev.e2e.benchmark / Benchmark Examples

Evidence: log

⚠️ act completes Flattened Login
tests-agent/scenarios.e2e.ts:257

ASSERTION_FAILED at step 4 of 4: agent.act "Complete this scenario as the screen instructs: log in with the email and password the screen shows as a hint. The screen lists nothing useful; take a screenshot and work from it.", after 2m 36s and 22 model calls

agent.act failed: Entered the hinted email and password and submitted the login form, but the screen shows “Invalid credentials.” The form remains on the login screen.

  • Turn 19: tap_at({"x":160,"y":355}) → [tap_at] Tapped the point (182, 404); no listed control is there (under it: #n9954 other "Use tester@tester.army / <secret:benchmark.password>, Email, Password…
  • Turn 20: tap_at({"x":80,"y":337}) → [tap_at] Tapped the point (91, 384); no listed control is there (under it: #n9982 other "Use tester@tester.army / <secret:benchmark.password>, Email, Password,…
  • Turn 21: tap_at({"x":160,"y":322}) → [tap_at] Tapped the point (182, 367); no listed control is there (under it: #n10010 other "Use tester@tester.army / <secret:benchmark.password>, Email, Passwor…
  • Screen: dev.e2e.benchmark / Benchmark Examples

Evidence: screenshot, log

All 22 tests in 1 file
Test Agent Time
⚠️ tests-agent/scenarios.e2e.ts · 2 flaky, 19 passed, 1 skipped 25 steps · 73 calls 11m 26s
⚠️ act completes Login Form (1 failed attempt first) 1 step · 9 calls 59.0s
🟢 act completes Infinite Scroll List 1 step 48.0s
🟢 act completes Modal Flow 1 step 13.1s
🟢 act completes Bottom Tabs 1 step 11.2s
🟢 act completes Text Input Variations 1 step 20.3s
🟢 act completes Broken Accessibility 2 steps · 6 calls 37.0s
🟢 act completes Vision Only 2 steps · 6 calls 37.1s
🟢 act completes Gestures 1 step · 10 calls 59.0s
🟢 act completes Async States 1 step · 9 calls 44.2s
🟢 act completes Debounced Search 1 step · 3 calls 24.0s
🟢 act completes Flattened Registration Form 2 steps · 1 call 39.7s
⚠️ act completes Flattened Login (1 failed attempt first) 2 steps · 11 calls 1m 6s
🟢 act completes Sticky Chrome Target 1 step 20.3s
🟢 act completes WebView Accessibility 1 step 16.6s
🟢 act completes Permission Prompt 1 step · 2 calls 30.7s
🟢 act completes Photo Picker 1 step · 2 calls 30.3s
🟢 act completes Product Catalog 1 step 12.8s
🟢 act completes Error Recovery 1 step 12.0s
🟢 act completes Choice Controls 1 step · 5 calls 46.7s
🟢 act completes Stripe PaymentSheet 1 step · 9 calls 44.0s
🟢 act completes Apple Pay 1 step 14.0s
⏭️ act completes Apple Pay Billing Address (skipped: the CI simulator's Apple Pay sheet skips the billing-address step, so the scenario cannot be completed there)

e2e 0.18.0 · 15m 1s · ios-simulator · run artifacts

… drop orphan web entries

The 39 mobile recordings dated from Sep 23-24, before the Oct 3 replay
policy bump (#732) and the key change in #929, so every CI run missed all
of them and called the model. Both platforms are re-recorded on a Mac
(iPhone 17 Pro on iOS 26.5, Pixel 7 API 36). The Android agentic job runs
with --strict-cache like the web one; iOS stays lenient until the three
recordings named in the README replay on a simulator.

The web benchmark cache kept 30 entries under the pre-#929 key next to
their re-keyed twins; the orphans go.
@okwasniewski
okwasniewski force-pushed the oskar/cache-orphans-mobile-strict branch from 9ae76bc to e0ef197 Compare October 9, 2026 07:56
… rendered row

The container key of a row inside an unnamed list was the list's first
leaf text, which on Android is whichever row the window rendered first:
the Huge Virtualized List tap replayed as 'Row 0512 in Row 0500' and
handed off whenever the window started at 0501, once locally and once in
CI. A container whose first text sits in a twin of the row the node came
up through is a list, and keys nothing by that text; its own label still
keys it. The four Android entries that carried such a key are re-recorded.
@okwasniewski okwasniewski changed the title ci(mobile): re-record the mobile benchmark, strict replay on Android, drop orphan web entries fix(cache): a row of a windowed list is not keyed by its list's first rendered row; mobile benchmark re-recorded, Android strict Oct 9, 2026
@okwasniewski
okwasniewski merged commit 841ea3f into main Oct 9, 2026
29 checks passed
@okwasniewski
okwasniewski deleted the oskar/cache-orphans-mobile-strict branch October 9, 2026 12:05
@github-actions github-actions Bot mentioned this pull request Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant