[E2E] Prove ready preload cache hits on both native samples - #627
Open
kyle-schellen wants to merge 1 commit into
Open
[E2E] Prove ready preload cache hits on both native samples#627kyle-schellen wants to merge 1 commit into
kyle-schellen wants to merge 1 commit into
Conversation
Contributor
Author
This stack of pull requests is managed by Graphite. Learn more about stacking. |
11 tasks
kyle-schellen
force-pushed
the
ks-e2e-preload-cache-hit-signal
branch
from
August 11, 2026 15:16
9055f4f to
bd7199e
Compare
kyle-schellen
force-pushed
the
ks-e2e-preload-cache-hit-signal
branch
2 times, most recently
from
August 11, 2026 19:11
7a4eef0 to
c408a61
Compare
kyle-schellen
force-pushed
the
ks-e2e-preload-sample-markers
branch
from
August 11, 2026 19:11
558cb61 to
76447c5
Compare
kyle-schellen
force-pushed
the
ks-e2e-preload-cache-hit-signal
branch
2 times, most recently
from
August 11, 2026 21:48
e26b2d8 to
67a0382
Compare
kyle-schellen
marked this pull request as ready for review
August 11, 2026 22:39
Install this buildOpen Tophat, select your target device, then click Install. Links open on the Mac running Tophat.
Checkout Kit E2E results
|
kyle-schellen
force-pushed
the
ks-e2e-preload-cache-hit-signal
branch
from
August 11, 2026 22:57
67a0382 to
4a1fa10
Compare
Contributor
kyle-schellen
marked this pull request as draft
August 12, 2026 12:31
kyle-schellen
force-pushed
the
ks-e2e-preload-cache-hit-signal
branch
from
August 12, 2026 13:45
4a1fa10 to
acd0a6a
Compare
kyle-schellen
force-pushed
the
ks-e2e-preload-sample-markers
branch
from
August 12, 2026 17:58
76447c5 to
770e7de
Compare
kyle-schellen
force-pushed
the
ks-e2e-preload-cache-hit-signal
branch
from
August 12, 2026 17:58
acd0a6a to
1842281
Compare
11 tasks
kyle-schellen
force-pushed
the
ks-e2e-preload-sample-markers
branch
from
August 14, 2026 20:36
770e7de to
56cc7f5
Compare
kyle-schellen
force-pushed
the
ks-e2e-preload-cache-hit-signal
branch
3 times, most recently
from
August 17, 2026 23:30
b8e8758 to
7abc816
Compare
kyle-schellen
force-pushed
the
ks-e2e-preload-sample-markers
branch
from
August 17, 2026 23:30
56cc7f5 to
49478c1
Compare
kyle-schellen
force-pushed
the
ks-e2e-preload-sample-markers
branch
from
August 18, 2026 13:30
49478c1 to
715c1f5
Compare
kyle-schellen
force-pushed
the
ks-e2e-preload-cache-hit-signal
branch
from
August 18, 2026 13:30
7abc816 to
d973bac
Compare
kyle-schellen
force-pushed
the
ks-e2e-preload-cache-hit-signal
branch
4 times, most recently
from
August 19, 2026 22:29
a747354 to
fbeab52
Compare
kyle-schellen
marked this pull request as ready for review
August 19, 2026 23:09
Package Size
Android file breakdown
Measured from the PR base SHA and PR head SHA. The file breakdown shows uncompressed sizes within each package artifact, so individual files do not sum to the compressed artifact total. This comment reports package artifact sizes only; it is not a final app binary-size report. |
kyle-schellen
force-pushed
the
ks-e2e-preload-cache-hit-signal
branch
from
August 19, 2026 23:26
fbeab52 to
d737760
Compare
Comment on lines
+44
to
+67
| class PreloadCacheHitLog( | ||
| private val openLines: () -> LogStream = ::followOwnLogcat, | ||
| private val isPreloadReady: () -> Boolean = { false }, | ||
| private val reportError: (Throwable) -> Unit = { | ||
| Timber.e(it, "Failed to observe the preload cache-hit diagnostic") | ||
| }, | ||
| ) { | ||
| companion object { | ||
| /** Must stay in step with PreloadCache.kt, which logs this on a cache hit. */ | ||
| const val DIAGNOSTIC = "Returning cached preloaded WebView." | ||
|
|
||
| /** Starts at the newest entry so earlier runs cannot create a false hit. */ | ||
| private fun followOwnLogcat(): LogStream { | ||
| val process = ProcessBuilder( | ||
| "logcat", "-T", "1", "--pid=${Process.myPid()}", "PreloadCache:D", "*:S" | ||
| ).redirectErrorStream(true).start() | ||
| val reader = BufferedReader(InputStreamReader(process.inputStream)) | ||
|
|
||
| return LogStream(reader.lineSequence()) { | ||
| process.destroy() | ||
| runCatching { reader.close() } | ||
| } | ||
| } | ||
| } |
Contributor
There was a problem hiding this comment.
Have you been able to do much testing against this to ensure it doesn't false positive?
I'm wondering if at app launch we can add a marker UUID that designates the start of logs to read from to avoid possible conflicts reading a stale cache hit marker
kyle-schellen
force-pushed
the
ks-e2e-preload-cache-hit-signal
branch
from
August 21, 2026 13:51
d737760 to
4f03d86
Compare
kyle-schellen
changed the base branch from
ks-e2e-preload-sample-markers
to
graphite-base/627
August 21, 2026 16:22
kyle-schellen
force-pushed
the
ks-e2e-preload-cache-hit-signal
branch
from
August 21, 2026 16:22
4f03d86 to
a331852
Compare
kyle-schellen
force-pushed
the
graphite-base/627
branch
from
August 21, 2026 16:22
715c1f5 to
25f45e0
Compare
kyle-schellen
changed the base branch from
graphite-base/627
to
ks-e2e-preload-sample-markers
August 21, 2026 16:22
kyle-schellen
changed the base branch from
ks-e2e-preload-sample-markers
to
graphite-base/627
August 21, 2026 19:22
kyle-schellen
added a commit
that referenced
this pull request
Aug 21, 2026
## What changed - Observe `PreloadState` in the Swift and Android sample apps using the existing public preload callbacks. - Expose the readiness result through matching invisible test IDs on both platforms: - `preload-state-not-ready` - `preload-state-ready` - Add unit tests for the shared readiness-to-ID contract. ## Why Maestro cannot read an in-memory Swift/Kotlin preload state. These markers give native E2E tests a stable condition to wait for before presentation. The identifier changes to `preload-state-ready` only when the SDK callback reports `Ready`, so the test does not infer preload completion from timing. The markers add no visible UI and no public SDK API. ## Testing - `dev swift test sample` - `dev android test demo` - `dev swift lint` - `dev android check detekt` - Consumed by the preload E2E test in #631, green on physical iOS and Android devices. ## Stack 1. **#626 — this PR:** preload state markers in the samples 2. #627 — ready cache-hit proof and sample markers 3. #631 — the E2E test, matrix wiring, and BrowserStack validation --- ### Before you merge > [!IMPORTANT] > - [x] I've added tests to support my implementation > - [x] I have read and agree with the [Contribution Guidelines](./CONTRIBUTING.md) > - [ ] I have read and agree with the [Code of Conduct](./CODE_OF_CONDUCT.md) > - [ ] I've updated the relevant platform README (`platforms/swift/README.md` and/or `platforms/android/README.md`) --- <details> <summary>Releasing a new Swift version?</summary> - [ ] I have bumped the version in `ShopifyCheckoutKit.podspec` - [ ] I have bumped the version in `platforms/swift/Sources/ShopifyCheckoutKit/ShopifyCheckoutKit.swift` - [ ] I have updated the SwiftPM/CocoaPods version snippets in `platforms/swift/README.md` (major version only) </details> <details> <summary>Releasing a new Embedded Checkout Protocol version?</summary> - [ ] I have bumped `embeddedCheckoutProtocolAndroid` in `platforms/android/gradle/libs.versions.toml` - [ ] I have updated `protocol/languages/kotlin/embedded-checkout-protocol/api/embedded-checkout-protocol.api` if the public API changed </details> <details> <summary>Releasing a new Android version?</summary> - [ ] I have bumped `checkoutKitAndroid` in `platforms/android/gradle/libs.versions.toml` - [ ] I have updated the Gradle/Maven version snippets in `platforms/android/README.md` </details> > [!TIP] > See the [Contributing documentation](./CONTRIBUTING.md) for the full release process per platform. <!-- github-gate:idempotency=checkout-kit-626-ready-marker-body-20260821 -->
kyle-schellen
force-pushed
the
ks-e2e-preload-cache-hit-signal
branch
from
August 21, 2026 19:22
a331852 to
3b0adea
Compare
kyle-schellen
force-pushed
the
graphite-base/627
branch
from
August 21, 2026 19:22
25f45e0 to
0fdad6c
Compare
kyle-schellen
force-pushed
the
ks-e2e-preload-cache-hit-signal
branch
from
August 21, 2026 19:23
3b0adea to
f5937d8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


What changed
Proves that presentation actually reused the preloaded WebView, and exposes that proof to Maestro on both native samples.
Loggerwhen presentation selects a matching cached WebView that reached.ready. The existing OSLog message is preserved for dashboard compatibility.preload-cache-hit-*identifier. Normal launches hide the diagnostic marker from the accessibility tree; [E2E] Prepare native preload ready-flow validation #631 enables preload observability only for diagnostic runs.Ready. The debug-only watcher owns and closes its reader/process with theCartViewModel.Why
preload-state-readyproves background preload completed. It does not prove presentation used that cached WebView — a fresh one looks identical on screen. This closes that gap.The
.readycondition matters: a cached entry that matches but is still loading would otherwise count as a hit.Both samples end up exposing the same identifier, so the E2E flow has no platform branch. Getting there differs only because the SDKs differ:
Logger, so it observes the message directlyinternal, so it reads its own PID-scoped Logcat. A per-watcher UUID boundary excludes buffered lines from earlier app processes before the observer accepts a cache hitEach sample matches the message text against its own copy because the SDK diagnostics are not public API. SDK emission tests and sample parser tests pin the exact literals, so accidental drift fails close to the change instead of surfacing as a 30-second E2E timeout.
Testing
dev swift test CheckoutWebViewTestsdev swift test sampledev android test demo,dev android check detektPreloadCacheHitMarkerTest: stale pre-boundary hits, old UUID sessions, current-boundary arming, Ready gating, Logcat failures, and reader shutdowndev swift lintdev android e2e --tags preloaddev swift e2e --tags preloadpreload-cache-hit-observed, withpreload-cache-hit-noneasserted beforehand so a stuck marker cannot pass.Stack
Before you merge
Important
platforms/swift/README.mdand/orplatforms/android/README.md)Releasing a new Swift version?
ShopifyCheckoutKit.podspecplatforms/swift/Sources/ShopifyCheckoutKit/ShopifyCheckoutKit.swiftplatforms/swift/README.md(major version only)Releasing a new Embedded Checkout Protocol version?
embeddedCheckoutProtocolAndroidinplatforms/android/gradle/libs.versions.tomlprotocol/languages/kotlin/embedded-checkout-protocol/api/embedded-checkout-protocol.apiif the public API changedReleasing a new Android version?
checkoutKitAndroidinplatforms/android/gradle/libs.versions.tomlplatforms/android/README.mdTip
See the Contributing documentation for the full release process per platform.