From a19238b8fe7f01d18dd338e79ce419ed5b061fb0 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 13 Jul 2026 21:43:30 +0000 Subject: [PATCH 01/12] Fix dead buy button on cached paywall re-presentation Since #431 stopped tearing down backgrounded paywalls on a non-finishing onStop, per-presentation transient state was no longer reset. A purchase launches Google Play's billing sheet (a separate activity), producing a non-finishing onStop that leaves loadingState=LoadingPurchase and presentationDidFinishPrepare=true. On the next presentation of the same cached PaywallView, the stale spinner swallows the buy tap and onViewCreated() early-returns without re-wiring the view. Reset the transient state (purchase/manual spinner -> Ready and the presentation-prepared flags) at the start of PaywallView.present(), which runs only for a genuinely new presentation. This does not revert #431: the don't-destroy-on-background behavior is untouched, resume-same-instance (onResume -> onViewCreated) is unaffected, and the in-flight purchase spinner is never cleared because present() is not called mid-purchase. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01Y6NCb2BMXSXwAN1vCMFvyc --- CHANGELOG.md | 5 ++ .../superwall/sdk/paywall/view/PaywallView.kt | 19 ++++++++ .../sdk/paywall/view/PaywallViewTest.kt | 48 +++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8880d382..cf73135b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ The changelog for `Superwall`. Also see the [releases](https://github.com/superwall/Superwall-Android/releases) on GitHub. +## Unreleased + +## Fixes +- Fix a dead buy button when re-presenting a cached paywall in the same session after a purchase. Per-presentation transient state (loading spinner and presentation-prepared flag) is now reset on each new presentation, so it no longer leaks from a previous presentation that was stopped without a finishing teardown. + ## 2.7.21 ## Enhancements diff --git a/superwall/src/main/java/com/superwall/sdk/paywall/view/PaywallView.kt b/superwall/src/main/java/com/superwall/sdk/paywall/view/PaywallView.kt index ca5c6d93b..8440f61e6 100644 --- a/superwall/src/main/java/com/superwall/sdk/paywall/view/PaywallView.kt +++ b/superwall/src/main/java/com/superwall/sdk/paywall/view/PaywallView.kt @@ -299,6 +299,7 @@ class PaywallView( paywallStatePublisher: MutableSharedFlow, completion: (Boolean) -> Unit, ) { + resetTransientPresentationState() webView.attach(this) cache?.acquireLoadingView()?.let { setupLoading(it) @@ -477,6 +478,24 @@ class PaywallView( controller.updateState(ResetPresentationPreparations) } + // A cached view can be re-presented after a previous presentation was stopped without a + // finishing teardown - the purchase billing sheet (or backgrounding) triggers a non-finishing + // onStop, which since #431 intentionally no longer tears the view down. That leaks + // per-presentation transient state into the next present: a stale LoadingPurchase/ManualLoading + // spinner swallows taps, and a stale presentationDidFinishPrepare makes onViewCreated() + // early-return without re-wiring the view. Resetting it at the start of present() gives every + // new presentation a clean slate. Safe because present() only runs for a genuinely new + // presentation - never on resume-same-instance (that goes through onResume -> onViewCreated) + // nor during an in-flight purchase. + internal fun resetTransientPresentationState() { + if (loadingState is PaywallLoadingState.LoadingPurchase || + loadingState is PaywallLoadingState.ManualLoading + ) { + controller.updateState(SetLoadingState(PaywallLoadingState.Ready)) + } + resetPresentationPreparations() + } + internal fun dismiss( result: PaywallResult, closeReason: PaywallCloseReason, diff --git a/superwall/src/test/java/com/superwall/sdk/paywall/view/PaywallViewTest.kt b/superwall/src/test/java/com/superwall/sdk/paywall/view/PaywallViewTest.kt index dd4daf0f1..1486d565f 100644 --- a/superwall/src/test/java/com/superwall/sdk/paywall/view/PaywallViewTest.kt +++ b/superwall/src/test/java/com/superwall/sdk/paywall/view/PaywallViewTest.kt @@ -928,6 +928,54 @@ class PaywallViewTest { } } + @OptIn(ExperimentalCoroutinesApi::class) + @Test + fun resetTransientPresentationState_clearsStalePurchaseSpinnerAndPrepareFlag_soRepresentReWires() = + runTest { + val dispatcher = StandardTestDispatcher(testScheduler) + Dispatchers.setMain(dispatcher) + try { + Given("a cached view left with stale transient state after a non-finishing stop mid-purchase") { + val view = makePaywallView(cache = null) + // A finished presentation whose purchase spinner never got torn down (#431): + view.controller.updateState(PaywallViewState.Updates.SetPresentedAndFinished) + view.controller.updateState( + PaywallViewState.Updates.SetLoadingState(PaywallLoadingState.LoadingPurchase), + ) + assertTrue( + "Precondition: stale LoadingPurchase spinner", + view.state.loadingState is PaywallLoadingState.LoadingPurchase, + ) + assertTrue( + "Precondition: stale presentationDidFinishPrepare", + view.state.presentationDidFinishPrepare, + ) + + When("the cached view is re-presented (present() resets transient state)") { + view.resetTransientPresentationState() + advanceUntilIdle() + + Then("the spinner is cleared and onViewCreated() will re-wire instead of early-returning") { + assertTrue( + "Stale purchase spinner should be reset to Ready", + view.state.loadingState is PaywallLoadingState.Ready, + ) + assertFalse( + "presentationDidFinishPrepare must be reset so onViewCreated() re-wires", + view.state.presentationDidFinishPrepare, + ) + assertTrue( + "presentationWillPrepare must be re-armed for the new presentation", + view.state.presentationWillPrepare, + ) + } + } + } + } finally { + Dispatchers.resetMain() + } + } + @OptIn(ExperimentalCoroutinesApi::class) @Test fun destroyed_whenFinishingAfterDismiss_emitsTerminalPaywallCloseWithReason_andClearsActiveKey() = From 583fd9a810bfad226e21cf398e21fadc8d849834 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 13 Jul 2026 21:57:52 +0000 Subject: [PATCH 02/12] Update paywall preload benchmark report [skip ci] --- .benchmark/REPORT.md | 6 +- .../results/preload-benchmark-high.json | 274 +++++++++--------- .benchmark/results/preload-benchmark-low.json | 274 +++++++++--------- .benchmark/results/preload-benchmark-mid.json | 272 ++++++++--------- 4 files changed, 413 insertions(+), 413 deletions(-) diff --git a/.benchmark/REPORT.md b/.benchmark/REPORT.md index 18689b97e..adf3de644 100644 --- a/.benchmark/REPORT.md +++ b/.benchmark/REPORT.md @@ -4,9 +4,9 @@ Time from `preloadAllPaywalls()` until every paywall reaches `PaywallLoadingStat | Tier | Paywalls | Mean | Baseline | Δ | Limit | Cold mean | Warm mean | Median | StdDev | CV | Samples | Status | |------|----------|------|----------|---|-------|-----------|-----------|--------|--------|----|---------|--------| -| LOW | 10 | 6.29s | 6.34s | -0.7% | +30% | 8.05s | — | 6.29s | 3.68s | 45.7% | 10 (10×1) | 🟢 improved | -| MID | 10 | 6.19s | 8.78s | -29.5% | +15% | 7.78s | — | 6.19s | 3.26s | 41.9% | 10 (10×1) | 🟢 improved | -| HIGH | 10 | 11.14s | 6.72s | +65.9% | +20% | 10.53s | — | 11.14s | 3.60s | 34.2% | 10 (10×1) | ❌ regression | +| LOW | 10 | 4.33s | 6.34s | -31.7% | +30% | 4.40s | — | 4.33s | 497ms | 11.3% | 10 (10×1) | 🟢 improved | +| MID | 10 | 5.08s | 8.78s | -42.1% | +15% | 5.26s | — | 5.08s | 732ms | 13.9% | 10 (10×1) | 🟢 improved | +| HIGH | 10 | 10.89s | 6.72s | +62.1% | +20% | 11.86s | — | 10.89s | 5.61s | 47.3% | 10 (10×1) | ❌ regression | ### Devices diff --git a/.benchmark/results/preload-benchmark-high.json b/.benchmark/results/preload-benchmark-high.json index 0c56e0e2d..77a64ce52 100644 --- a/.benchmark/results/preload-benchmark-high.json +++ b/.benchmark/results/preload-benchmark-high.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 15509, + "allReadyMs": 20495, "cold": true, - "configureMs": 3708, + "configureMs": 3746, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 10547, - "data-v3-0ed9-2024-04-04": 11875, - "free-trial-v3-d8d7-2024-04-04": 15509, - "inimai---open-app-copy-c50c-2024-11-28": 9576, - "localized-paywall-e901-2024-04-04": 11364, - "price-tester-1b8e-2024-04-04": 12284, - "products-v3-60c5-2024-04-04": 12130, - "superwall-template-9f9f-2024-05-21": 9474, - "url-paywall-v3-3810-2024-04-04": 11109, - "video-v3-72b4-2024-04-04": 9985 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9369, + "data-v3-0ed9-2024-04-04": 11648, + "free-trial-v3-d8d7-2024-04-04": 19620, + "inimai---open-app-copy-c50c-2024-11-28": 20495, + "localized-paywall-e901-2024-04-04": 18074, + "price-tester-1b8e-2024-04-04": 13312, + "products-v3-60c5-2024-04-04": 13005, + "superwall-template-9f9f-2024-05-21": 20084, + "url-paywall-v3-3810-2024-04-04": 9877, + "video-v3-72b4-2024-04-04": 12378 }, - "preloadCompleteEventMs": 5184, + "preloadCompleteEventMs": 2771, "run": 1 }, { - "allReadyMs": 10069, + "allReadyMs": 15812, "cold": true, - "configureMs": 2039, + "configureMs": 2865, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7557, - "data-v3-0ed9-2024-04-04": 9914, - "free-trial-v3-d8d7-2024-04-04": 8327, - "inimai---open-app-copy-c50c-2024-11-28": 6251, - "localized-paywall-e901-2024-04-04": 7865, - "price-tester-1b8e-2024-04-04": 8429, - "products-v3-60c5-2024-04-04": 9304, - "superwall-template-9f9f-2024-05-21": 6662, - "url-paywall-v3-3810-2024-04-04": 9092, - "video-v3-72b4-2024-04-04": 10069 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 15507, + "data-v3-0ed9-2024-04-04": 14332, + "free-trial-v3-d8d7-2024-04-04": 15812, + "inimai---open-app-copy-c50c-2024-11-28": 11561, + "localized-paywall-e901-2024-04-04": 13227, + "price-tester-1b8e-2024-04-04": 14538, + "products-v3-60c5-2024-04-04": 11301, + "superwall-template-9f9f-2024-05-21": 10426, + "url-paywall-v3-3810-2024-04-04": 14793, + "video-v3-72b4-2024-04-04": 12971 }, - "preloadCompleteEventMs": 1441, + "preloadCompleteEventMs": 3062, "run": 2 }, { - "allReadyMs": 12216, + "allReadyMs": 20855, "cold": true, - "configureMs": 3075, + "configureMs": 3171, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 12216, - "data-v3-0ed9-2024-04-04": 10500, - "free-trial-v3-d8d7-2024-04-04": 6911, - "inimai---open-app-copy-c50c-2024-11-28": 7221, - "localized-paywall-e901-2024-04-04": 8575, - "price-tester-1b8e-2024-04-04": 6131, - "products-v3-60c5-2024-04-04": 11491, - "superwall-template-9f9f-2024-05-21": 8003, - "url-paywall-v3-3810-2024-04-04": 9304, - "video-v3-72b4-2024-04-04": 10866 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 19339, + "data-v3-0ed9-2024-04-04": 18039, + "free-trial-v3-d8d7-2024-04-04": 14315, + "inimai---open-app-copy-c50c-2024-11-28": 11170, + "localized-paywall-e901-2024-04-04": 15667, + "price-tester-1b8e-2024-04-04": 20444, + "products-v3-60c5-2024-04-04": 16608, + "superwall-template-9f9f-2024-05-21": 12676, + "url-paywall-v3-3810-2024-04-04": 20021, + "video-v3-72b4-2024-04-04": 20855 }, - "preloadCompleteEventMs": 1835, + "preloadCompleteEventMs": 2335, "run": 3 }, { - "allReadyMs": 14229, + "allReadyMs": 12217, "cold": true, - "configureMs": 1909, + "configureMs": 2856, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 10861, - "data-v3-0ed9-2024-04-04": 14229, - "free-trial-v3-d8d7-2024-04-04": 11915, - "inimai---open-app-copy-c50c-2024-11-28": 12433, - "localized-paywall-e901-2024-04-04": 11394, - "price-tester-1b8e-2024-04-04": 9931, - "products-v3-60c5-2024-04-04": 9263, - "superwall-template-9f9f-2024-05-21": 8115, - "url-paywall-v3-3810-2024-04-04": 6801, - "video-v3-72b4-2024-04-04": 10295 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 12217, + "data-v3-0ed9-2024-04-04": 11709, + "free-trial-v3-d8d7-2024-04-04": 6921, + "inimai---open-app-copy-c50c-2024-11-28": 9454, + "localized-paywall-e901-2024-04-04": 6511, + "price-tester-1b8e-2024-04-04": 8894, + "products-v3-60c5-2024-04-04": 8486, + "superwall-template-9f9f-2024-05-21": 7591, + "url-paywall-v3-3810-2024-04-04": 7845, + "video-v3-72b4-2024-04-04": 8099 }, - "preloadCompleteEventMs": 1105, + "preloadCompleteEventMs": 1762, "run": 4 }, { - "allReadyMs": 8974, + "allReadyMs": 12759, "cold": true, - "configureMs": 2418, + "configureMs": 3887, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 8414, - "data-v3-0ed9-2024-04-04": 8109, - "free-trial-v3-d8d7-2024-04-04": 6059, - "inimai---open-app-copy-c50c-2024-11-28": 8821, - "localized-paywall-e901-2024-04-04": 5696, - "price-tester-1b8e-2024-04-04": 7141, - "products-v3-60c5-2024-04-04": 7448, - "superwall-template-9f9f-2024-05-21": 6785, - "url-paywall-v3-3810-2024-04-04": 8974, - "video-v3-72b4-2024-04-04": 7702 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 10802, + "data-v3-0ed9-2024-04-04": 12759, + "free-trial-v3-d8d7-2024-04-04": 7940, + "inimai---open-app-copy-c50c-2024-11-28": 11471, + "localized-paywall-e901-2024-04-04": 7085, + "price-tester-1b8e-2024-04-04": 6983, + "products-v3-60c5-2024-04-04": 9882, + "superwall-template-9f9f-2024-05-21": 11982, + "url-paywall-v3-3810-2024-04-04": 8347, + "video-v3-72b4-2024-04-04": 8551 }, - "preloadCompleteEventMs": 1570, + "preloadCompleteEventMs": 1943, "run": 5 }, { - "allReadyMs": 13263, + "allReadyMs": 9556, "cold": true, - "configureMs": 2638, + "configureMs": 2277, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9505, - "data-v3-0ed9-2024-04-04": 8994, - "free-trial-v3-d8d7-2024-04-04": 13263, - "inimai---open-app-copy-c50c-2024-11-28": 7807, - "localized-paywall-e901-2024-04-04": 8268, - "price-tester-1b8e-2024-04-04": 11088, - "products-v3-60c5-2024-04-04": 9861, - "superwall-template-9f9f-2024-05-21": 10782, - "url-paywall-v3-3810-2024-04-04": 10065, - "video-v3-72b4-2024-04-04": 7604 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9556, + "data-v3-0ed9-2024-04-04": 7851, + "free-trial-v3-d8d7-2024-04-04": 8885, + "inimai---open-app-copy-c50c-2024-11-28": 6258, + "localized-paywall-e901-2024-04-04": 7234, + "price-tester-1b8e-2024-04-04": 6360, + "products-v3-60c5-2024-04-04": 8158, + "superwall-template-9f9f-2024-05-21": 6106, + "url-paywall-v3-3810-2024-04-04": 6513, + "video-v3-72b4-2024-04-04": 8467 }, - "preloadCompleteEventMs": 2635, + "preloadCompleteEventMs": 1558, "run": 6 }, { - "allReadyMs": 12855, + "allReadyMs": 7132, "cold": true, - "configureMs": 2565, + "configureMs": 1846, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 11426, - "data-v3-0ed9-2024-04-04": 12855, - "free-trial-v3-d8d7-2024-04-04": 10712, - "inimai---open-app-copy-c50c-2024-11-28": 8944, - "localized-paywall-e901-2024-04-04": 9926, - "price-tester-1b8e-2024-04-04": 11884, - "products-v3-60c5-2024-04-04": 9362, - "superwall-template-9f9f-2024-05-21": 8419, - "url-paywall-v3-3810-2024-04-04": 10916, - "video-v3-72b4-2024-04-04": 11527 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5146, + "data-v3-0ed9-2024-04-04": 6315, + "free-trial-v3-d8d7-2024-04-04": 5299, + "inimai---open-app-copy-c50c-2024-11-28": 5400, + "localized-paywall-e901-2024-04-04": 7132, + "price-tester-1b8e-2024-04-04": 5959, + "products-v3-60c5-2024-04-04": 4688, + "superwall-template-9f9f-2024-05-21": 5654, + "url-paywall-v3-3810-2024-04-04": 5858, + "video-v3-72b4-2024-04-04": 4840 }, - "preloadCompleteEventMs": 2529, + "preloadCompleteEventMs": 1537, "run": 7 }, { - "allReadyMs": 5826, + "allReadyMs": 6023, "cold": true, - "configureMs": 1347, + "configureMs": 1748, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5213, - "data-v3-0ed9-2024-04-04": 5826, - "free-trial-v3-d8d7-2024-04-04": 4028, - "inimai---open-app-copy-c50c-2024-11-28": 3875, - "localized-paywall-e901-2024-04-04": 4435, - "price-tester-1b8e-2024-04-04": 4959, - "products-v3-60c5-2024-04-04": 3468, - "superwall-template-9f9f-2024-05-21": 3723, - "url-paywall-v3-3810-2024-04-04": 4334, - "video-v3-72b4-2024-04-04": 4180 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5617, + "data-v3-0ed9-2024-04-04": 6023, + "free-trial-v3-d8d7-2024-04-04": 5161, + "inimai---open-app-copy-c50c-2024-11-28": 4447, + "localized-paywall-e901-2024-04-04": 4958, + "price-tester-1b8e-2024-04-04": 4856, + "products-v3-60c5-2024-04-04": 5313, + "superwall-template-9f9f-2024-05-21": 4703, + "url-paywall-v3-3810-2024-04-04": 3887, + "video-v3-72b4-2024-04-04": 4243 }, - "preloadCompleteEventMs": 965, + "preloadCompleteEventMs": 1299, "run": 8 }, { - "allReadyMs": 6134, + "allReadyMs": 6688, "cold": true, - "configureMs": 1891, + "configureMs": 1086, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6134, - "data-v3-0ed9-2024-04-04": 5626, - "free-trial-v3-d8d7-2024-04-04": 5066, - "inimai---open-app-copy-c50c-2024-11-28": 4200, - "localized-paywall-e901-2024-04-04": 5117, - "price-tester-1b8e-2024-04-04": 4353, - "products-v3-60c5-2024-04-04": 4036, - "superwall-template-9f9f-2024-05-21": 4710, - "url-paywall-v3-3810-2024-04-04": 5779, - "video-v3-72b4-2024-04-04": 5320 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6280, + "data-v3-0ed9-2024-04-04": 5519, + "free-trial-v3-d8d7-2024-04-04": 4296, + "inimai---open-app-copy-c50c-2024-11-28": 4042, + "localized-paywall-e901-2024-04-04": 6688, + "price-tester-1b8e-2024-04-04": 4144, + "products-v3-60c5-2024-04-04": 5113, + "superwall-template-9f9f-2024-05-21": 4601, + "url-paywall-v3-3810-2024-04-04": 4960, + "video-v3-72b4-2024-04-04": 4806 }, - "preloadCompleteEventMs": 1278, + "preloadCompleteEventMs": 1078, "run": 9 }, { - "allReadyMs": 6223, + "allReadyMs": 7084, "cold": true, - "configureMs": 1722, + "configureMs": 1848, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6223, - "data-v3-0ed9-2024-04-04": 5919, - "free-trial-v3-d8d7-2024-04-04": 4466, - "inimai---open-app-copy-c50c-2024-11-28": 4008, - "localized-paywall-e901-2024-04-04": 5088, - "price-tester-1b8e-2024-04-04": 5456, - "products-v3-60c5-2024-04-04": 4986, - "superwall-template-9f9f-2024-05-21": 4212, - "url-paywall-v3-3810-2024-04-04": 5240, - "video-v3-72b4-2024-04-04": 5393 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6678, + "data-v3-0ed9-2024-04-04": 7084, + "free-trial-v3-d8d7-2024-04-04": 5762, + "inimai---open-app-copy-c50c-2024-11-28": 4693, + "localized-paywall-e901-2024-04-04": 5456, + "price-tester-1b8e-2024-04-04": 6118, + "products-v3-60c5-2024-04-04": 6423, + "superwall-template-9f9f-2024-05-21": 4947, + "url-paywall-v3-3810-2024-04-04": 6016, + "video-v3-72b4-2024-04-04": 6219 }, - "preloadCompleteEventMs": 1276, + "preloadCompleteEventMs": 794, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 34.216062455209986, - "coldMeanMs": 10529.8, - "maxMs": 15509, - "meanMs": 10529.8, - "medianMs": 11142.5, - "minMs": 5826, + "coefficientOfVariationPct": 47.299406981582536, + "coldMeanMs": 11862.1, + "maxMs": 20855, + "meanMs": 11862.1, + "medianMs": 10886.5, + "minMs": 6023, "sampleCount": 10, - "stdDevMs": 3602.8829444087014, + "stdDevMs": 5610.702955562302, "warmMeanMs": null }, "tier": "HIGH" diff --git a/.benchmark/results/preload-benchmark-low.json b/.benchmark/results/preload-benchmark-low.json index 373728420..4ee2687a4 100644 --- a/.benchmark/results/preload-benchmark-low.json +++ b/.benchmark/results/preload-benchmark-low.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 16811, + "allReadyMs": 5488, "cold": true, - "configureMs": 2093, + "configureMs": 2171, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7472, - "data-v3-0ed9-2024-04-04": 9567, - "free-trial-v3-d8d7-2024-04-04": 12711, - "inimai---open-app-copy-c50c-2024-11-28": 6243, - "localized-paywall-e901-2024-04-04": 16811, - "price-tester-1b8e-2024-04-04": 6653, - "products-v3-60c5-2024-04-04": 6856, - "superwall-template-9f9f-2024-05-21": 5939, - "url-paywall-v3-3810-2024-04-04": 10456, - "video-v3-72b4-2024-04-04": 11153 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3871, + "data-v3-0ed9-2024-04-04": 3619, + "free-trial-v3-d8d7-2024-04-04": 5337, + "inimai---open-app-copy-c50c-2024-11-28": 5185, + "localized-paywall-e901-2024-04-04": 5488, + "price-tester-1b8e-2024-04-04": 3266, + "products-v3-60c5-2024-04-04": 4527, + "superwall-template-9f9f-2024-05-21": 4729, + "url-paywall-v3-3810-2024-04-04": 3418, + "video-v3-72b4-2024-04-04": 3670 }, - "preloadCompleteEventMs": 1130, + "preloadCompleteEventMs": 1035, "run": 1 }, { - "allReadyMs": 8375, + "allReadyMs": 4304, "cold": true, - "configureMs": 2501, + "configureMs": 1440, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7706, - "data-v3-0ed9-2024-04-04": 8375, - "free-trial-v3-d8d7-2024-04-04": 5979, - "inimai---open-app-copy-c50c-2024-11-28": 4495, - "localized-paywall-e901-2024-04-04": 6641, - "price-tester-1b8e-2024-04-04": 5777, - "products-v3-60c5-2024-04-04": 6336, - "superwall-template-9f9f-2024-05-21": 5161, - "url-paywall-v3-3810-2024-04-04": 5671, - "video-v3-72b4-2024-04-04": 6134 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4304, + "data-v3-0ed9-2024-04-04": 4001, + "free-trial-v3-d8d7-2024-04-04": 4152, + "inimai---open-app-copy-c50c-2024-11-28": 3345, + "localized-paywall-e901-2024-04-04": 3597, + "price-tester-1b8e-2024-04-04": 3547, + "products-v3-60c5-2024-04-04": 3496, + "superwall-template-9f9f-2024-05-21": 3294, + "url-paywall-v3-3810-2024-04-04": 4052, + "video-v3-72b4-2024-04-04": 3749 }, - "preloadCompleteEventMs": 1293, + "preloadCompleteEventMs": 999, "run": 2 }, { - "allReadyMs": 7902, + "allReadyMs": 4246, "cold": true, - "configureMs": 2208, + "configureMs": 1341, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6675, - "data-v3-0ed9-2024-04-04": 7260, - "free-trial-v3-d8d7-2024-04-04": 6371, - "inimai---open-app-copy-c50c-2024-11-28": 5291, - "localized-paywall-e901-2024-04-04": 5139, - "price-tester-1b8e-2024-04-04": 6164, - "products-v3-60c5-2024-04-04": 7902, - "superwall-template-9f9f-2024-05-21": 5962, - "url-paywall-v3-3810-2024-04-04": 4886, - "video-v3-72b4-2024-04-04": 5038 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3691, + "data-v3-0ed9-2024-04-04": 4095, + "free-trial-v3-d8d7-2024-04-04": 3133, + "inimai---open-app-copy-c50c-2024-11-28": 3943, + "localized-paywall-e901-2024-04-04": 4145, + "price-tester-1b8e-2024-04-04": 3540, + "products-v3-60c5-2024-04-04": 4246, + "superwall-template-9f9f-2024-05-21": 3234, + "url-paywall-v3-3810-2024-04-04": 3435, + "video-v3-72b4-2024-04-04": 3486 }, - "preloadCompleteEventMs": 1123, + "preloadCompleteEventMs": 982, "run": 3 }, { - "allReadyMs": 12097, + "allReadyMs": 4357, "cold": true, - "configureMs": 1819, + "configureMs": 1521, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 11119, - "data-v3-0ed9-2024-04-04": 10091, - "free-trial-v3-d8d7-2024-04-04": 8099, - "inimai---open-app-copy-c50c-2024-11-28": 7013, - "localized-paywall-e901-2024-04-04": 7585, - "price-tester-1b8e-2024-04-04": 7167, - "products-v3-60c5-2024-04-04": 11529, - "superwall-template-9f9f-2024-05-21": 6646, - "url-paywall-v3-3810-2024-04-04": 12097, - "video-v3-72b4-2024-04-04": 11687 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4206, + "data-v3-0ed9-2024-04-04": 4357, + "free-trial-v3-d8d7-2024-04-04": 3702, + "inimai---open-app-copy-c50c-2024-11-28": 3349, + "localized-paywall-e901-2024-04-04": 3752, + "price-tester-1b8e-2024-04-04": 4055, + "products-v3-60c5-2024-04-04": 3551, + "superwall-template-9f9f-2024-05-21": 3299, + "url-paywall-v3-3810-2024-04-04": 3450, + "video-v3-72b4-2024-04-04": 3601 }, - "preloadCompleteEventMs": 1427, + "preloadCompleteEventMs": 1102, "run": 4 }, { - "allReadyMs": 5757, + "allReadyMs": 4108, "cold": true, - "configureMs": 2020, + "configureMs": 1324, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5251, - "data-v3-0ed9-2024-04-04": 5555, - "free-trial-v3-d8d7-2024-04-04": 4593, - "inimai---open-app-copy-c50c-2024-11-28": 3730, - "localized-paywall-e901-2024-04-04": 4643, - "price-tester-1b8e-2024-04-04": 3578, - "products-v3-60c5-2024-04-04": 4998, - "superwall-template-9f9f-2024-05-21": 3932, - "url-paywall-v3-3810-2024-04-04": 4846, - "video-v3-72b4-2024-04-04": 5757 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3554, + "data-v3-0ed9-2024-04-04": 3705, + "free-trial-v3-d8d7-2024-04-04": 4007, + "inimai---open-app-copy-c50c-2024-11-28": 3352, + "localized-paywall-e901-2024-04-04": 4108, + "price-tester-1b8e-2024-04-04": 3403, + "products-v3-60c5-2024-04-04": 3806, + "superwall-template-9f9f-2024-05-21": 3251, + "url-paywall-v3-3810-2024-04-04": 3856, + "video-v3-72b4-2024-04-04": 3907 }, - "preloadCompleteEventMs": 968, + "preloadCompleteEventMs": 1054, "run": 5 }, { - "allReadyMs": 5544, + "allReadyMs": 4908, "cold": true, - "configureMs": 1762, + "configureMs": 765, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5089, - "data-v3-0ed9-2024-04-04": 5393, - "free-trial-v3-d8d7-2024-04-04": 4380, - "inimai---open-app-copy-c50c-2024-11-28": 3722, - "localized-paywall-e901-2024-04-04": 4482, - "price-tester-1b8e-2024-04-04": 4785, - "products-v3-60c5-2024-04-04": 4684, - "superwall-template-9f9f-2024-05-21": 3975, - "url-paywall-v3-3810-2024-04-04": 4178, - "video-v3-72b4-2024-04-04": 5544 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4202, + "data-v3-0ed9-2024-04-04": 3898, + "free-trial-v3-d8d7-2024-04-04": 3284, + "inimai---open-app-copy-c50c-2024-11-28": 3747, + "localized-paywall-e901-2024-04-04": 4908, + "price-tester-1b8e-2024-04-04": 3437, + "products-v3-60c5-2024-04-04": 3545, + "superwall-template-9f9f-2024-05-21": 3082, + "url-paywall-v3-3810-2024-04-04": 3387, + "video-v3-72b4-2024-04-04": 3336 }, - "preloadCompleteEventMs": 919, + "preloadCompleteEventMs": 876, "run": 6 }, { - "allReadyMs": 6297, + "allReadyMs": 4384, "cold": true, - "configureMs": 1583, + "configureMs": 1402, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6297, - "data-v3-0ed9-2024-04-04": 4121, - "free-trial-v3-d8d7-2024-04-04": 5132, - "inimai---open-app-copy-c50c-2024-11-28": 3614, - "localized-paywall-e901-2024-04-04": 4930, - "price-tester-1b8e-2024-04-04": 4476, - "products-v3-60c5-2024-04-04": 3817, - "superwall-template-9f9f-2024-05-21": 4728, - "url-paywall-v3-3810-2024-04-04": 4273, - "video-v3-72b4-2024-04-04": 4425 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4384, + "data-v3-0ed9-2024-04-04": 3223, + "free-trial-v3-d8d7-2024-04-04": 4233, + "inimai---open-app-copy-c50c-2024-11-28": 3324, + "localized-paywall-e901-2024-04-04": 3828, + "price-tester-1b8e-2024-04-04": 4132, + "products-v3-60c5-2024-04-04": 3878, + "superwall-template-9f9f-2024-05-21": 3425, + "url-paywall-v3-3810-2024-04-04": 4080, + "video-v3-72b4-2024-04-04": 3929 }, - "preloadCompleteEventMs": 648, + "preloadCompleteEventMs": 952, "run": 7 }, { - "allReadyMs": 6292, + "allReadyMs": 4104, "cold": true, - "configureMs": 1666, + "configureMs": 1503, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4724, - "data-v3-0ed9-2024-04-04": 6292, - "free-trial-v3-d8d7-2024-04-04": 5129, - "inimai---open-app-copy-c50c-2024-11-28": 4116, - "localized-paywall-e901-2024-04-04": 3712, - "price-tester-1b8e-2024-04-04": 3560, - "products-v3-60c5-2024-04-04": 4977, - "superwall-template-9f9f-2024-05-21": 3965, - "url-paywall-v3-3810-2024-04-04": 5281, - "video-v3-72b4-2024-04-04": 4876 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3649, + "data-v3-0ed9-2024-04-04": 2993, + "free-trial-v3-d8d7-2024-04-04": 3094, + "inimai---open-app-copy-c50c-2024-11-28": 3144, + "localized-paywall-e901-2024-04-04": 3347, + "price-tester-1b8e-2024-04-04": 3195, + "products-v3-60c5-2024-04-04": 3498, + "superwall-template-9f9f-2024-05-21": 2791, + "url-paywall-v3-3810-2024-04-04": 3448, + "video-v3-72b4-2024-04-04": 4104 }, - "preloadCompleteEventMs": 1037, + "preloadCompleteEventMs": 1005, "run": 8 }, { - "allReadyMs": 5386, + "allReadyMs": 3645, "cold": true, - "configureMs": 1714, + "configureMs": 1306, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5386, - "data-v3-0ed9-2024-04-04": 5083, - "free-trial-v3-d8d7-2024-04-04": 4222, - "inimai---open-app-copy-c50c-2024-11-28": 3918, - "localized-paywall-e901-2024-04-04": 4374, - "price-tester-1b8e-2024-04-04": 3665, - "products-v3-60c5-2024-04-04": 4019, - "superwall-template-9f9f-2024-05-21": 3463, - "url-paywall-v3-3810-2024-04-04": 3817, - "video-v3-72b4-2024-04-04": 3615 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3342, + "data-v3-0ed9-2024-04-04": 3645, + "free-trial-v3-d8d7-2024-04-04": 2686, + "inimai---open-app-copy-c50c-2024-11-28": 2535, + "localized-paywall-e901-2024-04-04": 3040, + "price-tester-1b8e-2024-04-04": 2232, + "products-v3-60c5-2024-04-04": 3140, + "superwall-template-9f9f-2024-05-21": 2434, + "url-paywall-v3-3810-2024-04-04": 2939, + "video-v3-72b4-2024-04-04": 2989 }, - "preloadCompleteEventMs": 686, + "preloadCompleteEventMs": 604, "run": 9 }, { - "allReadyMs": 6069, + "allReadyMs": 4415, "cold": true, - "configureMs": 1835, + "configureMs": 1054, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6069, - "data-v3-0ed9-2024-04-04": 5664, - "free-trial-v3-d8d7-2024-04-04": 4296, - "inimai---open-app-copy-c50c-2024-11-28": 4397, - "localized-paywall-e901-2024-04-04": 4803, - "price-tester-1b8e-2024-04-04": 4955, - "products-v3-60c5-2024-04-04": 5107, - "superwall-template-9f9f-2024-05-21": 4043, - "url-paywall-v3-3810-2024-04-04": 5361, - "video-v3-72b4-2024-04-04": 5260 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3810, + "data-v3-0ed9-2024-04-04": 4314, + "free-trial-v3-d8d7-2024-04-04": 3911, + "inimai---open-app-copy-c50c-2024-11-28": 3356, + "localized-paywall-e901-2024-04-04": 4415, + "price-tester-1b8e-2024-04-04": 3104, + "products-v3-60c5-2024-04-04": 3508, + "superwall-template-9f9f-2024-05-21": 3255, + "url-paywall-v3-3810-2024-04-04": 4012, + "video-v3-72b4-2024-04-04": 3659 }, - "preloadCompleteEventMs": 1087, + "preloadCompleteEventMs": 1074, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 45.716351453666384, - "coldMeanMs": 8053.0, - "maxMs": 16811, - "meanMs": 8053.0, - "medianMs": 6294.5, - "minMs": 5386, + "coefficientOfVariationPct": 11.297661010250698, + "coldMeanMs": 4395.9, + "maxMs": 5488, + "meanMs": 4395.9, + "medianMs": 4330.5, + "minMs": 3645, "sampleCount": 10, - "stdDevMs": 3681.5377825637543, + "stdDevMs": 496.63388034961037, "warmMeanMs": null }, "tier": "LOW" diff --git a/.benchmark/results/preload-benchmark-mid.json b/.benchmark/results/preload-benchmark-mid.json index 816feccfd..a218f6076 100644 --- a/.benchmark/results/preload-benchmark-mid.json +++ b/.benchmark/results/preload-benchmark-mid.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 13314, + "allReadyMs": 6475, "cold": true, - "configureMs": 2873, + "configureMs": 2224, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 13111, - "data-v3-0ed9-2024-04-04": 11863, - "free-trial-v3-d8d7-2024-04-04": 10640, - "inimai---open-app-copy-c50c-2024-11-28": 7453, - "localized-paywall-e901-2024-04-04": 13314, - "price-tester-1b8e-2024-04-04": 8589, - "products-v3-60c5-2024-04-04": 11098, - "superwall-template-9f9f-2024-05-21": 8064, - "url-paywall-v3-3810-2024-04-04": 9570, - "video-v3-72b4-2024-04-04": 9209 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6171, + "data-v3-0ed9-2024-04-04": 6373, + "free-trial-v3-d8d7-2024-04-04": 5968, + "inimai---open-app-copy-c50c-2024-11-28": 5209, + "localized-paywall-e901-2024-04-04": 5360, + "price-tester-1b8e-2024-04-04": 5461, + "products-v3-60c5-2024-04-04": 5512, + "superwall-template-9f9f-2024-05-21": 5107, + "url-paywall-v3-3810-2024-04-04": 5766, + "video-v3-72b4-2024-04-04": 6475 }, - "preloadCompleteEventMs": 2495, + "preloadCompleteEventMs": 1915, "run": 1 }, { - "allReadyMs": 13903, + "allReadyMs": 5547, "cold": true, - "configureMs": 2186, + "configureMs": 1472, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 12373, - "data-v3-0ed9-2024-04-04": 13903, - "free-trial-v3-d8d7-2024-04-04": 6413, - "inimai---open-app-copy-c50c-2024-11-28": 9334, - "localized-paywall-e901-2024-04-04": 12575, - "price-tester-1b8e-2024-04-04": 6721, - "products-v3-60c5-2024-04-04": 8053, - "superwall-template-9f9f-2024-05-21": 10112, - "url-paywall-v3-3810-2024-04-04": 7028, - "video-v3-72b4-2024-04-04": 11755 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5243, + "data-v3-0ed9-2024-04-04": 5547, + "free-trial-v3-d8d7-2024-04-04": 4839, + "inimai---open-app-copy-c50c-2024-11-28": 4180, + "localized-paywall-e901-2024-04-04": 4687, + "price-tester-1b8e-2024-04-04": 5041, + "products-v3-60c5-2024-04-04": 4585, + "superwall-template-9f9f-2024-05-21": 4382, + "url-paywall-v3-3810-2024-04-04": 4079, + "video-v3-72b4-2024-04-04": 4991 }, - "preloadCompleteEventMs": 1688, + "preloadCompleteEventMs": 1520, "run": 2 }, { - "allReadyMs": 9111, + "allReadyMs": 4665, "cold": true, - "configureMs": 1767, + "configureMs": 1605, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4320, - "data-v3-0ed9-2024-04-04": 7839, - "free-trial-v3-d8d7-2024-04-04": 8093, - "inimai---open-app-copy-c50c-2024-11-28": 5948, - "localized-paywall-e901-2024-04-04": 9111, - "price-tester-1b8e-2024-04-04": 8246, - "products-v3-60c5-2024-04-04": 9010, - "superwall-template-9f9f-2024-05-21": 6459, - "url-paywall-v3-3810-2024-04-04": 8552, - "video-v3-72b4-2024-04-04": 8757 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3958, + "data-v3-0ed9-2024-04-04": 4463, + "free-trial-v3-d8d7-2024-04-04": 4615, + "inimai---open-app-copy-c50c-2024-11-28": 3603, + "localized-paywall-e901-2024-04-04": 4665, + "price-tester-1b8e-2024-04-04": 3705, + "products-v3-60c5-2024-04-04": 4109, + "superwall-template-9f9f-2024-05-21": 3502, + "url-paywall-v3-3810-2024-04-04": 4261, + "video-v3-72b4-2024-04-04": 4211 }, - "preloadCompleteEventMs": 1293, + "preloadCompleteEventMs": 1009, "run": 3 }, { - "allReadyMs": 5664, + "allReadyMs": 6445, "cold": true, - "configureMs": 1787, + "configureMs": 1276, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5002, - "data-v3-0ed9-2024-04-04": 5309, - "free-trial-v3-d8d7-2024-04-04": 4087, - "inimai---open-app-copy-c50c-2024-11-28": 3526, - "localized-paywall-e901-2024-04-04": 5664, - "price-tester-1b8e-2024-04-04": 4494, - "products-v3-60c5-2024-04-04": 4646, - "superwall-template-9f9f-2024-05-21": 3780, - "url-paywall-v3-3810-2024-04-04": 4748, - "video-v3-72b4-2024-04-04": 3475 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4573, + "data-v3-0ed9-2024-04-04": 6445, + "free-trial-v3-d8d7-2024-04-04": 5562, + "inimai---open-app-copy-c50c-2024-11-28": 4319, + "localized-paywall-e901-2024-04-04": 5778, + "price-tester-1b8e-2024-04-04": 4370, + "products-v3-60c5-2024-04-04": 4725, + "superwall-template-9f9f-2024-05-21": 4167, + "url-paywall-v3-3810-2024-04-04": 4015, + "video-v3-72b4-2024-04-04": 4877 }, - "preloadCompleteEventMs": 750, + "preloadCompleteEventMs": 1531, "run": 4 }, { - "allReadyMs": 5661, + "allReadyMs": 5416, "cold": true, - "configureMs": 1821, + "configureMs": 1607, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5151, - "data-v3-0ed9-2024-04-04": 5560, - "free-trial-v3-d8d7-2024-04-04": 4543, - "inimai---open-app-copy-c50c-2024-11-28": 3729, - "localized-paywall-e901-2024-04-04": 5661, - "price-tester-1b8e-2024-04-04": 4645, - "products-v3-60c5-2024-04-04": 4796, - "superwall-template-9f9f-2024-05-21": 3983, - "url-paywall-v3-3810-2024-04-04": 4391, - "video-v3-72b4-2024-04-04": 4188 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5416, + "data-v3-0ed9-2024-04-04": 4455, + "free-trial-v3-d8d7-2024-04-04": 4201, + "inimai---open-app-copy-c50c-2024-11-28": 3340, + "localized-paywall-e901-2024-04-04": 4707, + "price-tester-1b8e-2024-04-04": 3593, + "products-v3-60c5-2024-04-04": 3898, + "superwall-template-9f9f-2024-05-21": 3441, + "url-paywall-v3-3810-2024-04-04": 3745, + "video-v3-72b4-2024-04-04": 3694 }, - "preloadCompleteEventMs": 918, + "preloadCompleteEventMs": 1003, "run": 5 }, { - "allReadyMs": 6134, + "allReadyMs": 4746, "cold": true, - "configureMs": 1168, + "configureMs": 1631, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5171, - "data-v3-0ed9-2024-04-04": 6134, - "free-trial-v3-d8d7-2024-04-04": 4407, - "inimai---open-app-copy-c50c-2024-11-28": 3797, - "localized-paywall-e901-2024-04-04": 5322, - "price-tester-1b8e-2024-04-04": 5474, - "products-v3-60c5-2024-04-04": 4715, - "superwall-template-9f9f-2024-05-21": 4000, - "url-paywall-v3-3810-2024-04-04": 4204, - "video-v3-72b4-2024-04-04": 4511 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4493, + "data-v3-0ed9-2024-04-04": 4746, + "free-trial-v3-d8d7-2024-04-04": 4089, + "inimai---open-app-copy-c50c-2024-11-28": 3480, + "localized-paywall-e901-2024-04-04": 4139, + "price-tester-1b8e-2024-04-04": 4240, + "products-v3-60c5-2024-04-04": 3632, + "superwall-template-9f9f-2024-05-21": 3429, + "url-paywall-v3-3810-2024-04-04": 3936, + "video-v3-72b4-2024-04-04": 4291 }, "preloadCompleteEventMs": 1045, "run": 6 }, { - "allReadyMs": 6248, + "allReadyMs": 4568, "cold": true, - "configureMs": 2667, + "configureMs": 1376, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6248, - "data-v3-0ed9-2024-04-04": 5436, - "free-trial-v3-d8d7-2024-04-04": 4620, - "inimai---open-app-copy-c50c-2024-11-28": 4058, - "localized-paywall-e901-2024-04-04": 4979, - "price-tester-1b8e-2024-04-04": 4415, - "products-v3-60c5-2024-04-04": 5639, - "superwall-template-9f9f-2024-05-21": 4262, - "url-paywall-v3-3810-2024-04-04": 5131, - "video-v3-72b4-2024-04-04": 5740 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4163, + "data-v3-0ed9-2024-04-04": 4568, + "free-trial-v3-d8d7-2024-04-04": 3607, + "inimai---open-app-copy-c50c-2024-11-28": 3253, + "localized-paywall-e901-2024-04-04": 3708, + "price-tester-1b8e-2024-04-04": 3506, + "products-v3-60c5-2024-04-04": 3809, + "superwall-template-9f9f-2024-05-21": 3405, + "url-paywall-v3-3810-2024-04-04": 3911, + "video-v3-72b4-2024-04-04": 4012 }, - "preloadCompleteEventMs": 1156, + "preloadCompleteEventMs": 1085, "run": 7 }, { - "allReadyMs": 6569, + "allReadyMs": 5427, "cold": true, - "configureMs": 1540, + "configureMs": 1241, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5655, - "data-v3-0ed9-2024-04-04": 5250, - "free-trial-v3-d8d7-2024-04-04": 5402, - "inimai---open-app-copy-c50c-2024-11-28": 4032, - "localized-paywall-e901-2024-04-04": 6569, - "price-tester-1b8e-2024-04-04": 4387, - "products-v3-60c5-2024-04-04": 4641, - "superwall-template-9f9f-2024-05-21": 4234, - "url-paywall-v3-3810-2024-04-04": 3930, - "video-v3-72b4-2024-04-04": 4539 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4312, + "data-v3-0ed9-2024-04-04": 4008, + "free-trial-v3-d8d7-2024-04-04": 4109, + "inimai---open-app-copy-c50c-2024-11-28": 3350, + "localized-paywall-e901-2024-04-04": 5427, + "price-tester-1b8e-2024-04-04": 3604, + "products-v3-60c5-2024-04-04": 3249, + "superwall-template-9f9f-2024-05-21": 4617, + "url-paywall-v3-3810-2024-04-04": 3452, + "video-v3-72b4-2024-04-04": 3553 }, - "preloadCompleteEventMs": 1177, + "preloadCompleteEventMs": 952, "run": 8 }, { - "allReadyMs": 5157, + "allReadyMs": 4633, "cold": true, - "configureMs": 1777, + "configureMs": 1463, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4599, - "data-v3-0ed9-2024-04-04": 4903, - "free-trial-v3-d8d7-2024-04-04": 5055, - "inimai---open-app-copy-c50c-2024-11-28": 3329, - "localized-paywall-e901-2024-04-04": 5157, - "price-tester-1b8e-2024-04-04": 3939, - "products-v3-60c5-2024-04-04": 4244, - "superwall-template-9f9f-2024-05-21": 3531, - "url-paywall-v3-3810-2024-04-04": 4091, - "video-v3-72b4-2024-04-04": 4295 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4633, + "data-v3-0ed9-2024-04-04": 4431, + "free-trial-v3-d8d7-2024-04-04": 4026, + "inimai---open-app-copy-c50c-2024-11-28": 3318, + "localized-paywall-e901-2024-04-04": 3925, + "price-tester-1b8e-2024-04-04": 3824, + "products-v3-60c5-2024-04-04": 4229, + "superwall-template-9f9f-2024-05-21": 3470, + "url-paywall-v3-3810-2024-04-04": 3216, + "video-v3-72b4-2024-04-04": 4128 }, - "preloadCompleteEventMs": 572, + "preloadCompleteEventMs": 983, "run": 9 }, { - "allReadyMs": 6017, + "allReadyMs": 4692, "cold": true, - "configureMs": 1848, + "configureMs": 1656, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6017, - "data-v3-0ed9-2024-04-04": 5663, - "free-trial-v3-d8d7-2024-04-04": 3941, - "inimai---open-app-copy-c50c-2024-11-28": 4296, - "localized-paywall-e901-2024-04-04": 4955, - "price-tester-1b8e-2024-04-04": 4600, - "products-v3-60c5-2024-04-04": 5258, - "superwall-template-9f9f-2024-05-21": 4144, - "url-paywall-v3-3810-2024-04-04": 5106, - "video-v3-72b4-2024-04-04": 5410 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4237, + "data-v3-0ed9-2024-04-04": 4692, + "free-trial-v3-d8d7-2024-04-04": 3578, + "inimai---open-app-copy-c50c-2024-11-28": 3426, + "localized-paywall-e901-2024-04-04": 4338, + "price-tester-1b8e-2024-04-04": 3629, + "products-v3-60c5-2024-04-04": 4035, + "superwall-template-9f9f-2024-05-21": 3375, + "url-paywall-v3-3810-2024-04-04": 3883, + "video-v3-72b4-2024-04-04": 4288 }, - "preloadCompleteEventMs": 1240, + "preloadCompleteEventMs": 970, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 41.85237071417446, - "coldMeanMs": 7777.8, - "maxMs": 13903, - "meanMs": 7777.8, - "medianMs": 6191.0, - "minMs": 5157, + "coefficientOfVariationPct": 13.920501025868317, + "coldMeanMs": 5261.4, + "maxMs": 6475, + "meanMs": 5261.4, + "medianMs": 5081.0, + "minMs": 4568, "sampleCount": 10, - "stdDevMs": 3255.1936894070614, + "stdDevMs": 732.4132409750356, "warmMeanMs": null }, "tier": "MID" From be41e61b7a91b60bedf840e88fa8c93529bedb3d Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Jul 2026 16:56:44 +0000 Subject: [PATCH 03/12] test(app): add FTL re-present regression tests for transient state reset Add 2 emulator (Firebase Test Lab) androidTest cases covering the PR #434 fix: after a consumable purchase, re-presenting the same cached paywall used to leave the buy button dead because a stale LoadingPurchase overlay carried over. Both tests drive the full-screen register() path (the fixed path) from a fragment-hosted screen and purchase via Superwall test mode (no Play billing on CI): - PaywallHostFragment: minimal fragment that calls register() on view-create, mirroring the customer's fragment-hosted setup. - RepresentTests.test_represent_after_consumable_purchase_reinvokes_purchase: present -> buy -> drawer -> Purchased -> dismiss -> re-present -> tap buy again; asserts the purchase drawer re-appears (dead pre-fix). - RepresentTests.test_represent_resets_loading_state: after re-present, asserts the public loadingState is not LoadingPurchase (public-API analog of the internal reset unit test). Wire up androidx.fragment:fragment-testing (+ fragment-testing-manifest for the FragmentScenario host activity) via the version catalog. Flow keys off the CONSUMABLE_REBUY_PLACEMENT / BUY_BUTTON_TEXT constants so the placement and CTA label can be adjusted server-side. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01Y6NCb2BMXSXwAN1vCMFvyc --- app/build.gradle.kts | 3 + .../superapp/test/PaywallHostFragment.kt | 47 ++++ .../example/superapp/test/RepresentTests.kt | 250 ++++++++++++++++++ gradle/libs.versions.toml | 3 + 4 files changed, 303 insertions(+) create mode 100644 app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt create mode 100644 app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index d69a10500..ab45ed252 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -113,12 +113,15 @@ dependencies { androidTestImplementation(libs.test.runner) androidTestImplementation(libs.mockk.android) androidTestImplementation(libs.mockk.core) + androidTestImplementation(libs.androidx.fragment.testing) androidTestUtil(libs.orchestrator) // Debug // debugImplementation(libs.leakcanary.android) debugImplementation(libs.ui.tooling) debugImplementation(libs.ui.test.manifest) + // Provides FragmentScenario's empty host activity in the debug manifest. + debugImplementation(libs.androidx.fragment.testing.manifest) } tasks.register("pullEventTimelines") { diff --git a/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt b/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt new file mode 100644 index 000000000..755ec6c9a --- /dev/null +++ b/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt @@ -0,0 +1,47 @@ +package com.example.superapp.test + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.FrameLayout +import androidx.fragment.app.Fragment +import com.superwall.sdk.Superwall +import com.superwall.sdk.paywall.presentation.register + +/** + * Minimal test-host screen that presents a paywall from a [Fragment] via + * [register] — mirroring the customer's fragment-hosted setup that surfaced the + * regression fixed in PR #434 (stale transient presentation state carried onto a + * re-presented cached paywall). The fragment is only the screen that *triggers* + * presentation; the paywall itself shows full-screen in `SuperwallPaywallActivity` + * via the `register()` path (NOT the embedded `getPaywall()` path). + */ +class PaywallHostFragment : Fragment() { + // Parameterised so the whole flow keys off a single placement constant. + var placement: String = RepresentTests.CONSUMABLE_REBUY_PLACEMENT + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View = FrameLayout(requireContext()) + + override fun onViewCreated( + view: View, + savedInstanceState: Bundle?, + ) { + super.onViewCreated(view, savedInstanceState) + // On view-create, present the paywall exactly as the customer's fragment does. + present() + } + + /** + * Re-invokes the same `register()` entry point. On the second call the SDK reuses + * the CACHED `PaywallView`, which is precisely the path where the stale + * `LoadingPurchase` overlay used to swallow the buy tap before PR #434. + */ + fun present() { + Superwall.instance.register(placement = placement) + } +} diff --git a/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt b/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt new file mode 100644 index 000000000..b7b9f5b91 --- /dev/null +++ b/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt @@ -0,0 +1,250 @@ +package com.example.superapp.test + +import android.app.Application +import androidx.fragment.app.testing.launchFragmentInContainer +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation +import androidx.test.uiautomator.By +import androidx.test.uiautomator.UiDevice +import androidx.test.uiautomator.UiSelector +import androidx.test.uiautomator.Until +import com.example.superapp.utils.awaitUntilWebviewAppears +import com.example.superapp.utils.awaitUntilWebviewDisappears +import com.example.superapp.utils.clickButtonWith +import com.superwall.sdk.Superwall +import com.superwall.sdk.analytics.superwall.SuperwallEvent +import com.superwall.sdk.analytics.superwall.SuperwallEventInfo +import com.superwall.sdk.config.models.ConfigurationStatus +import com.superwall.sdk.config.options.PaywallOptions +import com.superwall.sdk.config.options.SuperwallOptions +import com.superwall.sdk.delegate.SuperwallDelegate +import com.superwall.sdk.logger.LogLevel +import com.superwall.sdk.paywall.view.delegate.PaywallLoadingState +import com.superwall.sdk.store.testmode.TestModeBehavior +import com.superwall.superapp.Keys +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withTimeoutOrNull +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds + +/** + * Emulator (Firebase Test Lab) regression tests for PR #434 + * (`fix/paywall-transient-state-reset-on-represent`). + * + * Repro: after a consumable purchase, re-presenting the SAME paywall in one app + * session left the buy button dead — a stale `LoadingPurchase` loading overlay (and + * stale `presentationDidFinishPrepare`) carried onto the re-presented CACHED paywall + * and swallowed the tap. The fix has `PaywallView.present()` call + * `resetTransientPresentationState()` first. + * + * These tests drive the full-screen `register()` flow (the fixed path) from a + * fragment-hosted screen ([PaywallHostFragment]), purchase via Superwall test mode + * (billing is unavailable on CI emulators), then re-present and re-tap buy. + * + * Assertions are event/state based (no golden screenshots) so they can be validated + * on FTL without locally generated baseline images. + */ +@RunWith(AndroidJUnit4::class) +class RepresentTests { + companion object { + /** + * Placement that must present a NON-gated paywall backed by a CONSUMABLE + * product (one that grants NO persistent entitlement), so the same paywall + * can be re-presented and re-bought within a single session. + * + * `non_recurring_product` is the closest existing placement (see + * `UITestHandler.testAndroid20Info`, "Non-recurring product purchase"). If it + * turns out to be gated / to grant a blocking entitlement, point this constant + * at a dedicated consumable re-buy placement instead. + */ + const val CONSUMABLE_REBUY_PLACEMENT = "non_recurring_product" + + /** + * The paywall's primary purchase CTA label (WebView text). Must be DISTINCT + * from the test-mode activation modal's "Continue" button, otherwise the buy + * tap is ambiguous. Update to match the configured paywall's button text. + */ + const val BUY_BUTTON_TEXT = "Continue" + + // Test-mode purchase drawer confirm button (set in TestModePurchaseDrawer). + private const val CONFIRM_PURCHASE_TEXT = "Confirm Purchase" + + // Unique substring of the test-mode activation modal (dashboard hint row), + // used to detect the modal without colliding with paywall/webview text. + private const val TEST_MODE_MODAL_HINT = "Configure test mode users" + + private val EVENT_TIMEOUT = 30.seconds + private val UI_TIMEOUT_MS = 30_000L + } + + // Live event stream fed by the Superwall delegate installed in [setup]. + private val events = MutableSharedFlow(replay = 64, extraBufferCapacity = 256) + + @Before + fun setup() { + Superwall.configure( + getInstrumentation().targetContext.applicationContext as Application, + Keys.CONSTANT_API_KEY, + options = + SuperwallOptions().apply { + logging.level = LogLevel.debug + // Billing is unavailable on CI emulators — ALWAYS routes purchases + // through the in-app test-mode drawer instead of Google Play. + testModeBehavior = TestModeBehavior.ALWAYS + paywalls = + PaywallOptions().apply { + shouldPreload = false + } + }, + ) + Superwall.instance.delegate = + object : SuperwallDelegate { + override fun handleSuperwallEvent(eventInfo: SuperwallEventInfo) { + events.tryEmit(eventInfo.event) + } + } + } + + /** + * Test 1 — repro + fix, end-to-end. + * + * Present → buy → drawer → Purchased → dismiss → re-present the SAME placement → + * tap buy AGAIN. Pre-fix the second tap is dead (stale overlay swallows it) so the + * drawer never reappears; post-fix the purchase flow is re-invoked. + */ + @Test + fun test_represent_after_consumable_purchase_reinvokes_purchase() = + runBlocking { + awaitConfigured() + + val scenario = launchFragmentInContainer() + + // First presentation. + dismissTestModeActivationModalIfPresent() + assertTrue("First paywall never appeared", awaitUntilWebviewAppears()) + delay(1.seconds) + + // First purchase. + clickButtonWith(BUY_BUTTON_TEXT) + assertTrue( + "Purchase drawer did not appear on the FIRST buy tap", + awaitTextAppears(CONFIRM_PURCHASE_TEXT), + ) + val firstComplete = awaitEventAsync { it is SuperwallEvent.TransactionComplete } + clickButtonWith(CONFIRM_PURCHASE_TEXT) + assertNotNull("First purchase never completed", firstComplete.await()) + awaitUntilWebviewDisappears() + delay(1.seconds) + + // Re-present the SAME placement via the same fragment (reuses cached PaywallView). + scenario.onFragment { it.present() } + dismissTestModeActivationModalIfPresent() + assertTrue("Re-presented paywall never appeared", awaitUntilWebviewAppears()) + delay(1.seconds) + + // Tap buy AGAIN — dead pre-fix, alive post-fix (PR #434). + clickButtonWith(BUY_BUTTON_TEXT) + assertTrue( + "Re-presented paywall's buy tap did NOT re-invoke the purchase flow — " + + "stale transient presentation state regression (PR #434)", + awaitTextAppears(CONFIRM_PURCHASE_TEXT), + ) + } + + /** + * Test 2 — public-API state assertion (analog of the internal-reset unit test). + * + * After purchasing and re-presenting, the re-presented paywall must NOT be stuck in + * `LoadingPurchase` (which is what showed the tap-swallowing overlay). `:app:` can't + * see the internal reset API, so we assert via the public `loadingState` getter. + */ + @Test + fun test_represent_resets_loading_state() = + runBlocking { + awaitConfigured() + + val scenario = launchFragmentInContainer() + + dismissTestModeActivationModalIfPresent() + assertTrue("First paywall never appeared", awaitUntilWebviewAppears()) + delay(1.seconds) + + // Purchase once so a LoadingPurchase state exists to (previously) leak. + clickButtonWith(BUY_BUTTON_TEXT) + assertTrue( + "Purchase drawer did not appear on the buy tap", + awaitTextAppears(CONFIRM_PURCHASE_TEXT), + ) + val complete = awaitEventAsync { it is SuperwallEvent.TransactionComplete } + clickButtonWith(CONFIRM_PURCHASE_TEXT) + assertNotNull("Purchase never completed", complete.await()) + awaitUntilWebviewDisappears() + delay(1.seconds) + + // Re-present the cached paywall. + scenario.onFragment { it.present() } + dismissTestModeActivationModalIfPresent() + assertTrue("Re-presented paywall never appeared", awaitUntilWebviewAppears()) + delay(1.seconds) + + val paywallView = Superwall.instance.paywallView + assertNotNull("No paywallView after re-present", paywallView) + val loadingState = paywallView!!.loadingState + // Post-fix `resetTransientPresentationState()` puts LoadingPurchase back to Ready, + // so the tap-swallowing overlay is not shown. + assertTrue( + "Re-presented paywall carried a stale LoadingPurchase state (PR #434); was $loadingState", + loadingState !is PaywallLoadingState.LoadingPurchase, + ) + } + + // region helpers + + private suspend fun awaitConfigured() { + Superwall.instance.configurationStateListener.first { it is ConfigurationStatus.Configured } + } + + private fun device() = UiDevice.getInstance(getInstrumentation()) + + /** + * The ALWAYS test-mode activation modal auto-presents once (per just-activated + * session) and is non-cancelable. Detect it via its unique dashboard hint text and + * tap "Continue" to get past it. Best-effort: absent modal is not an error. + */ + private suspend fun dismissTestModeActivationModalIfPresent() { + val d = device() + val modal = d.wait(Until.findObject(By.textContains(TEST_MODE_MODAL_HINT)), 10_000) + if (modal != null) { + d.findObject(UiSelector().textContains("Continue")).click() + d.waitForIdle() + delay(500.milliseconds) + } + } + + private fun awaitTextAppears( + text: String, + timeoutMs: Long = UI_TIMEOUT_MS, + ): Boolean = device().wait(Until.findObject(By.textContains(text)), timeoutMs) != null + + /** + * Subscribe to [events] BEFORE the triggering action (avoids the emit/collect race), + * returning a Deferred that resolves to the matching event or null on timeout. + */ + private fun CoroutineScope.awaitEventAsync(predicate: (SuperwallEvent) -> Boolean) = + async(Dispatchers.IO) { + withTimeoutOrNull(EVENT_TIMEOUT) { events.first(predicate) } + } + + // endregion +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 268687245..ab33017f0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -43,6 +43,7 @@ dokka = "2.1.0" detekt = "1.23.7" robolectric = "4.13" activity_ktx_version = "1.10.1" +fragment_version = "1.8.5" [libraries] # SQL @@ -110,6 +111,8 @@ test_core = { module = "androidx.test:core", version.ref = "test_runner_version" test_rules = { module = "androidx.test:rules", version.ref = "test_rules_version" } ui_test_junit4 = { module = "androidx.compose.ui:ui-test-junit4" } mockk_android = { module = "io.mockk:mockk-android", version.ref = "mockk_version" } +androidx-fragment-testing = { module = "androidx.fragment:fragment-testing", version.ref = "fragment_version" } +androidx-fragment-testing-manifest = { module = "androidx.fragment:fragment-testing-manifest", version.ref = "fragment_version" } # Debug ui_tooling = { module = "androidx.compose.ui:ui-tooling" } From f5882e7ce1f94454476780449cb5d953bdcd68a9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 14 Jul 2026 17:08:28 +0000 Subject: [PATCH 04/12] Update paywall preload benchmark report [skip ci] --- .benchmark/REPORT.md | 6 +- .../results/preload-benchmark-high.json | 274 +++++++++--------- .benchmark/results/preload-benchmark-low.json | 274 +++++++++--------- .benchmark/results/preload-benchmark-mid.json | 274 +++++++++--------- 4 files changed, 414 insertions(+), 414 deletions(-) diff --git a/.benchmark/REPORT.md b/.benchmark/REPORT.md index adf3de644..a056bb0ab 100644 --- a/.benchmark/REPORT.md +++ b/.benchmark/REPORT.md @@ -4,9 +4,9 @@ Time from `preloadAllPaywalls()` until every paywall reaches `PaywallLoadingStat | Tier | Paywalls | Mean | Baseline | Δ | Limit | Cold mean | Warm mean | Median | StdDev | CV | Samples | Status | |------|----------|------|----------|---|-------|-----------|-----------|--------|--------|----|---------|--------| -| LOW | 10 | 4.33s | 6.34s | -31.7% | +30% | 4.40s | — | 4.33s | 497ms | 11.3% | 10 (10×1) | 🟢 improved | -| MID | 10 | 5.08s | 8.78s | -42.1% | +15% | 5.26s | — | 5.08s | 732ms | 13.9% | 10 (10×1) | 🟢 improved | -| HIGH | 10 | 10.89s | 6.72s | +62.1% | +20% | 11.86s | — | 10.89s | 5.61s | 47.3% | 10 (10×1) | ❌ regression | +| LOW | 10 | 6.61s | 6.34s | +4.3% | +30% | 8.78s | — | 6.61s | 4.90s | 55.8% | 10 (10×1) | ✅ OK | +| MID | 10 | 5.30s | 8.78s | -39.5% | +15% | 5.66s | — | 5.30s | 655ms | 11.6% | 10 (10×1) | 🟢 improved | +| HIGH | 10 | 7.08s | 6.72s | +5.4% | +20% | 8.26s | — | 7.08s | 2.70s | 32.7% | 10 (10×1) | ✅ OK | ### Devices diff --git a/.benchmark/results/preload-benchmark-high.json b/.benchmark/results/preload-benchmark-high.json index 77a64ce52..50061e36d 100644 --- a/.benchmark/results/preload-benchmark-high.json +++ b/.benchmark/results/preload-benchmark-high.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 20495, + "allReadyMs": 13569, "cold": true, - "configureMs": 3746, + "configureMs": 3147, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9369, - "data-v3-0ed9-2024-04-04": 11648, - "free-trial-v3-d8d7-2024-04-04": 19620, - "inimai---open-app-copy-c50c-2024-11-28": 20495, - "localized-paywall-e901-2024-04-04": 18074, - "price-tester-1b8e-2024-04-04": 13312, - "products-v3-60c5-2024-04-04": 13005, - "superwall-template-9f9f-2024-05-21": 20084, - "url-paywall-v3-3810-2024-04-04": 9877, - "video-v3-72b4-2024-04-04": 12378 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 13569, + "data-v3-0ed9-2024-04-04": 12297, + "free-trial-v3-d8d7-2024-04-04": 13163, + "inimai---open-app-copy-c50c-2024-11-28": 11276, + "localized-paywall-e901-2024-04-04": 12450, + "price-tester-1b8e-2024-04-04": 11738, + "products-v3-60c5-2024-04-04": 12908, + "superwall-template-9f9f-2024-05-21": 11073, + "url-paywall-v3-3810-2024-04-04": 12704, + "video-v3-72b4-2024-04-04": 11942 }, - "preloadCompleteEventMs": 2771, + "preloadCompleteEventMs": 6196, "run": 1 }, { - "allReadyMs": 15812, + "allReadyMs": 7186, "cold": true, - "configureMs": 2865, + "configureMs": 1665, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 15507, - "data-v3-0ed9-2024-04-04": 14332, - "free-trial-v3-d8d7-2024-04-04": 15812, - "inimai---open-app-copy-c50c-2024-11-28": 11561, - "localized-paywall-e901-2024-04-04": 13227, - "price-tester-1b8e-2024-04-04": 14538, - "products-v3-60c5-2024-04-04": 11301, - "superwall-template-9f9f-2024-05-21": 10426, - "url-paywall-v3-3810-2024-04-04": 14793, - "video-v3-72b4-2024-04-04": 12971 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6576, + "data-v3-0ed9-2024-04-04": 6932, + "free-trial-v3-d8d7-2024-04-04": 5610, + "inimai---open-app-copy-c50c-2024-11-28": 4625, + "localized-paywall-e901-2024-04-04": 5243, + "price-tester-1b8e-2024-04-04": 7084, + "products-v3-60c5-2024-04-04": 5814, + "superwall-template-9f9f-2024-05-21": 4988, + "url-paywall-v3-3810-2024-04-04": 4523, + "video-v3-72b4-2024-04-04": 7186 }, - "preloadCompleteEventMs": 3062, + "preloadCompleteEventMs": 1141, "run": 2 }, { - "allReadyMs": 20855, + "allReadyMs": 11772, "cold": true, - "configureMs": 3171, + "configureMs": 2299, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 19339, - "data-v3-0ed9-2024-04-04": 18039, - "free-trial-v3-d8d7-2024-04-04": 14315, - "inimai---open-app-copy-c50c-2024-11-28": 11170, - "localized-paywall-e901-2024-04-04": 15667, - "price-tester-1b8e-2024-04-04": 20444, - "products-v3-60c5-2024-04-04": 16608, - "superwall-template-9f9f-2024-05-21": 12676, - "url-paywall-v3-3810-2024-04-04": 20021, - "video-v3-72b4-2024-04-04": 20855 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9572, + "data-v3-0ed9-2024-04-04": 11772, + "free-trial-v3-d8d7-2024-04-04": 10753, + "inimai---open-app-copy-c50c-2024-11-28": 7406, + "localized-paywall-e901-2024-04-04": 10295, + "price-tester-1b8e-2024-04-04": 7142, + "products-v3-60c5-2024-04-04": 11213, + "superwall-template-9f9f-2024-05-21": 7968, + "url-paywall-v3-3810-2024-04-04": 8698, + "video-v3-72b4-2024-04-04": 10956 }, - "preloadCompleteEventMs": 2335, + "preloadCompleteEventMs": 1290, "run": 3 }, { - "allReadyMs": 12217, + "allReadyMs": 10521, "cold": true, - "configureMs": 2856, + "configureMs": 1790, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 12217, - "data-v3-0ed9-2024-04-04": 11709, - "free-trial-v3-d8d7-2024-04-04": 6921, - "inimai---open-app-copy-c50c-2024-11-28": 9454, - "localized-paywall-e901-2024-04-04": 6511, - "price-tester-1b8e-2024-04-04": 8894, - "products-v3-60c5-2024-04-04": 8486, - "superwall-template-9f9f-2024-05-21": 7591, - "url-paywall-v3-3810-2024-04-04": 7845, - "video-v3-72b4-2024-04-04": 8099 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 10521, + "data-v3-0ed9-2024-04-04": 10113, + "free-trial-v3-d8d7-2024-04-04": 8561, + "inimai---open-app-copy-c50c-2024-11-28": 7234, + "localized-paywall-e901-2024-04-04": 6724, + "price-tester-1b8e-2024-04-04": 9182, + "products-v3-60c5-2024-04-04": 8099, + "superwall-template-9f9f-2024-05-21": 7743, + "url-paywall-v3-3810-2024-04-04": 7029, + "video-v3-72b4-2024-04-04": 9551 }, - "preloadCompleteEventMs": 1762, + "preloadCompleteEventMs": 1485, "run": 4 }, { - "allReadyMs": 12759, + "allReadyMs": 6434, "cold": true, - "configureMs": 3887, + "configureMs": 1502, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 10802, - "data-v3-0ed9-2024-04-04": 12759, - "free-trial-v3-d8d7-2024-04-04": 7940, - "inimai---open-app-copy-c50c-2024-11-28": 11471, - "localized-paywall-e901-2024-04-04": 7085, - "price-tester-1b8e-2024-04-04": 6983, - "products-v3-60c5-2024-04-04": 9882, - "superwall-template-9f9f-2024-05-21": 11982, - "url-paywall-v3-3810-2024-04-04": 8347, - "video-v3-72b4-2024-04-04": 8551 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5111, + "data-v3-0ed9-2024-04-04": 6434, + "free-trial-v3-d8d7-2024-04-04": 5314, + "inimai---open-app-copy-c50c-2024-11-28": 3733, + "localized-paywall-e901-2024-04-04": 4393, + "price-tester-1b8e-2024-04-04": 4139, + "products-v3-60c5-2024-04-04": 5467, + "superwall-template-9f9f-2024-05-21": 3987, + "url-paywall-v3-3810-2024-04-04": 3631, + "video-v3-72b4-2024-04-04": 4292 }, - "preloadCompleteEventMs": 1943, + "preloadCompleteEventMs": 743, "run": 5 }, { - "allReadyMs": 9556, + "allReadyMs": 5807, "cold": true, - "configureMs": 2277, + "configureMs": 2174, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9556, - "data-v3-0ed9-2024-04-04": 7851, - "free-trial-v3-d8d7-2024-04-04": 8885, - "inimai---open-app-copy-c50c-2024-11-28": 6258, - "localized-paywall-e901-2024-04-04": 7234, - "price-tester-1b8e-2024-04-04": 6360, - "products-v3-60c5-2024-04-04": 8158, - "superwall-template-9f9f-2024-05-21": 6106, - "url-paywall-v3-3810-2024-04-04": 6513, - "video-v3-72b4-2024-04-04": 8467 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4075, + "data-v3-0ed9-2024-04-04": 4941, + "free-trial-v3-d8d7-2024-04-04": 3667, + "inimai---open-app-copy-c50c-2024-11-28": 5807, + "localized-paywall-e901-2024-04-04": 3464, + "price-tester-1b8e-2024-04-04": 3363, + "products-v3-60c5-2024-04-04": 4483, + "superwall-template-9f9f-2024-05-21": 3210, + "url-paywall-v3-3810-2024-04-04": 3769, + "video-v3-72b4-2024-04-04": 4636 }, - "preloadCompleteEventMs": 1558, + "preloadCompleteEventMs": 722, "run": 6 }, { - "allReadyMs": 7132, + "allReadyMs": 7678, "cold": true, - "configureMs": 1846, + "configureMs": 1737, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5146, - "data-v3-0ed9-2024-04-04": 6315, - "free-trial-v3-d8d7-2024-04-04": 5299, - "inimai---open-app-copy-c50c-2024-11-28": 5400, - "localized-paywall-e901-2024-04-04": 7132, - "price-tester-1b8e-2024-04-04": 5959, - "products-v3-60c5-2024-04-04": 4688, - "superwall-template-9f9f-2024-05-21": 5654, - "url-paywall-v3-3810-2024-04-04": 5858, - "video-v3-72b4-2024-04-04": 4840 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5607, + "data-v3-0ed9-2024-04-04": 6122, + "free-trial-v3-d8d7-2024-04-04": 5100, + "inimai---open-app-copy-c50c-2024-11-28": 4743, + "localized-paywall-e901-2024-04-04": 4896, + "price-tester-1b8e-2024-04-04": 4436, + "products-v3-60c5-2024-04-04": 5252, + "superwall-template-9f9f-2024-05-21": 7678, + "url-paywall-v3-3810-2024-04-04": 3978, + "video-v3-72b4-2024-04-04": 4385 }, - "preloadCompleteEventMs": 1537, + "preloadCompleteEventMs": 1026, "run": 7 }, { - "allReadyMs": 6023, + "allReadyMs": 6978, "cold": true, - "configureMs": 1748, + "configureMs": 1481, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5617, - "data-v3-0ed9-2024-04-04": 6023, - "free-trial-v3-d8d7-2024-04-04": 5161, - "inimai---open-app-copy-c50c-2024-11-28": 4447, - "localized-paywall-e901-2024-04-04": 4958, - "price-tester-1b8e-2024-04-04": 4856, - "products-v3-60c5-2024-04-04": 5313, - "superwall-template-9f9f-2024-05-21": 4703, - "url-paywall-v3-3810-2024-04-04": 3887, - "video-v3-72b4-2024-04-04": 4243 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5606, + "data-v3-0ed9-2024-04-04": 4845, + "free-trial-v3-d8d7-2024-04-04": 4081, + "inimai---open-app-copy-c50c-2024-11-28": 6978, + "localized-paywall-e901-2024-04-04": 4946, + "price-tester-1b8e-2024-04-04": 4285, + "products-v3-60c5-2024-04-04": 4388, + "superwall-template-9f9f-2024-05-21": 5200, + "url-paywall-v3-3810-2024-04-04": 4183, + "video-v3-72b4-2024-04-04": 3725 }, - "preloadCompleteEventMs": 1299, + "preloadCompleteEventMs": 1064, "run": 8 }, { - "allReadyMs": 6688, + "allReadyMs": 6181, "cold": true, - "configureMs": 1086, + "configureMs": 1868, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6280, - "data-v3-0ed9-2024-04-04": 5519, - "free-trial-v3-d8d7-2024-04-04": 4296, - "inimai---open-app-copy-c50c-2024-11-28": 4042, - "localized-paywall-e901-2024-04-04": 6688, - "price-tester-1b8e-2024-04-04": 4144, - "products-v3-60c5-2024-04-04": 5113, - "superwall-template-9f9f-2024-05-21": 4601, - "url-paywall-v3-3810-2024-04-04": 4960, - "video-v3-72b4-2024-04-04": 4806 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3789, + "data-v3-0ed9-2024-04-04": 5672, + "free-trial-v3-d8d7-2024-04-04": 4961, + "inimai---open-app-copy-c50c-2024-11-28": 4248, + "localized-paywall-e901-2024-04-04": 6181, + "price-tester-1b8e-2024-04-04": 5368, + "products-v3-60c5-2024-04-04": 5266, + "superwall-template-9f9f-2024-05-21": 4045, + "url-paywall-v3-3810-2024-04-04": 5978, + "video-v3-72b4-2024-04-04": 5113 }, - "preloadCompleteEventMs": 1078, + "preloadCompleteEventMs": 746, "run": 9 }, { - "allReadyMs": 7084, + "allReadyMs": 6449, "cold": true, - "configureMs": 1848, + "configureMs": 1827, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6678, - "data-v3-0ed9-2024-04-04": 7084, - "free-trial-v3-d8d7-2024-04-04": 5762, - "inimai---open-app-copy-c50c-2024-11-28": 4693, - "localized-paywall-e901-2024-04-04": 5456, - "price-tester-1b8e-2024-04-04": 6118, - "products-v3-60c5-2024-04-04": 6423, - "superwall-template-9f9f-2024-05-21": 4947, - "url-paywall-v3-3810-2024-04-04": 6016, - "video-v3-72b4-2024-04-04": 6219 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4295, + "data-v3-0ed9-2024-04-04": 5121, + "free-trial-v3-d8d7-2024-04-04": 4613, + "inimai---open-app-copy-c50c-2024-11-28": 5273, + "localized-paywall-e901-2024-04-04": 6195, + "price-tester-1b8e-2024-04-04": 4714, + "products-v3-60c5-2024-04-04": 6449, + "superwall-template-9f9f-2024-05-21": 6043, + "url-paywall-v3-3810-2024-04-04": 4816, + "video-v3-72b4-2024-04-04": 5375 }, - "preloadCompleteEventMs": 794, + "preloadCompleteEventMs": 1244, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 47.299406981582536, - "coldMeanMs": 11862.1, - "maxMs": 20855, - "meanMs": 11862.1, - "medianMs": 10886.5, - "minMs": 6023, + "coefficientOfVariationPct": 32.72515887530627, + "coldMeanMs": 8257.5, + "maxMs": 13569, + "meanMs": 8257.5, + "medianMs": 7082.0, + "minMs": 5807, "sampleCount": 10, - "stdDevMs": 5610.702955562302, + "stdDevMs": 2702.279994128415, "warmMeanMs": null }, "tier": "HIGH" diff --git a/.benchmark/results/preload-benchmark-low.json b/.benchmark/results/preload-benchmark-low.json index 4ee2687a4..cc5a2bc32 100644 --- a/.benchmark/results/preload-benchmark-low.json +++ b/.benchmark/results/preload-benchmark-low.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 5488, + "allReadyMs": 21525, "cold": true, - "configureMs": 2171, + "configureMs": 11939, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3871, - "data-v3-0ed9-2024-04-04": 3619, - "free-trial-v3-d8d7-2024-04-04": 5337, - "inimai---open-app-copy-c50c-2024-11-28": 5185, - "localized-paywall-e901-2024-04-04": 5488, - "price-tester-1b8e-2024-04-04": 3266, - "products-v3-60c5-2024-04-04": 4527, - "superwall-template-9f9f-2024-05-21": 4729, - "url-paywall-v3-3810-2024-04-04": 3418, - "video-v3-72b4-2024-04-04": 3670 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 17348, + "data-v3-0ed9-2024-04-04": 17804, + "free-trial-v3-d8d7-2024-04-04": 21525, + "inimai---open-app-copy-c50c-2024-11-28": 18629, + "localized-paywall-e901-2024-04-04": 18897, + "price-tester-1b8e-2024-04-04": 15046, + "products-v3-60c5-2024-04-04": 15762, + "superwall-template-9f9f-2024-05-21": 20910, + "url-paywall-v3-3810-2024-04-04": 13476, + "video-v3-72b4-2024-04-04": 14728 }, - "preloadCompleteEventMs": 1035, + "preloadCompleteEventMs": 2740, "run": 1 }, { - "allReadyMs": 4304, + "allReadyMs": 8910, "cold": true, - "configureMs": 1440, + "configureMs": 2011, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4304, - "data-v3-0ed9-2024-04-04": 4001, - "free-trial-v3-d8d7-2024-04-04": 4152, - "inimai---open-app-copy-c50c-2024-11-28": 3345, - "localized-paywall-e901-2024-04-04": 3597, - "price-tester-1b8e-2024-04-04": 3547, - "products-v3-60c5-2024-04-04": 3496, - "superwall-template-9f9f-2024-05-21": 3294, - "url-paywall-v3-3810-2024-04-04": 4052, - "video-v3-72b4-2024-04-04": 3749 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 8910, + "data-v3-0ed9-2024-04-04": 8148, + "free-trial-v3-d8d7-2024-04-04": 6089, + "inimai---open-app-copy-c50c-2024-11-28": 5021, + "localized-paywall-e901-2024-04-04": 7318, + "price-tester-1b8e-2024-04-04": 6600, + "products-v3-60c5-2024-04-04": 6957, + "superwall-template-9f9f-2024-05-21": 5726, + "url-paywall-v3-3810-2024-04-04": 7571, + "video-v3-72b4-2024-04-04": 6395 }, - "preloadCompleteEventMs": 999, + "preloadCompleteEventMs": 1070, "run": 2 }, { - "allReadyMs": 4246, + "allReadyMs": 11693, "cold": true, - "configureMs": 1341, + "configureMs": 1674, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3691, - "data-v3-0ed9-2024-04-04": 4095, - "free-trial-v3-d8d7-2024-04-04": 3133, - "inimai---open-app-copy-c50c-2024-11-28": 3943, - "localized-paywall-e901-2024-04-04": 4145, - "price-tester-1b8e-2024-04-04": 3540, - "products-v3-60c5-2024-04-04": 4246, - "superwall-template-9f9f-2024-05-21": 3234, - "url-paywall-v3-3810-2024-04-04": 3435, - "video-v3-72b4-2024-04-04": 3486 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 10967, + "data-v3-0ed9-2024-04-04": 11490, + "free-trial-v3-d8d7-2024-04-04": 10552, + "inimai---open-app-copy-c50c-2024-11-28": 8812, + "localized-paywall-e901-2024-04-04": 9115, + "price-tester-1b8e-2024-04-04": 10096, + "products-v3-60c5-2024-04-04": 9420, + "superwall-template-9f9f-2024-05-21": 8609, + "url-paywall-v3-3810-2024-04-04": 11693, + "video-v3-72b4-2024-04-04": 11186 }, - "preloadCompleteEventMs": 982, + "preloadCompleteEventMs": 2510, "run": 3 }, { - "allReadyMs": 4357, + "allReadyMs": 9138, "cold": true, - "configureMs": 1521, + "configureMs": 1540, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4206, - "data-v3-0ed9-2024-04-04": 4357, - "free-trial-v3-d8d7-2024-04-04": 3702, - "inimai---open-app-copy-c50c-2024-11-28": 3349, - "localized-paywall-e901-2024-04-04": 3752, - "price-tester-1b8e-2024-04-04": 4055, - "products-v3-60c5-2024-04-04": 3551, - "superwall-template-9f9f-2024-05-21": 3299, - "url-paywall-v3-3810-2024-04-04": 3450, - "video-v3-72b4-2024-04-04": 3601 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6553, + "data-v3-0ed9-2024-04-04": 9138, + "free-trial-v3-d8d7-2024-04-04": 7518, + "inimai---open-app-copy-c50c-2024-11-28": 7214, + "localized-paywall-e901-2024-04-04": 8126, + "price-tester-1b8e-2024-04-04": 7619, + "products-v3-60c5-2024-04-04": 7873, + "superwall-template-9f9f-2024-05-21": 6910, + "url-paywall-v3-3810-2024-04-04": 8075, + "video-v3-72b4-2024-04-04": 7771 }, - "preloadCompleteEventMs": 1102, + "preloadCompleteEventMs": 1447, "run": 4 }, { - "allReadyMs": 4108, + "allReadyMs": 6171, "cold": true, - "configureMs": 1324, + "configureMs": 1538, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3554, - "data-v3-0ed9-2024-04-04": 3705, - "free-trial-v3-d8d7-2024-04-04": 4007, - "inimai---open-app-copy-c50c-2024-11-28": 3352, - "localized-paywall-e901-2024-04-04": 4108, - "price-tester-1b8e-2024-04-04": 3403, - "products-v3-60c5-2024-04-04": 3806, - "superwall-template-9f9f-2024-05-21": 3251, - "url-paywall-v3-3810-2024-04-04": 3856, - "video-v3-72b4-2024-04-04": 3907 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5463, + "data-v3-0ed9-2024-04-04": 6171, + "free-trial-v3-d8d7-2024-04-04": 5210, + "inimai---open-app-copy-c50c-2024-11-28": 4043, + "localized-paywall-e901-2024-04-04": 5007, + "price-tester-1b8e-2024-04-04": 4347, + "products-v3-60c5-2024-04-04": 5666, + "superwall-template-9f9f-2024-05-21": 3942, + "url-paywall-v3-3810-2024-04-04": 4246, + "video-v3-72b4-2024-04-04": 4856 }, - "preloadCompleteEventMs": 1054, + "preloadCompleteEventMs": 695, "run": 5 }, { - "allReadyMs": 4908, + "allReadyMs": 6104, "cold": true, - "configureMs": 765, + "configureMs": 1706, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4202, - "data-v3-0ed9-2024-04-04": 3898, - "free-trial-v3-d8d7-2024-04-04": 3284, - "inimai---open-app-copy-c50c-2024-11-28": 3747, - "localized-paywall-e901-2024-04-04": 4908, - "price-tester-1b8e-2024-04-04": 3437, - "products-v3-60c5-2024-04-04": 3545, - "superwall-template-9f9f-2024-05-21": 3082, - "url-paywall-v3-3810-2024-04-04": 3387, - "video-v3-72b4-2024-04-04": 3336 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5799, + "data-v3-0ed9-2024-04-04": 6104, + "free-trial-v3-d8d7-2024-04-04": 4988, + "inimai---open-app-copy-c50c-2024-11-28": 4276, + "localized-paywall-e901-2024-04-04": 4731, + "price-tester-1b8e-2024-04-04": 5090, + "products-v3-60c5-2024-04-04": 5242, + "superwall-template-9f9f-2024-05-21": 4478, + "url-paywall-v3-3810-2024-04-04": 4123, + "video-v3-72b4-2024-04-04": 5394 }, - "preloadCompleteEventMs": 876, + "preloadCompleteEventMs": 1351, "run": 6 }, { - "allReadyMs": 4384, + "allReadyMs": 7054, "cold": true, - "configureMs": 1402, + "configureMs": 1835, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4384, - "data-v3-0ed9-2024-04-04": 3223, - "free-trial-v3-d8d7-2024-04-04": 4233, - "inimai---open-app-copy-c50c-2024-11-28": 3324, - "localized-paywall-e901-2024-04-04": 3828, - "price-tester-1b8e-2024-04-04": 4132, - "products-v3-60c5-2024-04-04": 3878, - "superwall-template-9f9f-2024-05-21": 3425, - "url-paywall-v3-3810-2024-04-04": 4080, - "video-v3-72b4-2024-04-04": 3929 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6540, + "data-v3-0ed9-2024-04-04": 6852, + "free-trial-v3-d8d7-2024-04-04": 6236, + "inimai---open-app-copy-c50c-2024-11-28": 5418, + "localized-paywall-e901-2024-04-04": 5519, + "price-tester-1b8e-2024-04-04": 5925, + "products-v3-60c5-2024-04-04": 5824, + "superwall-template-9f9f-2024-05-21": 5215, + "url-paywall-v3-3810-2024-04-04": 5012, + "video-v3-72b4-2024-04-04": 7054 }, - "preloadCompleteEventMs": 952, + "preloadCompleteEventMs": 2102, "run": 7 }, { - "allReadyMs": 4104, + "allReadyMs": 5486, "cold": true, - "configureMs": 1503, + "configureMs": 1814, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3649, - "data-v3-0ed9-2024-04-04": 2993, - "free-trial-v3-d8d7-2024-04-04": 3094, - "inimai---open-app-copy-c50c-2024-11-28": 3144, - "localized-paywall-e901-2024-04-04": 3347, - "price-tester-1b8e-2024-04-04": 3195, - "products-v3-60c5-2024-04-04": 3498, - "superwall-template-9f9f-2024-05-21": 2791, - "url-paywall-v3-3810-2024-04-04": 3448, - "video-v3-72b4-2024-04-04": 4104 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4929, + "data-v3-0ed9-2024-04-04": 5486, + "free-trial-v3-d8d7-2024-04-04": 4575, + "inimai---open-app-copy-c50c-2024-11-28": 3612, + "localized-paywall-e901-2024-04-04": 3713, + "price-tester-1b8e-2024-04-04": 4676, + "products-v3-60c5-2024-04-04": 4423, + "superwall-template-9f9f-2024-05-21": 4017, + "url-paywall-v3-3810-2024-04-04": 5031, + "video-v3-72b4-2024-04-04": 3511 }, - "preloadCompleteEventMs": 1005, + "preloadCompleteEventMs": 685, "run": 8 }, { - "allReadyMs": 3645, + "allReadyMs": 5926, "cold": true, - "configureMs": 1306, + "configureMs": 1475, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3342, - "data-v3-0ed9-2024-04-04": 3645, - "free-trial-v3-d8d7-2024-04-04": 2686, - "inimai---open-app-copy-c50c-2024-11-28": 2535, - "localized-paywall-e901-2024-04-04": 3040, - "price-tester-1b8e-2024-04-04": 2232, - "products-v3-60c5-2024-04-04": 3140, - "superwall-template-9f9f-2024-05-21": 2434, - "url-paywall-v3-3810-2024-04-04": 2939, - "video-v3-72b4-2024-04-04": 2989 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4757, + "data-v3-0ed9-2024-04-04": 5926, + "free-trial-v3-d8d7-2024-04-04": 5216, + "inimai---open-app-copy-c50c-2024-11-28": 5420, + "localized-paywall-e901-2024-04-04": 5521, + "price-tester-1b8e-2024-04-04": 3744, + "products-v3-60c5-2024-04-04": 5062, + "superwall-template-9f9f-2024-05-21": 4200, + "url-paywall-v3-3810-2024-04-04": 4909, + "video-v3-72b4-2024-04-04": 3896 }, - "preloadCompleteEventMs": 604, + "preloadCompleteEventMs": 1072, "run": 9 }, { - "allReadyMs": 4415, + "allReadyMs": 5801, "cold": true, - "configureMs": 1054, + "configureMs": 1888, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3810, - "data-v3-0ed9-2024-04-04": 4314, - "free-trial-v3-d8d7-2024-04-04": 3911, - "inimai---open-app-copy-c50c-2024-11-28": 3356, - "localized-paywall-e901-2024-04-04": 4415, - "price-tester-1b8e-2024-04-04": 3104, - "products-v3-60c5-2024-04-04": 3508, - "superwall-template-9f9f-2024-05-21": 3255, - "url-paywall-v3-3810-2024-04-04": 4012, - "video-v3-72b4-2024-04-04": 3659 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3673, + "data-v3-0ed9-2024-04-04": 4990, + "free-trial-v3-d8d7-2024-04-04": 5497, + "inimai---open-app-copy-c50c-2024-11-28": 3774, + "localized-paywall-e901-2024-04-04": 5801, + "price-tester-1b8e-2024-04-04": 5092, + "products-v3-60c5-2024-04-04": 5649, + "superwall-template-9f9f-2024-05-21": 4079, + "url-paywall-v3-3810-2024-04-04": 5193, + "video-v3-72b4-2024-04-04": 5295 }, - "preloadCompleteEventMs": 1074, + "preloadCompleteEventMs": 744, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 11.297661010250698, - "coldMeanMs": 4395.9, - "maxMs": 5488, - "meanMs": 4395.9, - "medianMs": 4330.5, - "minMs": 3645, + "coefficientOfVariationPct": 55.7768082196462, + "coldMeanMs": 8780.8, + "maxMs": 21525, + "meanMs": 8780.8, + "medianMs": 6612.5, + "minMs": 5486, "sampleCount": 10, - "stdDevMs": 496.63388034961037, + "stdDevMs": 4897.649976150693, "warmMeanMs": null }, "tier": "LOW" diff --git a/.benchmark/results/preload-benchmark-mid.json b/.benchmark/results/preload-benchmark-mid.json index a218f6076..4b2c00dff 100644 --- a/.benchmark/results/preload-benchmark-mid.json +++ b/.benchmark/results/preload-benchmark-mid.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 6475, + "allReadyMs": 7038, "cold": true, - "configureMs": 2224, + "configureMs": 2334, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6171, - "data-v3-0ed9-2024-04-04": 6373, - "free-trial-v3-d8d7-2024-04-04": 5968, - "inimai---open-app-copy-c50c-2024-11-28": 5209, - "localized-paywall-e901-2024-04-04": 5360, - "price-tester-1b8e-2024-04-04": 5461, - "products-v3-60c5-2024-04-04": 5512, - "superwall-template-9f9f-2024-05-21": 5107, - "url-paywall-v3-3810-2024-04-04": 5766, - "video-v3-72b4-2024-04-04": 6475 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7038, + "data-v3-0ed9-2024-04-04": 6173, + "free-trial-v3-d8d7-2024-04-04": 6683, + "inimai---open-app-copy-c50c-2024-11-28": 4851, + "localized-paywall-e901-2024-04-04": 5563, + "price-tester-1b8e-2024-04-04": 5817, + "products-v3-60c5-2024-04-04": 6377, + "superwall-template-9f9f-2024-05-21": 5055, + "url-paywall-v3-3810-2024-04-04": 5715, + "video-v3-72b4-2024-04-04": 6530 }, - "preloadCompleteEventMs": 1915, + "preloadCompleteEventMs": 1399, "run": 1 }, { - "allReadyMs": 5547, + "allReadyMs": 5291, "cold": true, - "configureMs": 1472, + "configureMs": 1338, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5243, - "data-v3-0ed9-2024-04-04": 5547, - "free-trial-v3-d8d7-2024-04-04": 4839, - "inimai---open-app-copy-c50c-2024-11-28": 4180, - "localized-paywall-e901-2024-04-04": 4687, - "price-tester-1b8e-2024-04-04": 5041, - "products-v3-60c5-2024-04-04": 4585, - "superwall-template-9f9f-2024-05-21": 4382, - "url-paywall-v3-3810-2024-04-04": 4079, - "video-v3-72b4-2024-04-04": 4991 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5291, + "data-v3-0ed9-2024-04-04": 4480, + "free-trial-v3-d8d7-2024-04-04": 4632, + "inimai---open-app-copy-c50c-2024-11-28": 3513, + "localized-paywall-e901-2024-04-04": 4176, + "price-tester-1b8e-2024-04-04": 3871, + "products-v3-60c5-2024-04-04": 4784, + "superwall-template-9f9f-2024-05-21": 3715, + "url-paywall-v3-3810-2024-04-04": 4885, + "video-v3-72b4-2024-04-04": 3411 }, - "preloadCompleteEventMs": 1520, + "preloadCompleteEventMs": 795, "run": 2 }, { - "allReadyMs": 4665, + "allReadyMs": 5317, "cold": true, - "configureMs": 1605, + "configureMs": 1399, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3958, - "data-v3-0ed9-2024-04-04": 4463, - "free-trial-v3-d8d7-2024-04-04": 4615, - "inimai---open-app-copy-c50c-2024-11-28": 3603, - "localized-paywall-e901-2024-04-04": 4665, - "price-tester-1b8e-2024-04-04": 3705, - "products-v3-60c5-2024-04-04": 4109, - "superwall-template-9f9f-2024-05-21": 3502, - "url-paywall-v3-3810-2024-04-04": 4261, - "video-v3-72b4-2024-04-04": 4211 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4963, + "data-v3-0ed9-2024-04-04": 4451, + "free-trial-v3-d8d7-2024-04-04": 3996, + "inimai---open-app-copy-c50c-2024-11-28": 3438, + "localized-paywall-e901-2024-04-04": 5317, + "price-tester-1b8e-2024-04-04": 4046, + "products-v3-60c5-2024-04-04": 4198, + "superwall-template-9f9f-2024-05-21": 3692, + "url-paywall-v3-3810-2024-04-04": 5064, + "video-v3-72b4-2024-04-04": 4604 }, - "preloadCompleteEventMs": 1009, + "preloadCompleteEventMs": 529, "run": 3 }, { - "allReadyMs": 6445, + "allReadyMs": 5138, "cold": true, - "configureMs": 1276, + "configureMs": 1832, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4573, - "data-v3-0ed9-2024-04-04": 6445, - "free-trial-v3-d8d7-2024-04-04": 5562, - "inimai---open-app-copy-c50c-2024-11-28": 4319, - "localized-paywall-e901-2024-04-04": 5778, - "price-tester-1b8e-2024-04-04": 4370, - "products-v3-60c5-2024-04-04": 4725, - "superwall-template-9f9f-2024-05-21": 4167, - "url-paywall-v3-3810-2024-04-04": 4015, - "video-v3-72b4-2024-04-04": 4877 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4986, + "data-v3-0ed9-2024-04-04": 3159, + "free-trial-v3-d8d7-2024-04-04": 3666, + "inimai---open-app-copy-c50c-2024-11-28": 3514, + "localized-paywall-e901-2024-04-04": 4528, + "price-tester-1b8e-2024-04-04": 4477, + "products-v3-60c5-2024-04-04": 4784, + "superwall-template-9f9f-2024-05-21": 3362, + "url-paywall-v3-3810-2024-04-04": 4629, + "video-v3-72b4-2024-04-04": 5138 }, - "preloadCompleteEventMs": 1531, + "preloadCompleteEventMs": 649, "run": 4 }, { - "allReadyMs": 5416, + "allReadyMs": 6300, "cold": true, - "configureMs": 1607, + "configureMs": 1352, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5416, - "data-v3-0ed9-2024-04-04": 4455, - "free-trial-v3-d8d7-2024-04-04": 4201, - "inimai---open-app-copy-c50c-2024-11-28": 3340, - "localized-paywall-e901-2024-04-04": 4707, - "price-tester-1b8e-2024-04-04": 3593, - "products-v3-60c5-2024-04-04": 3898, - "superwall-template-9f9f-2024-05-21": 3441, - "url-paywall-v3-3810-2024-04-04": 3745, - "video-v3-72b4-2024-04-04": 3694 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3908, + "data-v3-0ed9-2024-04-04": 6148, + "free-trial-v3-d8d7-2024-04-04": 5894, + "inimai---open-app-copy-c50c-2024-11-28": 3401, + "localized-paywall-e901-2024-04-04": 5320, + "price-tester-1b8e-2024-04-04": 4642, + "products-v3-60c5-2024-04-04": 6300, + "superwall-template-9f9f-2024-05-21": 3249, + "url-paywall-v3-3810-2024-04-04": 3554, + "video-v3-72b4-2024-04-04": 4431 }, - "preloadCompleteEventMs": 1003, + "preloadCompleteEventMs": 1014, "run": 5 }, { - "allReadyMs": 4746, + "allReadyMs": 5293, "cold": true, - "configureMs": 1631, + "configureMs": 1382, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4493, - "data-v3-0ed9-2024-04-04": 4746, - "free-trial-v3-d8d7-2024-04-04": 4089, - "inimai---open-app-copy-c50c-2024-11-28": 3480, - "localized-paywall-e901-2024-04-04": 4139, - "price-tester-1b8e-2024-04-04": 4240, - "products-v3-60c5-2024-04-04": 3632, - "superwall-template-9f9f-2024-05-21": 3429, - "url-paywall-v3-3810-2024-04-04": 3936, - "video-v3-72b4-2024-04-04": 4291 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4736, + "data-v3-0ed9-2024-04-04": 5293, + "free-trial-v3-d8d7-2024-04-04": 4380, + "inimai---open-app-copy-c50c-2024-11-28": 3414, + "localized-paywall-e901-2024-04-04": 4888, + "price-tester-1b8e-2024-04-04": 3363, + "products-v3-60c5-2024-04-04": 4483, + "superwall-template-9f9f-2024-05-21": 3616, + "url-paywall-v3-3810-2024-04-04": 4026, + "video-v3-72b4-2024-04-04": 3873 }, - "preloadCompleteEventMs": 1045, + "preloadCompleteEventMs": 666, "run": 6 }, { - "allReadyMs": 4568, + "allReadyMs": 4994, "cold": true, - "configureMs": 1376, + "configureMs": 1832, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4163, - "data-v3-0ed9-2024-04-04": 4568, - "free-trial-v3-d8d7-2024-04-04": 3607, - "inimai---open-app-copy-c50c-2024-11-28": 3253, - "localized-paywall-e901-2024-04-04": 3708, - "price-tester-1b8e-2024-04-04": 3506, - "products-v3-60c5-2024-04-04": 3809, - "superwall-template-9f9f-2024-05-21": 3405, - "url-paywall-v3-3810-2024-04-04": 3911, - "video-v3-72b4-2024-04-04": 4012 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4129, + "data-v3-0ed9-2024-04-04": 3824, + "free-trial-v3-d8d7-2024-04-04": 4687, + "inimai---open-app-copy-c50c-2024-11-28": 3316, + "localized-paywall-e901-2024-04-04": 4792, + "price-tester-1b8e-2024-04-04": 4585, + "products-v3-60c5-2024-04-04": 3265, + "superwall-template-9f9f-2024-05-21": 4433, + "url-paywall-v3-3810-2024-04-04": 4994, + "video-v3-72b4-2024-04-04": 3520 }, - "preloadCompleteEventMs": 1085, + "preloadCompleteEventMs": 663, "run": 7 }, { - "allReadyMs": 5427, + "allReadyMs": 5850, "cold": true, - "configureMs": 1241, + "configureMs": 1780, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4312, - "data-v3-0ed9-2024-04-04": 4008, - "free-trial-v3-d8d7-2024-04-04": 4109, - "inimai---open-app-copy-c50c-2024-11-28": 3350, - "localized-paywall-e901-2024-04-04": 5427, - "price-tester-1b8e-2024-04-04": 3604, - "products-v3-60c5-2024-04-04": 3249, - "superwall-template-9f9f-2024-05-21": 4617, - "url-paywall-v3-3810-2024-04-04": 3452, - "video-v3-72b4-2024-04-04": 3553 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4227, + "data-v3-0ed9-2024-04-04": 3974, + "free-trial-v3-d8d7-2024-04-04": 4886, + "inimai---open-app-copy-c50c-2024-11-28": 4937, + "localized-paywall-e901-2024-04-04": 5850, + "price-tester-1b8e-2024-04-04": 3569, + "products-v3-60c5-2024-04-04": 4379, + "superwall-template-9f9f-2024-05-21": 4683, + "url-paywall-v3-3810-2024-04-04": 3721, + "video-v3-72b4-2024-04-04": 3316 }, - "preloadCompleteEventMs": 952, + "preloadCompleteEventMs": 671, "run": 8 }, { - "allReadyMs": 4633, + "allReadyMs": 5245, "cold": true, - "configureMs": 1463, + "configureMs": 1783, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4633, - "data-v3-0ed9-2024-04-04": 4431, - "free-trial-v3-d8d7-2024-04-04": 4026, - "inimai---open-app-copy-c50c-2024-11-28": 3318, - "localized-paywall-e901-2024-04-04": 3925, - "price-tester-1b8e-2024-04-04": 3824, - "products-v3-60c5-2024-04-04": 4229, - "superwall-template-9f9f-2024-05-21": 3470, - "url-paywall-v3-3810-2024-04-04": 3216, - "video-v3-72b4-2024-04-04": 4128 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4584, + "data-v3-0ed9-2024-04-04": 4838, + "free-trial-v3-d8d7-2024-04-04": 4068, + "inimai---open-app-copy-c50c-2024-11-28": 3511, + "localized-paywall-e901-2024-04-04": 3713, + "price-tester-1b8e-2024-04-04": 4331, + "products-v3-60c5-2024-04-04": 3916, + "superwall-template-9f9f-2024-05-21": 5245, + "url-paywall-v3-3810-2024-04-04": 4939, + "video-v3-72b4-2024-04-04": 4280 }, - "preloadCompleteEventMs": 983, + "preloadCompleteEventMs": 1015, "run": 9 }, { - "allReadyMs": 4692, + "allReadyMs": 6153, "cold": true, - "configureMs": 1656, + "configureMs": 1780, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4237, - "data-v3-0ed9-2024-04-04": 4692, - "free-trial-v3-d8d7-2024-04-04": 3578, - "inimai---open-app-copy-c50c-2024-11-28": 3426, - "localized-paywall-e901-2024-04-04": 4338, - "price-tester-1b8e-2024-04-04": 3629, - "products-v3-60c5-2024-04-04": 4035, - "superwall-template-9f9f-2024-05-21": 3375, - "url-paywall-v3-3810-2024-04-04": 3883, - "video-v3-72b4-2024-04-04": 4288 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4836, + "data-v3-0ed9-2024-04-04": 4634, + "free-trial-v3-d8d7-2024-04-04": 3873, + "inimai---open-app-copy-c50c-2024-11-28": 3265, + "localized-paywall-e901-2024-04-04": 6153, + "price-tester-1b8e-2024-04-04": 3670, + "products-v3-60c5-2024-04-04": 4228, + "superwall-template-9f9f-2024-05-21": 3417, + "url-paywall-v3-3810-2024-04-04": 3619, + "video-v3-72b4-2024-04-04": 4329 }, - "preloadCompleteEventMs": 970, + "preloadCompleteEventMs": 646, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 13.920501025868317, - "coldMeanMs": 5261.4, - "maxMs": 6475, - "meanMs": 5261.4, - "medianMs": 5081.0, - "minMs": 4568, + "coefficientOfVariationPct": 11.573251482042023, + "coldMeanMs": 5661.9, + "maxMs": 7038, + "meanMs": 5661.9, + "medianMs": 5305.0, + "minMs": 4994, "sampleCount": 10, - "stdDevMs": 732.4132409750356, + "stdDevMs": 655.2659256617372, "warmMeanMs": null }, "tier": "MID" From 532bfead1a9203dae4759ef9d366216df7f5cb91 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Jul 2026 17:14:39 +0000 Subject: [PATCH 05/12] Move transient-state reset to PaywallManager cache-hit so embedded getPaywallView re-present is covered; rewire UI test to embed The dead-buy-button fix previously lived in PaywallView.present(), which only runs on the full-screen register() path. The embedded getPaywall/getPaywallView API never calls present(), so an embedded re-present returned the same cached PaywallView with stale LoadingPurchase/presentationDidFinishPrepare and the bug reproduced there. Both paths funnel through PaywallManager.getPaywallView's cache-hit branch on a re-present, so the reset now happens there (guarded by !isPreloading). Rewire the :app: UI test to embed the paywall via PaywallBuilder instead of register(), so it exercises the embedded cache-hit reset. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01Y6NCb2BMXSXwAN1vCMFvyc --- CHANGELOG.md | 2 +- .../superapp/test/PaywallHostFragment.kt | 81 +++++++++++++++---- .../example/superapp/test/RepresentTests.kt | 48 +++++++---- .../sdk/paywall/manager/PaywallManager.kt | 8 ++ .../superwall/sdk/paywall/view/PaywallView.kt | 11 +-- .../sdk/paywall/manager/PaywallManagerTest.kt | 56 +++++++++++++ .../sdk/paywall/view/PaywallViewTest.kt | 2 +- 7 files changed, 172 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf73135b8..01677ef49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ The changelog for `Superwall`. Also see the [releases](https://github.com/superw ## Unreleased ## Fixes -- Fix a dead buy button when re-presenting a cached paywall in the same session after a purchase. Per-presentation transient state (loading spinner and presentation-prepared flag) is now reset on each new presentation, so it no longer leaks from a previous presentation that was stopped without a finishing teardown. +- Fix a dead buy button when re-presenting a cached paywall in the same session after a purchase, for both `register()` and embedded paywalls (`getPaywall`/`getPaywallView`). Per-presentation transient state (loading spinner and presentation-prepared flag) is now reset on each new presentation, so it no longer leaks from a previous presentation that was stopped without a finishing teardown. ## 2.7.21 diff --git a/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt b/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt index 755ec6c9a..4ddbbdd3c 100644 --- a/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt +++ b/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt @@ -6,42 +6,95 @@ import android.view.View import android.view.ViewGroup import android.widget.FrameLayout import androidx.fragment.app.Fragment -import com.superwall.sdk.Superwall -import com.superwall.sdk.paywall.presentation.register +import androidx.lifecycle.lifecycleScope +import com.superwall.sdk.paywall.presentation.get_paywall.builder.PaywallBuilder +import com.superwall.sdk.paywall.presentation.internal.state.PaywallResult +import com.superwall.sdk.paywall.view.PaywallView +import com.superwall.sdk.paywall.view.delegate.PaywallViewCallback +import kotlinx.coroutines.launch /** - * Minimal test-host screen that presents a paywall from a [Fragment] via - * [register] — mirroring the customer's fragment-hosted setup that surfaced the - * regression fixed in PR #434 (stale transient presentation state carried onto a - * re-presented cached paywall). The fragment is only the screen that *triggers* - * presentation; the paywall itself shows full-screen in `SuperwallPaywallActivity` - * via the `register()` path (NOT the embedded `getPaywall()` path). + * Minimal test-host screen that EMBEDS a paywall inside a [Fragment] via the public + * embed API ([PaywallBuilder] -> [com.superwall.sdk.Superwall.getPaywall]), NOT via + * [com.superwall.sdk.paywall.presentation.register]. + * + * This mirrors the customer's fragment-hosted setup that surfaced the regression + * fixed in PR #434: the embedded `getPaywallView` path returns the SAME cached + * `PaywallView` on a re-present, and before the fix the stale `LoadingPurchase` + * overlay / `presentationDidFinishPrepare` flag were never cleared on that path + * (the reset used to live in `present()`, which the embed API never calls). The fix + * moved the reset upstream into `PaywallManager.getPaywallView`'s cache-hit branch, + * so this embedded flow now exercises it. + * + * Display prep mirrors `PaywallComposable`: `PaywallBuilder.build()` internally runs + * `getPaywall()` (which triggers the cache-hit reset), `setupWith`, and + * `beforeViewCreated()`; we then add the returned view to the fragment container and + * call `onViewCreated()`. */ class PaywallHostFragment : Fragment() { // Parameterised so the whole flow keys off a single placement constant. var placement: String = RepresentTests.CONSUMABLE_REBUY_PLACEMENT + private lateinit var container: FrameLayout + private var paywallView: PaywallView? = null + + // Minimal embed delegate. The fragment host stays on screen so the test can + // re-embed the same paywall, so we intentionally do NOT finish the activity here. + private val delegate = + object : PaywallViewCallback { + override fun onFinished( + paywall: PaywallView, + result: PaywallResult, + shouldDismiss: Boolean, + ) { + // no-op: keep the host alive for re-embedding. + } + } + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?, - ): View = FrameLayout(requireContext()) + ): View = FrameLayout(requireContext()).also { this.container = it } override fun onViewCreated( view: View, savedInstanceState: Bundle?, ) { super.onViewCreated(view, savedInstanceState) - // On view-create, present the paywall exactly as the customer's fragment does. + // On view-create, embed the paywall exactly as the customer's fragment does. present() } /** - * Re-invokes the same `register()` entry point. On the second call the SDK reuses - * the CACHED `PaywallView`, which is precisely the path where the stale - * `LoadingPurchase` overlay used to swallow the buy tap before PR #434. + * Obtains the embedded paywall via the public [PaywallBuilder]/`getPaywall` API and + * attaches it into the fragment's container. On the second call the SDK reuses the + * CACHED `PaywallView` (via `PaywallManager.getPaywallView`'s cache-hit branch), + * which is precisely the path whose stale `LoadingPurchase` overlay used to swallow + * the buy tap before PR #434. */ fun present() { - Superwall.instance.register(placement = placement) + viewLifecycleOwner.lifecycleScope.launch { + embedPaywall() + } + } + + private suspend fun embedPaywall() { + // Detach any previously-embedded instance before re-embedding the (cached) view. + paywallView?.let { (it.parent as? ViewGroup)?.removeView(it) } + + PaywallBuilder(placement) + .delegate(delegate) + .activity(requireActivity()) + .build() + .onSuccess { view -> + paywallView = view + // `build()` already ran getPaywall() (cache-hit reset) + beforeViewCreated(); + // ensure the view isn't still parented, attach it, then drive onViewCreated() + // as PaywallComposable does. + (view.parent as? ViewGroup)?.removeView(view) + container.addView(view) + view.onViewCreated() + } } } diff --git a/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt b/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt index b7b9f5b91..5bb5e381e 100644 --- a/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt +++ b/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt @@ -9,7 +9,6 @@ import androidx.test.uiautomator.UiDevice import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import com.example.superapp.utils.awaitUntilWebviewAppears -import com.example.superapp.utils.awaitUntilWebviewDisappears import com.example.superapp.utils.clickButtonWith import com.superwall.sdk.Superwall import com.superwall.sdk.analytics.superwall.SuperwallEvent @@ -45,12 +44,15 @@ import kotlin.time.Duration.Companion.seconds * Repro: after a consumable purchase, re-presenting the SAME paywall in one app * session left the buy button dead — a stale `LoadingPurchase` loading overlay (and * stale `presentationDidFinishPrepare`) carried onto the re-presented CACHED paywall - * and swallowed the tap. The fix has `PaywallView.present()` call - * `resetTransientPresentationState()` first. + * and swallowed the tap. The fix resets that transient state upstream in + * `PaywallManager.getPaywallView`'s cache-hit branch, so BOTH the full-screen + * `register()` path and the embedded `getPaywall`/`getPaywallView` path are covered. * - * These tests drive the full-screen `register()` flow (the fixed path) from a - * fragment-hosted screen ([PaywallHostFragment]), purchase via Superwall test mode - * (billing is unavailable on CI emulators), then re-present and re-tap buy. + * These tests drive the EMBEDDED path — the one the customer hit, and the one that was + * previously unfixed because the embed API never calls `present()`. A fragment + * ([PaywallHostFragment]) embeds the paywall via `PaywallBuilder`/`getPaywall`, + * purchases via Superwall test mode (billing is unavailable on CI emulators), then + * re-obtains/re-attaches the embedded paywall and re-taps buy. * * Assertions are event/state based (no golden screenshots) so they can be validated * on FTL without locally generated baseline images. @@ -117,11 +119,12 @@ class RepresentTests { } /** - * Test 1 — repro + fix, end-to-end. + * Test 1 — repro + fix, end-to-end (embedded path). * - * Present → buy → drawer → Purchased → dismiss → re-present the SAME placement → + * Embed → buy → drawer → Confirm → complete → re-embed the SAME placement → * tap buy AGAIN. Pre-fix the second tap is dead (stale overlay swallows it) so the - * drawer never reappears; post-fix the purchase flow is re-invoked. + * drawer never reappears; post-fix the purchase flow is re-invoked because the + * cache-hit reset in `PaywallManager` cleared the stale `LoadingPurchase` overlay. */ @Test fun test_represent_after_consumable_purchase_reinvokes_purchase() = @@ -130,7 +133,7 @@ class RepresentTests { val scenario = launchFragmentInContainer() - // First presentation. + // First embedded presentation. dismissTestModeActivationModalIfPresent() assertTrue("First paywall never appeared", awaitUntilWebviewAppears()) delay(1.seconds) @@ -144,10 +147,13 @@ class RepresentTests { val firstComplete = awaitEventAsync { it is SuperwallEvent.TransactionComplete } clickButtonWith(CONFIRM_PURCHASE_TEXT) assertNotNull("First purchase never completed", firstComplete.await()) - awaitUntilWebviewDisappears() + // The embedded paywall isn't dismissed (no full-screen activity to finish); + // just wait for the test-mode drawer to close so the re-tap detects a FRESH drawer. + awaitTextDisappears(CONFIRM_PURCHASE_TEXT) delay(1.seconds) - // Re-present the SAME placement via the same fragment (reuses cached PaywallView). + // Re-obtain/re-attach the SAME placement via the embedded API (reuses the cached + // PaywallView through PaywallManager.getPaywallView's cache-hit reset). scenario.onFragment { it.present() } dismissTestModeActivationModalIfPresent() assertTrue("Re-presented paywall never appeared", awaitUntilWebviewAppears()) @@ -165,7 +171,7 @@ class RepresentTests { /** * Test 2 — public-API state assertion (analog of the internal-reset unit test). * - * After purchasing and re-presenting, the re-presented paywall must NOT be stuck in + * After purchasing and re-embedding, the re-presented paywall must NOT be stuck in * `LoadingPurchase` (which is what showed the tap-swallowing overlay). `:app:` can't * see the internal reset API, so we assert via the public `loadingState` getter. */ @@ -189,10 +195,10 @@ class RepresentTests { val complete = awaitEventAsync { it is SuperwallEvent.TransactionComplete } clickButtonWith(CONFIRM_PURCHASE_TEXT) assertNotNull("Purchase never completed", complete.await()) - awaitUntilWebviewDisappears() + awaitTextDisappears(CONFIRM_PURCHASE_TEXT) delay(1.seconds) - // Re-present the cached paywall. + // Re-obtain/re-attach the cached embedded paywall (exercises the cache-hit reset). scenario.onFragment { it.present() } dismissTestModeActivationModalIfPresent() assertTrue("Re-presented paywall never appeared", awaitUntilWebviewAppears()) @@ -237,6 +243,18 @@ class RepresentTests { timeoutMs: Long = UI_TIMEOUT_MS, ): Boolean = device().wait(Until.findObject(By.textContains(text)), timeoutMs) != null + /** + * Waits until [text] is no longer on screen (best-effort, bounded by [timeoutMs]). + * Used after confirming a test-mode purchase so the subsequent buy re-tap detects a + * FRESH drawer rather than the lingering previous one. The embedded paywall itself is + * never dismissed (there's no full-screen activity to finish), so we can't wait on the + * webview disappearing. + */ + private fun awaitTextDisappears( + text: String, + timeoutMs: Long = UI_TIMEOUT_MS, + ): Boolean = device().wait(Until.gone(By.textContains(text)), timeoutMs) ?: false + /** * Subscribe to [events] BEFORE the triggering action (avoids the emit/collect race), * returning a Deferred that resolves to the matching event or null on timeout. diff --git a/superwall/src/main/java/com/superwall/sdk/paywall/manager/PaywallManager.kt b/superwall/src/main/java/com/superwall/sdk/paywall/manager/PaywallManager.kt index 33dbb0a1f..59f8d5313 100644 --- a/superwall/src/main/java/com/superwall/sdk/paywall/manager/PaywallManager.kt +++ b/superwall/src/main/java/com/superwall/sdk/paywall/manager/PaywallManager.kt @@ -80,6 +80,14 @@ class PaywallManager( if (!isPreloading) { view.callback = delegate view.updateState(PaywallViewState.Updates.MergePaywall(it)) + // A cached view is being handed back for a new presentation. Clear any + // per-presentation transient state (a stale LoadingPurchase/ManualLoading + // spinner that swallows taps, and a stale presentationDidFinishPrepare) + // leaked by a previous presentation that stopped without a finishing + // teardown. This covers both the register()/full-screen path and the + // embedded getPaywallView/getPaywall path, which both funnel through here. + // Guarded by !isPreloading so preloading never resets a live view. + view.resetTransientPresentationState() } return@mapAsync view } diff --git a/superwall/src/main/java/com/superwall/sdk/paywall/view/PaywallView.kt b/superwall/src/main/java/com/superwall/sdk/paywall/view/PaywallView.kt index 8440f61e6..af9f277d8 100644 --- a/superwall/src/main/java/com/superwall/sdk/paywall/view/PaywallView.kt +++ b/superwall/src/main/java/com/superwall/sdk/paywall/view/PaywallView.kt @@ -299,7 +299,6 @@ class PaywallView( paywallStatePublisher: MutableSharedFlow, completion: (Boolean) -> Unit, ) { - resetTransientPresentationState() webView.attach(this) cache?.acquireLoadingView()?.let { setupLoading(it) @@ -483,10 +482,12 @@ class PaywallView( // onStop, which since #431 intentionally no longer tears the view down. That leaks // per-presentation transient state into the next present: a stale LoadingPurchase/ManualLoading // spinner swallows taps, and a stale presentationDidFinishPrepare makes onViewCreated() - // early-return without re-wiring the view. Resetting it at the start of present() gives every - // new presentation a clean slate. Safe because present() only runs for a genuinely new - // presentation - never on resume-same-instance (that goes through onResume -> onViewCreated) - // nor during an in-flight purchase. + // early-return without re-wiring the view. Called from PaywallManager.getPaywallView's cache-hit + // branch when a cached view is handed back for a new presentation, so every new presentation - + // full-screen register() and embedded getPaywallView/getPaywall alike - gets a clean slate. + // Safe because that branch only runs for a genuinely new presentation request - never on + // resume-same-instance (that goes through onResume -> onViewCreated) nor during an in-flight + // purchase. internal fun resetTransientPresentationState() { if (loadingState is PaywallLoadingState.LoadingPurchase || loadingState is PaywallLoadingState.ManualLoading diff --git a/superwall/src/test/java/com/superwall/sdk/paywall/manager/PaywallManagerTest.kt b/superwall/src/test/java/com/superwall/sdk/paywall/manager/PaywallManagerTest.kt index 5e5a7fd73..72ea28d8c 100644 --- a/superwall/src/test/java/com/superwall/sdk/paywall/manager/PaywallManagerTest.kt +++ b/superwall/src/test/java/com/superwall/sdk/paywall/manager/PaywallManagerTest.kt @@ -159,6 +159,62 @@ class PaywallManagerTest { verify { mockView.updateState(any()) } } + @Test + fun test_getPaywallView_resetsTransientState_onCacheHitForNewPresentation() = + runTest { + // A cached view handed back for a new presentation (register() or embedded + // getPaywallView/getPaywall) must have its per-presentation transient state cleared + // so a stale LoadingPurchase spinner / presentationDidFinishPrepare flag from a + // previous non-finishing stop can't dead-button the buy button on re-present. + val paywall = + mockk { + every { identifier } returns "test_paywall" + } + val request = + mockk { + every { isDebuggerLaunched } returns false + } + val mockView = + mockk(relaxed = true) { + every { loadingState } returns PaywallLoadingState.Unknown + } + val delegate = mockk() + + coEvery { paywallRequestManager.getPaywall(any(), any()) } returns Either.Success(paywall) + every { cache.getPaywallView(any()) } returns mockView + every { mockView.callback = any() } just Runs + every { mockView.updateState(any()) } just Runs + every { mockView.resetTransientPresentationState() } just Runs + + paywallManager.getPaywallView(request, isForPresentation = true, isPreloading = false, delegate) + + verify { mockView.resetTransientPresentationState() } + } + + @Test + fun test_getPaywallView_doesNotResetTransientState_whenPreloading() = + runTest { + // Preloading must never reset a (possibly live) cached view's transient state. + val paywall = + mockk { + every { identifier } returns "test_paywall" + } + val request = + mockk { + every { isDebuggerLaunched } returns false + } + val mockView = mockk(relaxed = true) + + coEvery { paywallRequestManager.getPaywall(any(), any()) } returns Either.Success(paywall) + every { cache.getPaywallView(any()) } returns mockView + + paywallManager.getPaywallView(request, isForPresentation = false, isPreloading = true, null) + + verify(exactly = 0) { mockView.resetTransientPresentationState() } + verify(exactly = 0) { mockView.callback = any() } + verify(exactly = 0) { mockView.updateState(any()) } + } + @Test fun test_getPaywallView_skipsCache_whenDebuggerLaunched() = runTest { diff --git a/superwall/src/test/java/com/superwall/sdk/paywall/view/PaywallViewTest.kt b/superwall/src/test/java/com/superwall/sdk/paywall/view/PaywallViewTest.kt index 1486d565f..6a95ac06d 100644 --- a/superwall/src/test/java/com/superwall/sdk/paywall/view/PaywallViewTest.kt +++ b/superwall/src/test/java/com/superwall/sdk/paywall/view/PaywallViewTest.kt @@ -951,7 +951,7 @@ class PaywallViewTest { view.state.presentationDidFinishPrepare, ) - When("the cached view is re-presented (present() resets transient state)") { + When("the cached view is re-presented (PaywallManager resets transient state on cache-hit)") { view.resetTransientPresentationState() advanceUntilIdle() From 67440bef6244ab2ccc7ac0f6e441d9530b85c162 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 14 Jul 2026 17:29:44 +0000 Subject: [PATCH 06/12] Update paywall preload benchmark report [skip ci] --- .benchmark/REPORT.md | 6 +- .../results/preload-benchmark-high.json | 274 +++++++++--------- .benchmark/results/preload-benchmark-low.json | 274 +++++++++--------- .benchmark/results/preload-benchmark-mid.json | 274 +++++++++--------- 4 files changed, 414 insertions(+), 414 deletions(-) diff --git a/.benchmark/REPORT.md b/.benchmark/REPORT.md index a056bb0ab..42d1fd94e 100644 --- a/.benchmark/REPORT.md +++ b/.benchmark/REPORT.md @@ -4,9 +4,9 @@ Time from `preloadAllPaywalls()` until every paywall reaches `PaywallLoadingStat | Tier | Paywalls | Mean | Baseline | Δ | Limit | Cold mean | Warm mean | Median | StdDev | CV | Samples | Status | |------|----------|------|----------|---|-------|-----------|-----------|--------|--------|----|---------|--------| -| LOW | 10 | 6.61s | 6.34s | +4.3% | +30% | 8.78s | — | 6.61s | 4.90s | 55.8% | 10 (10×1) | ✅ OK | -| MID | 10 | 5.30s | 8.78s | -39.5% | +15% | 5.66s | — | 5.30s | 655ms | 11.6% | 10 (10×1) | 🟢 improved | -| HIGH | 10 | 7.08s | 6.72s | +5.4% | +20% | 8.26s | — | 7.08s | 2.70s | 32.7% | 10 (10×1) | ✅ OK | +| LOW | 10 | 7.28s | 6.34s | +14.9% | +30% | 8.23s | — | 7.28s | 2.64s | 32.1% | 10 (10×1) | ✅ OK | +| MID | 10 | 5.34s | 8.78s | -39.1% | +15% | 6.25s | — | 5.34s | 2.22s | 35.6% | 10 (10×1) | 🟢 improved | +| HIGH | 10 | 4.38s | 6.72s | -34.8% | +20% | 4.65s | — | 4.38s | 820ms | 17.6% | 10 (10×1) | 🟢 improved | ### Devices diff --git a/.benchmark/results/preload-benchmark-high.json b/.benchmark/results/preload-benchmark-high.json index 50061e36d..380b4f000 100644 --- a/.benchmark/results/preload-benchmark-high.json +++ b/.benchmark/results/preload-benchmark-high.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 13569, + "allReadyMs": 5844, "cold": true, - "configureMs": 3147, + "configureMs": 2356, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 13569, - "data-v3-0ed9-2024-04-04": 12297, - "free-trial-v3-d8d7-2024-04-04": 13163, - "inimai---open-app-copy-c50c-2024-11-28": 11276, - "localized-paywall-e901-2024-04-04": 12450, - "price-tester-1b8e-2024-04-04": 11738, - "products-v3-60c5-2024-04-04": 12908, - "superwall-template-9f9f-2024-05-21": 11073, - "url-paywall-v3-3810-2024-04-04": 12704, - "video-v3-72b4-2024-04-04": 11942 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5844, + "data-v3-0ed9-2024-04-04": 5540, + "free-trial-v3-d8d7-2024-04-04": 4624, + "inimai---open-app-copy-c50c-2024-11-28": 4117, + "localized-paywall-e901-2024-04-04": 4980, + "price-tester-1b8e-2024-04-04": 5182, + "products-v3-60c5-2024-04-04": 5287, + "superwall-template-9f9f-2024-05-21": 4320, + "url-paywall-v3-3810-2024-04-04": 5132, + "video-v3-72b4-2024-04-04": 4472 }, - "preloadCompleteEventMs": 6196, + "preloadCompleteEventMs": 996, "run": 1 }, { - "allReadyMs": 7186, + "allReadyMs": 4165, "cold": true, - "configureMs": 1665, + "configureMs": 831, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6576, - "data-v3-0ed9-2024-04-04": 6932, - "free-trial-v3-d8d7-2024-04-04": 5610, - "inimai---open-app-copy-c50c-2024-11-28": 4625, - "localized-paywall-e901-2024-04-04": 5243, - "price-tester-1b8e-2024-04-04": 7084, - "products-v3-60c5-2024-04-04": 5814, - "superwall-template-9f9f-2024-05-21": 4988, - "url-paywall-v3-3810-2024-04-04": 4523, - "video-v3-72b4-2024-04-04": 7186 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4165, + "data-v3-0ed9-2024-04-04": 3506, + "free-trial-v3-d8d7-2024-04-04": 3861, + "inimai---open-app-copy-c50c-2024-11-28": 2796, + "localized-paywall-e901-2024-04-04": 3912, + "price-tester-1b8e-2024-04-04": 2695, + "products-v3-60c5-2024-04-04": 3658, + "superwall-template-9f9f-2024-05-21": 2999, + "url-paywall-v3-3810-2024-04-04": 3303, + "video-v3-72b4-2024-04-04": 3202 }, - "preloadCompleteEventMs": 1141, + "preloadCompleteEventMs": 945, "run": 2 }, { - "allReadyMs": 11772, + "allReadyMs": 3674, "cold": true, - "configureMs": 2299, + "configureMs": 1324, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9572, - "data-v3-0ed9-2024-04-04": 11772, - "free-trial-v3-d8d7-2024-04-04": 10753, - "inimai---open-app-copy-c50c-2024-11-28": 7406, - "localized-paywall-e901-2024-04-04": 10295, - "price-tester-1b8e-2024-04-04": 7142, - "products-v3-60c5-2024-04-04": 11213, - "superwall-template-9f9f-2024-05-21": 7968, - "url-paywall-v3-3810-2024-04-04": 8698, - "video-v3-72b4-2024-04-04": 10956 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3319, + "data-v3-0ed9-2024-04-04": 3674, + "free-trial-v3-d8d7-2024-04-04": 2762, + "inimai---open-app-copy-c50c-2024-11-28": 2353, + "localized-paywall-e901-2024-04-04": 2813, + "price-tester-1b8e-2024-04-04": 2965, + "products-v3-60c5-2024-04-04": 3066, + "superwall-template-9f9f-2024-05-21": 2556, + "url-paywall-v3-3810-2024-04-04": 3116, + "video-v3-72b4-2024-04-04": 3420 }, - "preloadCompleteEventMs": 1290, + "preloadCompleteEventMs": 535, "run": 3 }, { - "allReadyMs": 10521, + "allReadyMs": 3966, "cold": true, - "configureMs": 1790, + "configureMs": 2582, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 10521, - "data-v3-0ed9-2024-04-04": 10113, - "free-trial-v3-d8d7-2024-04-04": 8561, - "inimai---open-app-copy-c50c-2024-11-28": 7234, - "localized-paywall-e901-2024-04-04": 6724, - "price-tester-1b8e-2024-04-04": 9182, - "products-v3-60c5-2024-04-04": 8099, - "superwall-template-9f9f-2024-05-21": 7743, - "url-paywall-v3-3810-2024-04-04": 7029, - "video-v3-72b4-2024-04-04": 9551 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3511, + "data-v3-0ed9-2024-04-04": 3257, + "free-trial-v3-d8d7-2024-04-04": 2901, + "inimai---open-app-copy-c50c-2024-11-28": 2596, + "localized-paywall-e901-2024-04-04": 3966, + "price-tester-1b8e-2024-04-04": 3562, + "products-v3-60c5-2024-04-04": 2953, + "superwall-template-9f9f-2024-05-21": 3815, + "url-paywall-v3-3810-2024-04-04": 3054, + "video-v3-72b4-2024-04-04": 2647 }, - "preloadCompleteEventMs": 1485, + "preloadCompleteEventMs": 599, "run": 4 }, { - "allReadyMs": 6434, + "allReadyMs": 4534, "cold": true, - "configureMs": 1502, + "configureMs": 1416, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5111, - "data-v3-0ed9-2024-04-04": 6434, - "free-trial-v3-d8d7-2024-04-04": 5314, - "inimai---open-app-copy-c50c-2024-11-28": 3733, - "localized-paywall-e901-2024-04-04": 4393, - "price-tester-1b8e-2024-04-04": 4139, - "products-v3-60c5-2024-04-04": 5467, - "superwall-template-9f9f-2024-05-21": 3987, - "url-paywall-v3-3810-2024-04-04": 3631, - "video-v3-72b4-2024-04-04": 4292 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4534, + "data-v3-0ed9-2024-04-04": 4382, + "free-trial-v3-d8d7-2024-04-04": 3924, + "inimai---open-app-copy-c50c-2024-11-28": 3516, + "localized-paywall-e901-2024-04-04": 3772, + "price-tester-1b8e-2024-04-04": 3722, + "products-v3-60c5-2024-04-04": 4129, + "superwall-template-9f9f-2024-05-21": 3465, + "url-paywall-v3-3810-2024-04-04": 4026, + "video-v3-72b4-2024-04-04": 3671 }, - "preloadCompleteEventMs": 743, + "preloadCompleteEventMs": 1016, "run": 5 }, { - "allReadyMs": 5807, + "allReadyMs": 4815, "cold": true, - "configureMs": 2174, + "configureMs": 1620, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4075, - "data-v3-0ed9-2024-04-04": 4941, - "free-trial-v3-d8d7-2024-04-04": 3667, - "inimai---open-app-copy-c50c-2024-11-28": 5807, - "localized-paywall-e901-2024-04-04": 3464, - "price-tester-1b8e-2024-04-04": 3363, - "products-v3-60c5-2024-04-04": 4483, - "superwall-template-9f9f-2024-05-21": 3210, - "url-paywall-v3-3810-2024-04-04": 3769, - "video-v3-72b4-2024-04-04": 4636 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4511, + "data-v3-0ed9-2024-04-04": 4309, + "free-trial-v3-d8d7-2024-04-04": 3649, + "inimai---open-app-copy-c50c-2024-11-28": 3487, + "localized-paywall-e901-2024-04-04": 4815, + "price-tester-1b8e-2024-04-04": 4056, + "products-v3-60c5-2024-04-04": 3801, + "superwall-template-9f9f-2024-05-21": 3436, + "url-paywall-v3-3810-2024-04-04": 3284, + "video-v3-72b4-2024-04-04": 3700 }, - "preloadCompleteEventMs": 722, + "preloadCompleteEventMs": 911, "run": 6 }, { - "allReadyMs": 7678, + "allReadyMs": 3931, "cold": true, - "configureMs": 1737, + "configureMs": 1167, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5607, - "data-v3-0ed9-2024-04-04": 6122, - "free-trial-v3-d8d7-2024-04-04": 5100, - "inimai---open-app-copy-c50c-2024-11-28": 4743, - "localized-paywall-e901-2024-04-04": 4896, - "price-tester-1b8e-2024-04-04": 4436, - "products-v3-60c5-2024-04-04": 5252, - "superwall-template-9f9f-2024-05-21": 7678, - "url-paywall-v3-3810-2024-04-04": 3978, - "video-v3-72b4-2024-04-04": 4385 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3523, + "data-v3-0ed9-2024-04-04": 3931, + "free-trial-v3-d8d7-2024-04-04": 2914, + "inimai---open-app-copy-c50c-2024-11-28": 2711, + "localized-paywall-e901-2024-04-04": 2965, + "price-tester-1b8e-2024-04-04": 3219, + "products-v3-60c5-2024-04-04": 3168, + "superwall-template-9f9f-2024-05-21": 2609, + "url-paywall-v3-3810-2024-04-04": 2457, + "video-v3-72b4-2024-04-04": 3321 }, - "preloadCompleteEventMs": 1026, + "preloadCompleteEventMs": 610, "run": 7 }, { - "allReadyMs": 6978, + "allReadyMs": 4226, "cold": true, - "configureMs": 1481, + "configureMs": 1624, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5606, - "data-v3-0ed9-2024-04-04": 4845, - "free-trial-v3-d8d7-2024-04-04": 4081, - "inimai---open-app-copy-c50c-2024-11-28": 6978, - "localized-paywall-e901-2024-04-04": 4946, - "price-tester-1b8e-2024-04-04": 4285, - "products-v3-60c5-2024-04-04": 4388, - "superwall-template-9f9f-2024-05-21": 5200, - "url-paywall-v3-3810-2024-04-04": 4183, - "video-v3-72b4-2024-04-04": 3725 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4226, + "data-v3-0ed9-2024-04-04": 4073, + "free-trial-v3-d8d7-2024-04-04": 3263, + "inimai---open-app-copy-c50c-2024-11-28": 3061, + "localized-paywall-e901-2024-04-04": 3770, + "price-tester-1b8e-2024-04-04": 3263, + "products-v3-60c5-2024-04-04": 3365, + "superwall-template-9f9f-2024-05-21": 3567, + "url-paywall-v3-3810-2024-04-04": 2959, + "video-v3-72b4-2024-04-04": 3871 }, - "preloadCompleteEventMs": 1064, + "preloadCompleteEventMs": 1238, "run": 8 }, { - "allReadyMs": 6181, + "allReadyMs": 5893, "cold": true, - "configureMs": 1868, + "configureMs": 1568, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3789, - "data-v3-0ed9-2024-04-04": 5672, - "free-trial-v3-d8d7-2024-04-04": 4961, - "inimai---open-app-copy-c50c-2024-11-28": 4248, - "localized-paywall-e901-2024-04-04": 6181, - "price-tester-1b8e-2024-04-04": 5368, - "products-v3-60c5-2024-04-04": 5266, - "superwall-template-9f9f-2024-05-21": 4045, - "url-paywall-v3-3810-2024-04-04": 5978, - "video-v3-72b4-2024-04-04": 5113 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4727, + "data-v3-0ed9-2024-04-04": 4575, + "free-trial-v3-d8d7-2024-04-04": 3814, + "inimai---open-app-copy-c50c-2024-11-28": 3712, + "localized-paywall-e901-2024-04-04": 5893, + "price-tester-1b8e-2024-04-04": 4270, + "products-v3-60c5-2024-04-04": 4372, + "superwall-template-9f9f-2024-05-21": 3610, + "url-paywall-v3-3810-2024-04-04": 4220, + "video-v3-72b4-2024-04-04": 3458 }, - "preloadCompleteEventMs": 746, + "preloadCompleteEventMs": 925, "run": 9 }, { - "allReadyMs": 6449, + "allReadyMs": 5482, "cold": true, - "configureMs": 1827, + "configureMs": 1648, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4295, - "data-v3-0ed9-2024-04-04": 5121, - "free-trial-v3-d8d7-2024-04-04": 4613, - "inimai---open-app-copy-c50c-2024-11-28": 5273, - "localized-paywall-e901-2024-04-04": 6195, - "price-tester-1b8e-2024-04-04": 4714, - "products-v3-60c5-2024-04-04": 6449, - "superwall-template-9f9f-2024-05-21": 6043, - "url-paywall-v3-3810-2024-04-04": 4816, - "video-v3-72b4-2024-04-04": 5375 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4008, + "data-v3-0ed9-2024-04-04": 4261, + "free-trial-v3-d8d7-2024-04-04": 4362, + "inimai---open-app-copy-c50c-2024-11-28": 3653, + "localized-paywall-e901-2024-04-04": 5482, + "price-tester-1b8e-2024-04-04": 3146, + "products-v3-60c5-2024-04-04": 3856, + "superwall-template-9f9f-2024-05-21": 3551, + "url-paywall-v3-3810-2024-04-04": 3754, + "video-v3-72b4-2024-04-04": 4620 }, - "preloadCompleteEventMs": 1244, + "preloadCompleteEventMs": 1031, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 32.72515887530627, - "coldMeanMs": 8257.5, - "maxMs": 13569, - "meanMs": 8257.5, - "medianMs": 7082.0, - "minMs": 5807, + "coefficientOfVariationPct": 17.629290131541918, + "coldMeanMs": 4653.0, + "maxMs": 5893, + "meanMs": 4653.0, + "medianMs": 4380.0, + "minMs": 3674, "sampleCount": 10, - "stdDevMs": 2702.279994128415, + "stdDevMs": 820.2908698206454, "warmMeanMs": null }, "tier": "HIGH" diff --git a/.benchmark/results/preload-benchmark-low.json b/.benchmark/results/preload-benchmark-low.json index cc5a2bc32..5292e1b80 100644 --- a/.benchmark/results/preload-benchmark-low.json +++ b/.benchmark/results/preload-benchmark-low.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 21525, + "allReadyMs": 13052, "cold": true, - "configureMs": 11939, + "configureMs": 2852, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 17348, - "data-v3-0ed9-2024-04-04": 17804, - "free-trial-v3-d8d7-2024-04-04": 21525, - "inimai---open-app-copy-c50c-2024-11-28": 18629, - "localized-paywall-e901-2024-04-04": 18897, - "price-tester-1b8e-2024-04-04": 15046, - "products-v3-60c5-2024-04-04": 15762, - "superwall-template-9f9f-2024-05-21": 20910, - "url-paywall-v3-3810-2024-04-04": 13476, - "video-v3-72b4-2024-04-04": 14728 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 11272, + "data-v3-0ed9-2024-04-04": 12841, + "free-trial-v3-d8d7-2024-04-04": 11797, + "inimai---open-app-copy-c50c-2024-11-28": 9949, + "localized-paywall-e901-2024-04-04": 13052, + "price-tester-1b8e-2024-04-04": 10762, + "products-v3-60c5-2024-04-04": 9284, + "superwall-template-9f9f-2024-05-21": 9640, + "url-paywall-v3-3810-2024-04-04": 12003, + "video-v3-72b4-2024-04-04": 11476 }, - "preloadCompleteEventMs": 2740, + "preloadCompleteEventMs": 2305, "run": 1 }, { - "allReadyMs": 8910, + "allReadyMs": 7340, "cold": true, - "configureMs": 2011, + "configureMs": 1556, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 8910, - "data-v3-0ed9-2024-04-04": 8148, - "free-trial-v3-d8d7-2024-04-04": 6089, - "inimai---open-app-copy-c50c-2024-11-28": 5021, - "localized-paywall-e901-2024-04-04": 7318, - "price-tester-1b8e-2024-04-04": 6600, - "products-v3-60c5-2024-04-04": 6957, - "superwall-template-9f9f-2024-05-21": 5726, - "url-paywall-v3-3810-2024-04-04": 7571, - "video-v3-72b4-2024-04-04": 6395 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7035, + "data-v3-0ed9-2024-04-04": 6732, + "free-trial-v3-d8d7-2024-04-04": 7340, + "inimai---open-app-copy-c50c-2024-11-28": 4654, + "localized-paywall-e901-2024-04-04": 5821, + "price-tester-1b8e-2024-04-04": 4501, + "products-v3-60c5-2024-04-04": 5668, + "superwall-template-9f9f-2024-05-21": 5009, + "url-paywall-v3-3810-2024-04-04": 5465, + "video-v3-72b4-2024-04-04": 5262 }, - "preloadCompleteEventMs": 1070, + "preloadCompleteEventMs": 1084, "run": 2 }, { - "allReadyMs": 11693, + "allReadyMs": 12325, "cold": true, - "configureMs": 1674, + "configureMs": 1582, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 10967, - "data-v3-0ed9-2024-04-04": 11490, - "free-trial-v3-d8d7-2024-04-04": 10552, - "inimai---open-app-copy-c50c-2024-11-28": 8812, - "localized-paywall-e901-2024-04-04": 9115, - "price-tester-1b8e-2024-04-04": 10096, - "products-v3-60c5-2024-04-04": 9420, - "superwall-template-9f9f-2024-05-21": 8609, - "url-paywall-v3-3810-2024-04-04": 11693, - "video-v3-72b4-2024-04-04": 11186 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9726, + "data-v3-0ed9-2024-04-04": 10954, + "free-trial-v3-d8d7-2024-04-04": 10081, + "inimai---open-app-copy-c50c-2024-11-28": 9827, + "localized-paywall-e901-2024-04-04": 10235, + "price-tester-1b8e-2024-04-04": 11006, + "products-v3-60c5-2024-04-04": 11208, + "superwall-template-9f9f-2024-05-21": 9220, + "url-paywall-v3-3810-2024-04-04": 12120, + "video-v3-72b4-2024-04-04": 12325 }, - "preloadCompleteEventMs": 2510, + "preloadCompleteEventMs": 2207, "run": 3 }, { - "allReadyMs": 9138, + "allReadyMs": 10058, "cold": true, - "configureMs": 1540, + "configureMs": 2338, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6553, - "data-v3-0ed9-2024-04-04": 9138, - "free-trial-v3-d8d7-2024-04-04": 7518, - "inimai---open-app-copy-c50c-2024-11-28": 7214, - "localized-paywall-e901-2024-04-04": 8126, - "price-tester-1b8e-2024-04-04": 7619, - "products-v3-60c5-2024-04-04": 7873, - "superwall-template-9f9f-2024-05-21": 6910, - "url-paywall-v3-3810-2024-04-04": 8075, - "video-v3-72b4-2024-04-04": 7771 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 8184, + "data-v3-0ed9-2024-04-04": 7728, + "free-trial-v3-d8d7-2024-04-04": 7322, + "inimai---open-app-copy-c50c-2024-11-28": 6143, + "localized-paywall-e901-2024-04-04": 10058, + "price-tester-1b8e-2024-04-04": 7424, + "products-v3-60c5-2024-04-04": 7880, + "superwall-template-9f9f-2024-05-21": 6654, + "url-paywall-v3-3810-2024-04-04": 6963, + "video-v3-72b4-2024-04-04": 5686 }, - "preloadCompleteEventMs": 1447, + "preloadCompleteEventMs": 1289, "run": 4 }, { - "allReadyMs": 6171, + "allReadyMs": 6048, "cold": true, - "configureMs": 1538, + "configureMs": 1858, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5463, - "data-v3-0ed9-2024-04-04": 6171, - "free-trial-v3-d8d7-2024-04-04": 5210, - "inimai---open-app-copy-c50c-2024-11-28": 4043, - "localized-paywall-e901-2024-04-04": 5007, - "price-tester-1b8e-2024-04-04": 4347, - "products-v3-60c5-2024-04-04": 5666, - "superwall-template-9f9f-2024-05-21": 3942, - "url-paywall-v3-3810-2024-04-04": 4246, - "video-v3-72b4-2024-04-04": 4856 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5490, + "data-v3-0ed9-2024-04-04": 6048, + "free-trial-v3-d8d7-2024-04-04": 4626, + "inimai---open-app-copy-c50c-2024-11-28": 4070, + "localized-paywall-e901-2024-04-04": 4677, + "price-tester-1b8e-2024-04-04": 4879, + "products-v3-60c5-2024-04-04": 5187, + "superwall-template-9f9f-2024-05-21": 4272, + "url-paywall-v3-3810-2024-04-04": 3868, + "video-v3-72b4-2024-04-04": 4983 }, - "preloadCompleteEventMs": 695, + "preloadCompleteEventMs": 1541, "run": 5 }, { - "allReadyMs": 6104, + "allReadyMs": 7229, "cold": true, - "configureMs": 1706, + "configureMs": 1624, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5799, - "data-v3-0ed9-2024-04-04": 6104, - "free-trial-v3-d8d7-2024-04-04": 4988, - "inimai---open-app-copy-c50c-2024-11-28": 4276, - "localized-paywall-e901-2024-04-04": 4731, - "price-tester-1b8e-2024-04-04": 5090, - "products-v3-60c5-2024-04-04": 5242, - "superwall-template-9f9f-2024-05-21": 4478, - "url-paywall-v3-3810-2024-04-04": 4123, - "video-v3-72b4-2024-04-04": 5394 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5914, + "data-v3-0ed9-2024-04-04": 5543, + "free-trial-v3-d8d7-2024-04-04": 7128, + "inimai---open-app-copy-c50c-2024-11-28": 4176, + "localized-paywall-e901-2024-04-04": 7229, + "price-tester-1b8e-2024-04-04": 4530, + "products-v3-60c5-2024-04-04": 4987, + "superwall-template-9f9f-2024-05-21": 4378, + "url-paywall-v3-3810-2024-04-04": 4631, + "video-v3-72b4-2024-04-04": 4784 }, - "preloadCompleteEventMs": 1351, + "preloadCompleteEventMs": 1212, "run": 6 }, { - "allReadyMs": 7054, + "allReadyMs": 6941, "cold": true, - "configureMs": 1835, + "configureMs": 1878, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6540, - "data-v3-0ed9-2024-04-04": 6852, - "free-trial-v3-d8d7-2024-04-04": 6236, - "inimai---open-app-copy-c50c-2024-11-28": 5418, - "localized-paywall-e901-2024-04-04": 5519, - "price-tester-1b8e-2024-04-04": 5925, - "products-v3-60c5-2024-04-04": 5824, - "superwall-template-9f9f-2024-05-21": 5215, - "url-paywall-v3-3810-2024-04-04": 5012, - "video-v3-72b4-2024-04-04": 7054 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5772, + "data-v3-0ed9-2024-04-04": 6941, + "free-trial-v3-d8d7-2024-04-04": 5519, + "inimai---open-app-copy-c50c-2024-11-28": 5266, + "localized-paywall-e901-2024-04-04": 6588, + "price-tester-1b8e-2024-04-04": 6335, + "products-v3-60c5-2024-04-04": 6284, + "superwall-template-9f9f-2024-05-21": 5164, + "url-paywall-v3-3810-2024-04-04": 5873, + "video-v3-72b4-2024-04-04": 6081 }, - "preloadCompleteEventMs": 2102, + "preloadCompleteEventMs": 839, "run": 7 }, { - "allReadyMs": 5486, + "allReadyMs": 7473, "cold": true, - "configureMs": 1814, + "configureMs": 1190, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4929, - "data-v3-0ed9-2024-04-04": 5486, - "free-trial-v3-d8d7-2024-04-04": 4575, - "inimai---open-app-copy-c50c-2024-11-28": 3612, - "localized-paywall-e901-2024-04-04": 3713, - "price-tester-1b8e-2024-04-04": 4676, - "products-v3-60c5-2024-04-04": 4423, - "superwall-template-9f9f-2024-05-21": 4017, - "url-paywall-v3-3810-2024-04-04": 5031, - "video-v3-72b4-2024-04-04": 3511 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5953, + "data-v3-0ed9-2024-04-04": 6814, + "free-trial-v3-d8d7-2024-04-04": 5342, + "inimai---open-app-copy-c50c-2024-11-28": 5035, + "localized-paywall-e901-2024-04-04": 7473, + "price-tester-1b8e-2024-04-04": 6055, + "products-v3-60c5-2024-04-04": 6206, + "superwall-template-9f9f-2024-05-21": 4883, + "url-paywall-v3-3810-2024-04-04": 5700, + "video-v3-72b4-2024-04-04": 5599 }, - "preloadCompleteEventMs": 685, + "preloadCompleteEventMs": 1662, "run": 8 }, { - "allReadyMs": 5926, + "allReadyMs": 5949, "cold": true, - "configureMs": 1475, + "configureMs": 1773, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4757, - "data-v3-0ed9-2024-04-04": 5926, - "free-trial-v3-d8d7-2024-04-04": 5216, - "inimai---open-app-copy-c50c-2024-11-28": 5420, - "localized-paywall-e901-2024-04-04": 5521, - "price-tester-1b8e-2024-04-04": 3744, - "products-v3-60c5-2024-04-04": 5062, - "superwall-template-9f9f-2024-05-21": 4200, - "url-paywall-v3-3810-2024-04-04": 4909, - "video-v3-72b4-2024-04-04": 3896 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5190, + "data-v3-0ed9-2024-04-04": 5949, + "free-trial-v3-d8d7-2024-04-04": 4684, + "inimai---open-app-copy-c50c-2024-11-28": 4076, + "localized-paywall-e901-2024-04-04": 4228, + "price-tester-1b8e-2024-04-04": 4734, + "products-v3-60c5-2024-04-04": 4886, + "superwall-template-9f9f-2024-05-21": 5443, + "url-paywall-v3-3810-2024-04-04": 4430, + "video-v3-72b4-2024-04-04": 5645 }, - "preloadCompleteEventMs": 1072, + "preloadCompleteEventMs": 1261, "run": 9 }, { - "allReadyMs": 5801, + "allReadyMs": 5908, "cold": true, - "configureMs": 1888, + "configureMs": 1826, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3673, - "data-v3-0ed9-2024-04-04": 4990, - "free-trial-v3-d8d7-2024-04-04": 5497, - "inimai---open-app-copy-c50c-2024-11-28": 3774, - "localized-paywall-e901-2024-04-04": 5801, - "price-tester-1b8e-2024-04-04": 5092, - "products-v3-60c5-2024-04-04": 5649, - "superwall-template-9f9f-2024-05-21": 4079, - "url-paywall-v3-3810-2024-04-04": 5193, - "video-v3-72b4-2024-04-04": 5295 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5149, + "data-v3-0ed9-2024-04-04": 5453, + "free-trial-v3-d8d7-2024-04-04": 4897, + "inimai---open-app-copy-c50c-2024-11-28": 3884, + "localized-paywall-e901-2024-04-04": 5908, + "price-tester-1b8e-2024-04-04": 4694, + "products-v3-60c5-2024-04-04": 4188, + "superwall-template-9f9f-2024-05-21": 3783, + "url-paywall-v3-3810-2024-04-04": 4087, + "video-v3-72b4-2024-04-04": 4390 }, - "preloadCompleteEventMs": 744, + "preloadCompleteEventMs": 798, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 55.7768082196462, - "coldMeanMs": 8780.8, - "maxMs": 21525, - "meanMs": 8780.8, - "medianMs": 6612.5, - "minMs": 5486, + "coefficientOfVariationPct": 32.07398582767803, + "coldMeanMs": 8232.3, + "maxMs": 13052, + "meanMs": 8232.3, + "medianMs": 7284.5, + "minMs": 5908, "sampleCount": 10, - "stdDevMs": 4897.649976150693, + "stdDevMs": 2640.4267352919383, "warmMeanMs": null }, "tier": "LOW" diff --git a/.benchmark/results/preload-benchmark-mid.json b/.benchmark/results/preload-benchmark-mid.json index 4b2c00dff..7c2889339 100644 --- a/.benchmark/results/preload-benchmark-mid.json +++ b/.benchmark/results/preload-benchmark-mid.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 7038, + "allReadyMs": 10809, "cold": true, - "configureMs": 2334, + "configureMs": 2494, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7038, - "data-v3-0ed9-2024-04-04": 6173, - "free-trial-v3-d8d7-2024-04-04": 6683, - "inimai---open-app-copy-c50c-2024-11-28": 4851, - "localized-paywall-e901-2024-04-04": 5563, - "price-tester-1b8e-2024-04-04": 5817, - "products-v3-60c5-2024-04-04": 6377, - "superwall-template-9f9f-2024-05-21": 5055, - "url-paywall-v3-3810-2024-04-04": 5715, - "video-v3-72b4-2024-04-04": 6530 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 8000, + "data-v3-0ed9-2024-04-04": 10352, + "free-trial-v3-d8d7-2024-04-04": 8971, + "inimai---open-app-copy-c50c-2024-11-28": 9176, + "localized-paywall-e901-2024-04-04": 7238, + "price-tester-1b8e-2024-04-04": 8258, + "products-v3-60c5-2024-04-04": 7033, + "superwall-template-9f9f-2024-05-21": 6670, + "url-paywall-v3-3810-2024-04-04": 10809, + "video-v3-72b4-2024-04-04": 8920 }, - "preloadCompleteEventMs": 1399, + "preloadCompleteEventMs": 2505, "run": 1 }, { - "allReadyMs": 5291, + "allReadyMs": 9280, "cold": true, - "configureMs": 1338, + "configureMs": 2566, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5291, - "data-v3-0ed9-2024-04-04": 4480, - "free-trial-v3-d8d7-2024-04-04": 4632, - "inimai---open-app-copy-c50c-2024-11-28": 3513, - "localized-paywall-e901-2024-04-04": 4176, - "price-tester-1b8e-2024-04-04": 3871, - "products-v3-60c5-2024-04-04": 4784, - "superwall-template-9f9f-2024-05-21": 3715, - "url-paywall-v3-3810-2024-04-04": 4885, - "video-v3-72b4-2024-04-04": 3411 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9073, + "data-v3-0ed9-2024-04-04": 7279, + "free-trial-v3-d8d7-2024-04-04": 8652, + "inimai---open-app-copy-c50c-2024-11-28": 6140, + "localized-paywall-e901-2024-04-04": 9280, + "price-tester-1b8e-2024-04-04": 9175, + "products-v3-60c5-2024-04-04": 7687, + "superwall-template-9f9f-2024-05-21": 6653, + "url-paywall-v3-3810-2024-04-04": 4733, + "video-v3-72b4-2024-04-04": 7535 }, - "preloadCompleteEventMs": 795, + "preloadCompleteEventMs": 2025, "run": 2 }, { - "allReadyMs": 5317, + "allReadyMs": 7425, "cold": true, - "configureMs": 1399, + "configureMs": 1615, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4963, - "data-v3-0ed9-2024-04-04": 4451, - "free-trial-v3-d8d7-2024-04-04": 3996, - "inimai---open-app-copy-c50c-2024-11-28": 3438, - "localized-paywall-e901-2024-04-04": 5317, - "price-tester-1b8e-2024-04-04": 4046, - "products-v3-60c5-2024-04-04": 4198, - "superwall-template-9f9f-2024-05-21": 3692, - "url-paywall-v3-3810-2024-04-04": 5064, - "video-v3-72b4-2024-04-04": 4604 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7222, + "data-v3-0ed9-2024-04-04": 7425, + "free-trial-v3-d8d7-2024-04-04": 6863, + "inimai---open-app-copy-c50c-2024-11-28": 5997, + "localized-paywall-e901-2024-04-04": 6968, + "price-tester-1b8e-2024-04-04": 6660, + "products-v3-60c5-2024-04-04": 5642, + "superwall-template-9f9f-2024-05-21": 5794, + "url-paywall-v3-3810-2024-04-04": 6559, + "video-v3-72b4-2024-04-04": 6098 }, - "preloadCompleteEventMs": 529, + "preloadCompleteEventMs": 2738, "run": 3 }, { - "allReadyMs": 5138, + "allReadyMs": 5652, "cold": true, - "configureMs": 1832, + "configureMs": 1276, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4986, - "data-v3-0ed9-2024-04-04": 3159, - "free-trial-v3-d8d7-2024-04-04": 3666, - "inimai---open-app-copy-c50c-2024-11-28": 3514, - "localized-paywall-e901-2024-04-04": 4528, - "price-tester-1b8e-2024-04-04": 4477, - "products-v3-60c5-2024-04-04": 4784, - "superwall-template-9f9f-2024-05-21": 3362, - "url-paywall-v3-3810-2024-04-04": 4629, - "video-v3-72b4-2024-04-04": 5138 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4487, + "data-v3-0ed9-2024-04-04": 4994, + "free-trial-v3-d8d7-2024-04-04": 4640, + "inimai---open-app-copy-c50c-2024-11-28": 4032, + "localized-paywall-e901-2024-04-04": 5652, + "price-tester-1b8e-2024-04-04": 4083, + "products-v3-60c5-2024-04-04": 4184, + "superwall-template-9f9f-2024-05-21": 3930, + "url-paywall-v3-3810-2024-04-04": 3778, + "video-v3-72b4-2024-04-04": 4285 }, - "preloadCompleteEventMs": 649, + "preloadCompleteEventMs": 1427, "run": 4 }, { - "allReadyMs": 6300, + "allReadyMs": 4489, "cold": true, - "configureMs": 1352, + "configureMs": 1640, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3908, - "data-v3-0ed9-2024-04-04": 6148, - "free-trial-v3-d8d7-2024-04-04": 5894, - "inimai---open-app-copy-c50c-2024-11-28": 3401, - "localized-paywall-e901-2024-04-04": 5320, - "price-tester-1b8e-2024-04-04": 4642, - "products-v3-60c5-2024-04-04": 6300, - "superwall-template-9f9f-2024-05-21": 3249, - "url-paywall-v3-3810-2024-04-04": 3554, - "video-v3-72b4-2024-04-04": 4431 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3881, + "data-v3-0ed9-2024-04-04": 4489, + "free-trial-v3-d8d7-2024-04-04": 3223, + "inimai---open-app-copy-c50c-2024-11-28": 3121, + "localized-paywall-e901-2024-04-04": 3628, + "price-tester-1b8e-2024-04-04": 3527, + "products-v3-60c5-2024-04-04": 2969, + "superwall-template-9f9f-2024-05-21": 3476, + "url-paywall-v3-3810-2024-04-04": 3730, + "video-v3-72b4-2024-04-04": 4084 }, - "preloadCompleteEventMs": 1014, + "preloadCompleteEventMs": 653, "run": 5 }, { - "allReadyMs": 5293, + "allReadyMs": 5030, "cold": true, - "configureMs": 1382, + "configureMs": 1512, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4736, - "data-v3-0ed9-2024-04-04": 5293, - "free-trial-v3-d8d7-2024-04-04": 4380, - "inimai---open-app-copy-c50c-2024-11-28": 3414, - "localized-paywall-e901-2024-04-04": 4888, - "price-tester-1b8e-2024-04-04": 3363, - "products-v3-60c5-2024-04-04": 4483, - "superwall-template-9f9f-2024-05-21": 3616, - "url-paywall-v3-3810-2024-04-04": 4026, - "video-v3-72b4-2024-04-04": 3873 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4164, + "data-v3-0ed9-2024-04-04": 4572, + "free-trial-v3-d8d7-2024-04-04": 4370, + "inimai---open-app-copy-c50c-2024-11-28": 3300, + "localized-paywall-e901-2024-04-04": 5030, + "price-tester-1b8e-2024-04-04": 3606, + "products-v3-60c5-2024-04-04": 3759, + "superwall-template-9f9f-2024-05-21": 3505, + "url-paywall-v3-3810-2024-04-04": 4265, + "video-v3-72b4-2024-04-04": 3249 }, - "preloadCompleteEventMs": 666, + "preloadCompleteEventMs": 924, "run": 6 }, { - "allReadyMs": 4994, + "allReadyMs": 4492, "cold": true, - "configureMs": 1832, + "configureMs": 1406, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4129, - "data-v3-0ed9-2024-04-04": 3824, - "free-trial-v3-d8d7-2024-04-04": 4687, - "inimai---open-app-copy-c50c-2024-11-28": 3316, - "localized-paywall-e901-2024-04-04": 4792, - "price-tester-1b8e-2024-04-04": 4585, - "products-v3-60c5-2024-04-04": 3265, - "superwall-template-9f9f-2024-05-21": 4433, - "url-paywall-v3-3810-2024-04-04": 4994, - "video-v3-72b4-2024-04-04": 3520 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4492, + "data-v3-0ed9-2024-04-04": 3884, + "free-trial-v3-d8d7-2024-04-04": 3477, + "inimai---open-app-copy-c50c-2024-11-28": 4036, + "localized-paywall-e901-2024-04-04": 3580, + "price-tester-1b8e-2024-04-04": 3376, + "products-v3-60c5-2024-04-04": 3122, + "superwall-template-9f9f-2024-05-21": 4239, + "url-paywall-v3-3810-2024-04-04": 4340, + "video-v3-72b4-2024-04-04": 3528 }, - "preloadCompleteEventMs": 663, + "preloadCompleteEventMs": 968, "run": 7 }, { - "allReadyMs": 5850, + "allReadyMs": 4599, "cold": true, - "configureMs": 1780, + "configureMs": 1413, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4227, - "data-v3-0ed9-2024-04-04": 3974, - "free-trial-v3-d8d7-2024-04-04": 4886, - "inimai---open-app-copy-c50c-2024-11-28": 4937, - "localized-paywall-e901-2024-04-04": 5850, - "price-tester-1b8e-2024-04-04": 3569, - "products-v3-60c5-2024-04-04": 4379, - "superwall-template-9f9f-2024-05-21": 4683, - "url-paywall-v3-3810-2024-04-04": 3721, - "video-v3-72b4-2024-04-04": 3316 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4295, + "data-v3-0ed9-2024-04-04": 4599, + "free-trial-v3-d8d7-2024-04-04": 3688, + "inimai---open-app-copy-c50c-2024-11-28": 3233, + "localized-paywall-e901-2024-04-04": 3536, + "price-tester-1b8e-2024-04-04": 3486, + "products-v3-60c5-2024-04-04": 3789, + "superwall-template-9f9f-2024-05-21": 3385, + "url-paywall-v3-3810-2024-04-04": 4397, + "video-v3-72b4-2024-04-04": 4093 }, - "preloadCompleteEventMs": 671, + "preloadCompleteEventMs": 943, "run": 8 }, { - "allReadyMs": 5245, + "allReadyMs": 6006, "cold": true, - "configureMs": 1783, + "configureMs": 1716, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4584, - "data-v3-0ed9-2024-04-04": 4838, - "free-trial-v3-d8d7-2024-04-04": 4068, - "inimai---open-app-copy-c50c-2024-11-28": 3511, - "localized-paywall-e901-2024-04-04": 3713, - "price-tester-1b8e-2024-04-04": 4331, - "products-v3-60c5-2024-04-04": 3916, - "superwall-template-9f9f-2024-05-21": 5245, - "url-paywall-v3-3810-2024-04-04": 4939, - "video-v3-72b4-2024-04-04": 4280 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5294, + "data-v3-0ed9-2024-04-04": 6006, + "free-trial-v3-d8d7-2024-04-04": 5395, + "inimai---open-app-copy-c50c-2024-11-28": 4584, + "localized-paywall-e901-2024-04-04": 5497, + "price-tester-1b8e-2024-04-04": 4280, + "products-v3-60c5-2024-04-04": 5091, + "superwall-template-9f9f-2024-05-21": 4483, + "url-paywall-v3-3810-2024-04-04": 5602, + "video-v3-72b4-2024-04-04": 5703 }, - "preloadCompleteEventMs": 1015, + "preloadCompleteEventMs": 1706, "run": 9 }, { - "allReadyMs": 6153, + "allReadyMs": 4722, "cold": true, - "configureMs": 1780, + "configureMs": 1042, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4836, - "data-v3-0ed9-2024-04-04": 4634, - "free-trial-v3-d8d7-2024-04-04": 3873, - "inimai---open-app-copy-c50c-2024-11-28": 3265, - "localized-paywall-e901-2024-04-04": 6153, - "price-tester-1b8e-2024-04-04": 3670, - "products-v3-60c5-2024-04-04": 4228, - "superwall-template-9f9f-2024-05-21": 3417, - "url-paywall-v3-3810-2024-04-04": 3619, - "video-v3-72b4-2024-04-04": 4329 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4469, + "data-v3-0ed9-2024-04-04": 4722, + "free-trial-v3-d8d7-2024-04-04": 4064, + "inimai---open-app-copy-c50c-2024-11-28": 3457, + "localized-paywall-e901-2024-04-04": 3912, + "price-tester-1b8e-2024-04-04": 4216, + "products-v3-60c5-2024-04-04": 4318, + "superwall-template-9f9f-2024-05-21": 3659, + "url-paywall-v3-3810-2024-04-04": 3304, + "video-v3-72b4-2024-04-04": 3861 }, - "preloadCompleteEventMs": 646, + "preloadCompleteEventMs": 998, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 11.573251482042023, - "coldMeanMs": 5661.9, - "maxMs": 7038, - "meanMs": 5661.9, - "medianMs": 5305.0, - "minMs": 4994, + "coefficientOfVariationPct": 35.577018683093556, + "coldMeanMs": 6250.4, + "maxMs": 10809, + "meanMs": 6250.4, + "medianMs": 5341.0, + "minMs": 4489, "sampleCount": 10, - "stdDevMs": 655.2659256617372, + "stdDevMs": 2223.7059757680795, "warmMeanMs": null }, "tier": "MID" From a977acaea4e2b49ca80faaaebe154be8cb776b75 Mon Sep 17 00:00:00 2001 From: Ian Rumac Date: Tue, 21 Jul 2026 17:22:35 +0200 Subject: [PATCH 07/12] Ensure loading is reset after purchase --- .../example/superapp/test/RepresentTests.kt | 7 + .../test/PaywallFragmentTestActivity.kt | 137 ++++++++++++++++++ .../paywall/view/PaywallViewDismissTest.kt | 55 +++++++ .../superwall/sdk/paywall/view/PaywallView.kt | 9 ++ 4 files changed, 208 insertions(+) create mode 100644 app/src/main/java/com/superwall/superapp/test/PaywallFragmentTestActivity.kt diff --git a/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt b/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt index 5bb5e381e..a173ad906 100644 --- a/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt +++ b/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt @@ -18,6 +18,7 @@ import com.superwall.sdk.config.options.PaywallOptions import com.superwall.sdk.config.options.SuperwallOptions import com.superwall.sdk.delegate.SuperwallDelegate import com.superwall.sdk.logger.LogLevel +import com.superwall.sdk.models.entitlements.SubscriptionStatus import com.superwall.sdk.paywall.view.delegate.PaywallLoadingState import com.superwall.sdk.store.testmode.TestModeBehavior import com.superwall.superapp.Keys @@ -219,6 +220,12 @@ class RepresentTests { private suspend fun awaitConfigured() { Superwall.instance.configurationStateListener.first { it is ConfigurationStatus.Configured } + // Force a DEFINITE entitlement status. On CI emulators Google Play Billing is + // unavailable (developer error 5), so the status otherwise stays `Unknown` and + // paywall presentation is SKIPPED with `subscription_status_timeout` (the status + // stayed "unknown" for >5s). `Inactive` means "no entitlements" so the non-gated + // paywall still presents. Mirrors every paywall-presenting test in `UITestHandler`. + Superwall.instance.setSubscriptionStatus(SubscriptionStatus.Inactive) } private fun device() = UiDevice.getInstance(getInstrumentation()) diff --git a/app/src/main/java/com/superwall/superapp/test/PaywallFragmentTestActivity.kt b/app/src/main/java/com/superwall/superapp/test/PaywallFragmentTestActivity.kt new file mode 100644 index 000000000..445f3b5e4 --- /dev/null +++ b/app/src/main/java/com/superwall/superapp/test/PaywallFragmentTestActivity.kt @@ -0,0 +1,137 @@ +package com.superwall.superapp.test + +import android.os.Bundle +import android.view.Gravity +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.FrameLayout +import android.widget.LinearLayout +import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.Fragment +import androidx.fragment.app.commit +import androidx.lifecycle.lifecycleScope +import com.superwall.sdk.paywall.presentation.get_paywall.builder.PaywallBuilder +import com.superwall.sdk.paywall.presentation.internal.state.PaywallResult +import com.superwall.sdk.paywall.view.PaywallView +import com.superwall.sdk.paywall.view.delegate.PaywallViewCallback +import kotlinx.coroutines.launch + +/** + * Manual, in-app analog of the `PaywallHostFragment` used by the `RepresentTests` + * androidTest suite. Lets you reproduce the PR #434 re-present regression by hand: + * embed a paywall in a [Fragment] via the public `getPaywall`/[PaywallBuilder] API, + * buy, then tap "Re-present paywall" to re-attach the SAME cached [PaywallView] and + * confirm the buy button is still alive. + * + * The androidTest [com.example.superapp.test.PaywallHostFragment] can't be launched by + * the running app (it lives in the androidTest source set), so this mirrors it in main. + */ +class PaywallFragmentTestActivity : AppCompatActivity() { + private val containerId = View.generateViewId() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + val root = + LinearLayout(this).apply { + orientation = LinearLayout.VERTICAL + layoutParams = + LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT, + ) + } + + val represent = + Button(this).apply { + text = "Re-present paywall" + setOnClickListener { + (supportFragmentManager.findFragmentById(containerId) as? EmbeddedPaywallFragment) + ?.present() + } + } + + val container = + FrameLayout(this).apply { + id = containerId + layoutParams = + LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + 0, + ).apply { weight = 1f } + } + + root.addView(represent) + root.addView(container) + setContentView(root) + + if (savedInstanceState == null) { + supportFragmentManager.commit { + replace(containerId, EmbeddedPaywallFragment()) + } + } + } +} + +/** + * Embeds a paywall inside a [Fragment] via the public embed API + * ([PaywallBuilder] -> `Superwall.getPaywall`), NOT via `register`. Mirrors the + * customer's fragment-hosted setup from PR #434. Re-attaches the SAME cached + * [PaywallView] on each [present] call. + */ +class EmbeddedPaywallFragment : Fragment() { + // Same placement the RepresentTests suite uses. + var placement: String = "non_recurring_product" + + private lateinit var container: FrameLayout + private var paywallView: PaywallView? = null + + private val delegate = + object : PaywallViewCallback { + override fun onFinished( + paywall: PaywallView, + result: PaywallResult, + shouldDismiss: Boolean, + ) { + // no-op: keep the host alive for re-embedding. + } + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View = FrameLayout(requireContext()).also { this.container = it } + + override fun onViewCreated( + view: View, + savedInstanceState: Bundle?, + ) { + super.onViewCreated(view, savedInstanceState) + present() + } + + fun present() { + viewLifecycleOwner.lifecycleScope.launch { + embedPaywall() + } + } + + private suspend fun embedPaywall() { + // Detach any previously-embedded instance before re-embedding the (cached) view. + paywallView?.let { (it.parent as? ViewGroup)?.removeView(it) } + + PaywallBuilder(placement) + .delegate(delegate) + .activity(requireActivity()) + .build() + .onSuccess { view -> + paywallView = view + (view.parent as? ViewGroup)?.removeView(view) + container.addView(view) + view.onViewCreated() + } + } +} diff --git a/superwall/src/androidTest/java/com/superwall/sdk/paywall/view/PaywallViewDismissTest.kt b/superwall/src/androidTest/java/com/superwall/sdk/paywall/view/PaywallViewDismissTest.kt index 10a16a422..63f6309ea 100644 --- a/superwall/src/androidTest/java/com/superwall/sdk/paywall/view/PaywallViewDismissTest.kt +++ b/superwall/src/androidTest/java/com/superwall/sdk/paywall/view/PaywallViewDismissTest.kt @@ -16,6 +16,7 @@ import com.superwall.sdk.paywall.presentation.internal.PresentationRequestType import com.superwall.sdk.paywall.presentation.internal.request.PresentationInfo import com.superwall.sdk.paywall.presentation.internal.state.PaywallResult import com.superwall.sdk.paywall.presentation.internal.state.PaywallState +import com.superwall.sdk.paywall.view.delegate.PaywallLoadingState import com.superwall.sdk.paywall.view.delegate.PaywallViewCallback import com.superwall.sdk.paywall.view.delegate.PaywallViewDelegateAdapter import kotlinx.coroutines.Dispatchers @@ -157,6 +158,60 @@ class PaywallViewDismissTest { } } + @Test + fun dismiss_purchased_resets_loading_spinner_for_embedded_paywall() = + runBlocking { + val finished = kotlinx.coroutines.CompletableDeferred() + // Mirrors the tab-bar / embedded host: onFinished is a no-op, so the view stays + // on screen after the purchase and is NEVER torn down (destroy() is not called). + val callback = + object : PaywallViewCallback { + override fun onFinished( + paywall: PaywallView, + result: PaywallResult, + shouldDismiss: Boolean, + ) { + finished.complete(Unit) + } + } + retainedCallback = callback + val delegate = PaywallViewDelegateAdapter(callback) + val view = makeView(delegate) + + val publisher = MutableSharedFlow(replay = 1, extraBufferCapacity = 1) + val request = makeRequest() + Given("an embedded paywall showing the purchase spinner") { + withContext(Dispatchers.Main) { + view.set(request, publisher, null) + view.onViewCreated() + // Buy tap sets this in production (Superwall.kt InitiatePurchase). + view.updateState( + PaywallViewState.Updates.SetLoadingState(PaywallLoadingState.LoadingPurchase), + ) + } + + When("the purchase completes and the SDK auto-dismisses") { + withContext(Dispatchers.Main) { + view.dismiss( + result = PaywallResult.Purchased(productId = "product1"), + closeReason = PaywallCloseReason.SystemLogic, + ) + } + + // Wait for the dismissal hand-off (onFinished, shouldDismiss=true). + withContext(Dispatchers.IO) { + withTimeout(3000) { finished.await() } + } + + Then("the loading spinner is reset to Ready even though the host kept the view") { + // No destroy()/teardown here: the host (tab-bar embed) leaves the view + // on screen. Pre-fix the LoadingPurchase spinner leaked and spun forever. + assertEquals(PaywallLoadingState.Ready, view.loadingState) + } + } + } + } + @Test fun dismiss_declined_for_next_paywall_does_not_clear_publisher() = runBlocking { diff --git a/superwall/src/main/java/com/superwall/sdk/paywall/view/PaywallView.kt b/superwall/src/main/java/com/superwall/sdk/paywall/view/PaywallView.kt index af9f277d8..c0cad2da9 100644 --- a/superwall/src/main/java/com/superwall/sdk/paywall/view/PaywallView.kt +++ b/superwall/src/main/java/com/superwall/sdk/paywall/view/PaywallView.kt @@ -556,6 +556,15 @@ class PaywallView( } callback?.let { + // A callback-backed (embedded) paywall delegates teardown to its host, which + // may legitimately keep the view on screen (e.g. a tab-bar embed). The purchase + // spinner is otherwise only reset in the full destroy() teardown, so without + // this an embedded paywall that stays visible after a purchase spins forever. + if (loadingState is PaywallLoadingState.LoadingPurchase || + loadingState is PaywallLoadingState.ManualLoading + ) { + controller.updateState(SetLoadingState(PaywallLoadingState.Ready)) + } controller.updateState(CallbackInvoked) it.onFinished( paywall = this, From 716d63ed719240b04e92ff38066f1615231b644a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 21 Jul 2026 15:34:37 +0000 Subject: [PATCH 08/12] Update paywall preload benchmark report [skip ci] --- .benchmark/REPORT.md | 6 +- .../results/preload-benchmark-high.json | 274 +++++++++--------- .benchmark/results/preload-benchmark-low.json | 274 +++++++++--------- .benchmark/results/preload-benchmark-mid.json | 274 +++++++++--------- 4 files changed, 414 insertions(+), 414 deletions(-) diff --git a/.benchmark/REPORT.md b/.benchmark/REPORT.md index 42d1fd94e..4dde391a8 100644 --- a/.benchmark/REPORT.md +++ b/.benchmark/REPORT.md @@ -4,9 +4,9 @@ Time from `preloadAllPaywalls()` until every paywall reaches `PaywallLoadingStat | Tier | Paywalls | Mean | Baseline | Δ | Limit | Cold mean | Warm mean | Median | StdDev | CV | Samples | Status | |------|----------|------|----------|---|-------|-----------|-----------|--------|--------|----|---------|--------| -| LOW | 10 | 7.28s | 6.34s | +14.9% | +30% | 8.23s | — | 7.28s | 2.64s | 32.1% | 10 (10×1) | ✅ OK | -| MID | 10 | 5.34s | 8.78s | -39.1% | +15% | 6.25s | — | 5.34s | 2.22s | 35.6% | 10 (10×1) | 🟢 improved | -| HIGH | 10 | 4.38s | 6.72s | -34.8% | +20% | 4.65s | — | 4.38s | 820ms | 17.6% | 10 (10×1) | 🟢 improved | +| LOW | 10 | 5.68s | 6.34s | -10.3% | +30% | 6.38s | — | 5.68s | 1.69s | 26.5% | 10 (10×1) | 🟢 improved | +| MID | 10 | 6.51s | 8.78s | -25.8% | +15% | 7.72s | — | 6.51s | 3.00s | 38.8% | 10 (10×1) | 🟢 improved | +| HIGH | 10 | 6.76s | 6.72s | +0.7% | +20% | 7.90s | — | 6.76s | 3.62s | 45.8% | 10 (10×1) | ✅ OK | ### Devices diff --git a/.benchmark/results/preload-benchmark-high.json b/.benchmark/results/preload-benchmark-high.json index 380b4f000..d31809dcd 100644 --- a/.benchmark/results/preload-benchmark-high.json +++ b/.benchmark/results/preload-benchmark-high.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 5844, + "allReadyMs": 17460, "cold": true, - "configureMs": 2356, + "configureMs": 2826, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5844, - "data-v3-0ed9-2024-04-04": 5540, - "free-trial-v3-d8d7-2024-04-04": 4624, - "inimai---open-app-copy-c50c-2024-11-28": 4117, - "localized-paywall-e901-2024-04-04": 4980, - "price-tester-1b8e-2024-04-04": 5182, - "products-v3-60c5-2024-04-04": 5287, - "superwall-template-9f9f-2024-05-21": 4320, - "url-paywall-v3-3810-2024-04-04": 5132, - "video-v3-72b4-2024-04-04": 4472 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 13994, + "data-v3-0ed9-2024-04-04": 17460, + "free-trial-v3-d8d7-2024-04-04": 9948, + "inimai---open-app-copy-c50c-2024-11-28": 10367, + "localized-paywall-e901-2024-04-04": 9279, + "price-tester-1b8e-2024-04-04": 11828, + "products-v3-60c5-2024-04-04": 12192, + "superwall-template-9f9f-2024-05-21": 8702, + "url-paywall-v3-3810-2024-04-04": 10996, + "video-v3-72b4-2024-04-04": 12701 }, - "preloadCompleteEventMs": 996, + "preloadCompleteEventMs": 1533, "run": 1 }, { - "allReadyMs": 4165, + "allReadyMs": 7335, "cold": true, - "configureMs": 831, + "configureMs": 1586, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4165, - "data-v3-0ed9-2024-04-04": 3506, - "free-trial-v3-d8d7-2024-04-04": 3861, - "inimai---open-app-copy-c50c-2024-11-28": 2796, - "localized-paywall-e901-2024-04-04": 3912, - "price-tester-1b8e-2024-04-04": 2695, - "products-v3-60c5-2024-04-04": 3658, - "superwall-template-9f9f-2024-05-21": 2999, - "url-paywall-v3-3810-2024-04-04": 3303, - "video-v3-72b4-2024-04-04": 3202 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4835, + "data-v3-0ed9-2024-04-04": 7335, + "free-trial-v3-d8d7-2024-04-04": 5957, + "inimai---open-app-copy-c50c-2024-11-28": 4374, + "localized-paywall-e901-2024-04-04": 5038, + "price-tester-1b8e-2024-04-04": 5549, + "products-v3-60c5-2024-04-04": 5446, + "superwall-template-9f9f-2024-05-21": 6929, + "url-paywall-v3-3810-2024-04-04": 5753, + "video-v3-72b4-2024-04-04": 6110 }, - "preloadCompleteEventMs": 945, + "preloadCompleteEventMs": 1180, "run": 2 }, { - "allReadyMs": 3674, + "allReadyMs": 7669, "cold": true, - "configureMs": 1324, + "configureMs": 2090, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3319, - "data-v3-0ed9-2024-04-04": 3674, - "free-trial-v3-d8d7-2024-04-04": 2762, - "inimai---open-app-copy-c50c-2024-11-28": 2353, - "localized-paywall-e901-2024-04-04": 2813, - "price-tester-1b8e-2024-04-04": 2965, - "products-v3-60c5-2024-04-04": 3066, - "superwall-template-9f9f-2024-05-21": 2556, - "url-paywall-v3-3810-2024-04-04": 3116, - "video-v3-72b4-2024-04-04": 3420 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7262, + "data-v3-0ed9-2024-04-04": 7669, + "free-trial-v3-d8d7-2024-04-04": 4348, + "inimai---open-app-copy-c50c-2024-11-28": 5418, + "localized-paywall-e901-2024-04-04": 5991, + "price-tester-1b8e-2024-04-04": 4603, + "products-v3-60c5-2024-04-04": 6296, + "superwall-template-9f9f-2024-05-21": 5737, + "url-paywall-v3-3810-2024-04-04": 4858, + "video-v3-72b4-2024-04-04": 5010 }, - "preloadCompleteEventMs": 535, + "preloadCompleteEventMs": 1156, "run": 3 }, { - "allReadyMs": 3966, + "allReadyMs": 9955, "cold": true, - "configureMs": 2582, + "configureMs": 1539, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3511, - "data-v3-0ed9-2024-04-04": 3257, - "free-trial-v3-d8d7-2024-04-04": 2901, - "inimai---open-app-copy-c50c-2024-11-28": 2596, - "localized-paywall-e901-2024-04-04": 3966, - "price-tester-1b8e-2024-04-04": 3562, - "products-v3-60c5-2024-04-04": 2953, - "superwall-template-9f9f-2024-05-21": 3815, - "url-paywall-v3-3810-2024-04-04": 3054, - "video-v3-72b4-2024-04-04": 2647 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9345, + "data-v3-0ed9-2024-04-04": 8633, + "free-trial-v3-d8d7-2024-04-04": 6583, + "inimai---open-app-copy-c50c-2024-11-28": 6225, + "localized-paywall-e901-2024-04-04": 9955, + "price-tester-1b8e-2024-04-04": 5660, + "products-v3-60c5-2024-04-04": 6888, + "superwall-template-9f9f-2024-05-21": 7560, + "url-paywall-v3-3810-2024-04-04": 7971, + "video-v3-72b4-2024-04-04": 7153 }, - "preloadCompleteEventMs": 599, + "preloadCompleteEventMs": 991, "run": 4 }, { - "allReadyMs": 4534, + "allReadyMs": 7326, "cold": true, - "configureMs": 1416, + "configureMs": 1650, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4534, - "data-v3-0ed9-2024-04-04": 4382, - "free-trial-v3-d8d7-2024-04-04": 3924, - "inimai---open-app-copy-c50c-2024-11-28": 3516, - "localized-paywall-e901-2024-04-04": 3772, - "price-tester-1b8e-2024-04-04": 3722, - "products-v3-60c5-2024-04-04": 4129, - "superwall-template-9f9f-2024-05-21": 3465, - "url-paywall-v3-3810-2024-04-04": 4026, - "video-v3-72b4-2024-04-04": 3671 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6961, + "data-v3-0ed9-2024-04-04": 6505, + "free-trial-v3-d8d7-2024-04-04": 6049, + "inimai---open-app-copy-c50c-2024-11-28": 5538, + "localized-paywall-e901-2024-04-04": 7114, + "price-tester-1b8e-2024-04-04": 6200, + "products-v3-60c5-2024-04-04": 6708, + "superwall-template-9f9f-2024-05-21": 5386, + "url-paywall-v3-3810-2024-04-04": 5132, + "video-v3-72b4-2024-04-04": 7326 }, - "preloadCompleteEventMs": 1016, + "preloadCompleteEventMs": 1206, "run": 5 }, { - "allReadyMs": 4815, + "allReadyMs": 5813, "cold": true, - "configureMs": 1620, + "configureMs": 1701, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4511, - "data-v3-0ed9-2024-04-04": 4309, - "free-trial-v3-d8d7-2024-04-04": 3649, - "inimai---open-app-copy-c50c-2024-11-28": 3487, - "localized-paywall-e901-2024-04-04": 4815, - "price-tester-1b8e-2024-04-04": 4056, - "products-v3-60c5-2024-04-04": 3801, - "superwall-template-9f9f-2024-05-21": 3436, - "url-paywall-v3-3810-2024-04-04": 3284, - "video-v3-72b4-2024-04-04": 3700 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5813, + "data-v3-0ed9-2024-04-04": 5407, + "free-trial-v3-d8d7-2024-04-04": 4848, + "inimai---open-app-copy-c50c-2024-11-28": 3780, + "localized-paywall-e901-2024-04-04": 4594, + "price-tester-1b8e-2024-04-04": 4899, + "products-v3-60c5-2024-04-04": 3628, + "superwall-template-9f9f-2024-05-21": 3984, + "url-paywall-v3-3810-2024-04-04": 5052, + "video-v3-72b4-2024-04-04": 5509 }, - "preloadCompleteEventMs": 911, + "preloadCompleteEventMs": 713, "run": 6 }, { - "allReadyMs": 3931, + "allReadyMs": 5210, "cold": true, - "configureMs": 1167, + "configureMs": 1766, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3523, - "data-v3-0ed9-2024-04-04": 3931, - "free-trial-v3-d8d7-2024-04-04": 2914, - "inimai---open-app-copy-c50c-2024-11-28": 2711, - "localized-paywall-e901-2024-04-04": 2965, - "price-tester-1b8e-2024-04-04": 3219, - "products-v3-60c5-2024-04-04": 3168, - "superwall-template-9f9f-2024-05-21": 2609, - "url-paywall-v3-3810-2024-04-04": 2457, - "video-v3-72b4-2024-04-04": 3321 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4652, + "data-v3-0ed9-2024-04-04": 5108, + "free-trial-v3-d8d7-2024-04-04": 4194, + "inimai---open-app-copy-c50c-2024-11-28": 3279, + "localized-paywall-e901-2024-04-04": 5210, + "price-tester-1b8e-2024-04-04": 4245, + "products-v3-60c5-2024-04-04": 4804, + "superwall-template-9f9f-2024-05-21": 3483, + "url-paywall-v3-3810-2024-04-04": 4347, + "video-v3-72b4-2024-04-04": 4042 }, - "preloadCompleteEventMs": 610, + "preloadCompleteEventMs": 688, "run": 7 }, { - "allReadyMs": 4226, + "allReadyMs": 6200, "cold": true, - "configureMs": 1624, + "configureMs": 1812, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4226, - "data-v3-0ed9-2024-04-04": 4073, - "free-trial-v3-d8d7-2024-04-04": 3263, - "inimai---open-app-copy-c50c-2024-11-28": 3061, - "localized-paywall-e901-2024-04-04": 3770, - "price-tester-1b8e-2024-04-04": 3263, - "products-v3-60c5-2024-04-04": 3365, - "superwall-template-9f9f-2024-05-21": 3567, - "url-paywall-v3-3810-2024-04-04": 2959, - "video-v3-72b4-2024-04-04": 3871 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3959, + "data-v3-0ed9-2024-04-04": 6200, + "free-trial-v3-d8d7-2024-04-04": 5438, + "inimai---open-app-copy-c50c-2024-11-28": 4111, + "localized-paywall-e901-2024-04-04": 5540, + "price-tester-1b8e-2024-04-04": 5286, + "products-v3-60c5-2024-04-04": 5794, + "superwall-template-9f9f-2024-05-21": 4314, + "url-paywall-v3-3810-2024-04-04": 4982, + "video-v3-72b4-2024-04-04": 5896 }, - "preloadCompleteEventMs": 1238, + "preloadCompleteEventMs": 1010, "run": 8 }, { - "allReadyMs": 5893, + "allReadyMs": 5965, "cold": true, - "configureMs": 1568, + "configureMs": 1849, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4727, - "data-v3-0ed9-2024-04-04": 4575, - "free-trial-v3-d8d7-2024-04-04": 3814, - "inimai---open-app-copy-c50c-2024-11-28": 3712, - "localized-paywall-e901-2024-04-04": 5893, - "price-tester-1b8e-2024-04-04": 4270, - "products-v3-60c5-2024-04-04": 4372, - "superwall-template-9f9f-2024-05-21": 3610, - "url-paywall-v3-3810-2024-04-04": 4220, - "video-v3-72b4-2024-04-04": 3458 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5152, + "data-v3-0ed9-2024-04-04": 5965, + "free-trial-v3-d8d7-2024-04-04": 5458, + "inimai---open-app-copy-c50c-2024-11-28": 3983, + "localized-paywall-e901-2024-04-04": 5254, + "price-tester-1b8e-2024-04-04": 4441, + "products-v3-60c5-2024-04-04": 4543, + "superwall-template-9f9f-2024-05-21": 4238, + "url-paywall-v3-3810-2024-04-04": 3830, + "video-v3-72b4-2024-04-04": 5610 }, - "preloadCompleteEventMs": 925, + "preloadCompleteEventMs": 1060, "run": 9 }, { - "allReadyMs": 5482, + "allReadyMs": 6069, "cold": true, - "configureMs": 1648, + "configureMs": 1428, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4008, - "data-v3-0ed9-2024-04-04": 4261, - "free-trial-v3-d8d7-2024-04-04": 4362, - "inimai---open-app-copy-c50c-2024-11-28": 3653, - "localized-paywall-e901-2024-04-04": 5482, - "price-tester-1b8e-2024-04-04": 3146, - "products-v3-60c5-2024-04-04": 3856, - "superwall-template-9f9f-2024-05-21": 3551, - "url-paywall-v3-3810-2024-04-04": 3754, - "video-v3-72b4-2024-04-04": 4620 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6069, + "data-v3-0ed9-2024-04-04": 5714, + "free-trial-v3-d8d7-2024-04-04": 5409, + "inimai---open-app-copy-c50c-2024-11-28": 4037, + "localized-paywall-e901-2024-04-04": 5206, + "price-tester-1b8e-2024-04-04": 4750, + "products-v3-60c5-2024-04-04": 4547, + "superwall-template-9f9f-2024-05-21": 4292, + "url-paywall-v3-3810-2024-04-04": 3935, + "video-v3-72b4-2024-04-04": 4699 }, - "preloadCompleteEventMs": 1031, + "preloadCompleteEventMs": 956, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 17.629290131541918, - "coldMeanMs": 4653.0, - "maxMs": 5893, - "meanMs": 4653.0, - "medianMs": 4380.0, - "minMs": 3674, + "coefficientOfVariationPct": 45.81337610611249, + "coldMeanMs": 7900.2, + "maxMs": 17460, + "meanMs": 7900.2, + "medianMs": 6763.0, + "minMs": 5210, "sampleCount": 10, - "stdDevMs": 820.2908698206454, + "stdDevMs": 3619.3483391350987, "warmMeanMs": null }, "tier": "HIGH" diff --git a/.benchmark/results/preload-benchmark-low.json b/.benchmark/results/preload-benchmark-low.json index 5292e1b80..c93fab565 100644 --- a/.benchmark/results/preload-benchmark-low.json +++ b/.benchmark/results/preload-benchmark-low.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 13052, + "allReadyMs": 10612, "cold": true, - "configureMs": 2852, + "configureMs": 2538, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 11272, - "data-v3-0ed9-2024-04-04": 12841, - "free-trial-v3-d8d7-2024-04-04": 11797, - "inimai---open-app-copy-c50c-2024-11-28": 9949, - "localized-paywall-e901-2024-04-04": 13052, - "price-tester-1b8e-2024-04-04": 10762, - "products-v3-60c5-2024-04-04": 9284, - "superwall-template-9f9f-2024-05-21": 9640, - "url-paywall-v3-3810-2024-04-04": 12003, - "video-v3-72b4-2024-04-04": 11476 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9322, + "data-v3-0ed9-2024-04-04": 7125, + "free-trial-v3-d8d7-2024-04-04": 9784, + "inimai---open-app-copy-c50c-2024-11-28": 5319, + "localized-paywall-e901-2024-04-04": 10612, + "price-tester-1b8e-2024-04-04": 7278, + "products-v3-60c5-2024-04-04": 5984, + "superwall-template-9f9f-2024-05-21": 5576, + "url-paywall-v3-3810-2024-04-04": 10300, + "video-v3-72b4-2024-04-04": 6137 }, - "preloadCompleteEventMs": 2305, + "preloadCompleteEventMs": 1545, "run": 1 }, { - "allReadyMs": 7340, + "allReadyMs": 6934, "cold": true, - "configureMs": 1556, + "configureMs": 1995, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7035, - "data-v3-0ed9-2024-04-04": 6732, - "free-trial-v3-d8d7-2024-04-04": 7340, - "inimai---open-app-copy-c50c-2024-11-28": 4654, - "localized-paywall-e901-2024-04-04": 5821, - "price-tester-1b8e-2024-04-04": 4501, - "products-v3-60c5-2024-04-04": 5668, - "superwall-template-9f9f-2024-05-21": 5009, - "url-paywall-v3-3810-2024-04-04": 5465, - "video-v3-72b4-2024-04-04": 5262 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6581, + "data-v3-0ed9-2024-04-04": 6934, + "free-trial-v3-d8d7-2024-04-04": 6124, + "inimai---open-app-copy-c50c-2024-11-28": 4606, + "localized-paywall-e901-2024-04-04": 5872, + "price-tester-1b8e-2024-04-04": 5720, + "products-v3-60c5-2024-04-04": 6277, + "superwall-template-9f9f-2024-05-21": 5518, + "url-paywall-v3-3810-2024-04-04": 4504, + "video-v3-72b4-2024-04-04": 4961 }, - "preloadCompleteEventMs": 1084, + "preloadCompleteEventMs": 1223, "run": 2 }, { - "allReadyMs": 12325, + "allReadyMs": 7726, "cold": true, - "configureMs": 1582, + "configureMs": 1880, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9726, - "data-v3-0ed9-2024-04-04": 10954, - "free-trial-v3-d8d7-2024-04-04": 10081, - "inimai---open-app-copy-c50c-2024-11-28": 9827, - "localized-paywall-e901-2024-04-04": 10235, - "price-tester-1b8e-2024-04-04": 11006, - "products-v3-60c5-2024-04-04": 11208, - "superwall-template-9f9f-2024-05-21": 9220, - "url-paywall-v3-3810-2024-04-04": 12120, - "video-v3-72b4-2024-04-04": 12325 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7423, + "data-v3-0ed9-2024-04-04": 7726, + "free-trial-v3-d8d7-2024-04-04": 6662, + "inimai---open-app-copy-c50c-2024-11-28": 5699, + "localized-paywall-e901-2024-04-04": 6968, + "price-tester-1b8e-2024-04-04": 5441, + "products-v3-60c5-2024-04-04": 6866, + "superwall-template-9f9f-2024-05-21": 5953, + "url-paywall-v3-3810-2024-04-04": 6257, + "video-v3-72b4-2024-04-04": 7120 }, - "preloadCompleteEventMs": 2207, + "preloadCompleteEventMs": 2030, "run": 3 }, { - "allReadyMs": 10058, + "allReadyMs": 5650, "cold": true, - "configureMs": 2338, + "configureMs": 1551, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 8184, - "data-v3-0ed9-2024-04-04": 7728, - "free-trial-v3-d8d7-2024-04-04": 7322, - "inimai---open-app-copy-c50c-2024-11-28": 6143, - "localized-paywall-e901-2024-04-04": 10058, - "price-tester-1b8e-2024-04-04": 7424, - "products-v3-60c5-2024-04-04": 7880, - "superwall-template-9f9f-2024-05-21": 6654, - "url-paywall-v3-3810-2024-04-04": 6963, - "video-v3-72b4-2024-04-04": 5686 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5397, + "data-v3-0ed9-2024-04-04": 5650, + "free-trial-v3-d8d7-2024-04-04": 4333, + "inimai---open-app-copy-c50c-2024-11-28": 3922, + "localized-paywall-e901-2024-04-04": 4125, + "price-tester-1b8e-2024-04-04": 4383, + "products-v3-60c5-2024-04-04": 4536, + "superwall-template-9f9f-2024-05-21": 4992, + "url-paywall-v3-3810-2024-04-04": 3821, + "video-v3-72b4-2024-04-04": 5144 }, - "preloadCompleteEventMs": 1289, + "preloadCompleteEventMs": 1063, "run": 4 }, { - "allReadyMs": 6048, + "allReadyMs": 5719, "cold": true, - "configureMs": 1858, + "configureMs": 1662, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5490, - "data-v3-0ed9-2024-04-04": 6048, - "free-trial-v3-d8d7-2024-04-04": 4626, - "inimai---open-app-copy-c50c-2024-11-28": 4070, - "localized-paywall-e901-2024-04-04": 4677, - "price-tester-1b8e-2024-04-04": 4879, - "products-v3-60c5-2024-04-04": 5187, - "superwall-template-9f9f-2024-05-21": 4272, - "url-paywall-v3-3810-2024-04-04": 3868, - "video-v3-72b4-2024-04-04": 4983 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5105, + "data-v3-0ed9-2024-04-04": 5611, + "free-trial-v3-d8d7-2024-04-04": 4700, + "inimai---open-app-copy-c50c-2024-11-28": 3889, + "localized-paywall-e901-2024-04-04": 5719, + "price-tester-1b8e-2024-04-04": 4802, + "products-v3-60c5-2024-04-04": 3788, + "superwall-template-9f9f-2024-05-21": 4142, + "url-paywall-v3-3810-2024-04-04": 5257, + "video-v3-72b4-2024-04-04": 4903 }, - "preloadCompleteEventMs": 1541, + "preloadCompleteEventMs": 855, "run": 5 }, { - "allReadyMs": 7229, + "allReadyMs": 5798, "cold": true, - "configureMs": 1624, + "configureMs": 2576, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5914, - "data-v3-0ed9-2024-04-04": 5543, - "free-trial-v3-d8d7-2024-04-04": 7128, - "inimai---open-app-copy-c50c-2024-11-28": 4176, - "localized-paywall-e901-2024-04-04": 7229, - "price-tester-1b8e-2024-04-04": 4530, - "products-v3-60c5-2024-04-04": 4987, - "superwall-template-9f9f-2024-05-21": 4378, - "url-paywall-v3-3810-2024-04-04": 4631, - "video-v3-72b4-2024-04-04": 4784 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5696, + "data-v3-0ed9-2024-04-04": 4578, + "free-trial-v3-d8d7-2024-04-04": 5038, + "inimai---open-app-copy-c50c-2024-11-28": 3971, + "localized-paywall-e901-2024-04-04": 5139, + "price-tester-1b8e-2024-04-04": 3869, + "products-v3-60c5-2024-04-04": 5494, + "superwall-template-9f9f-2024-05-21": 4173, + "url-paywall-v3-3810-2024-04-04": 5290, + "video-v3-72b4-2024-04-04": 5798 }, - "preloadCompleteEventMs": 1212, + "preloadCompleteEventMs": 1189, "run": 6 }, { - "allReadyMs": 6941, + "allReadyMs": 5585, "cold": true, - "configureMs": 1878, + "configureMs": 1786, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5772, - "data-v3-0ed9-2024-04-04": 6941, - "free-trial-v3-d8d7-2024-04-04": 5519, - "inimai---open-app-copy-c50c-2024-11-28": 5266, - "localized-paywall-e901-2024-04-04": 6588, - "price-tester-1b8e-2024-04-04": 6335, - "products-v3-60c5-2024-04-04": 6284, - "superwall-template-9f9f-2024-05-21": 5164, - "url-paywall-v3-3810-2024-04-04": 5873, - "video-v3-72b4-2024-04-04": 6081 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4877, + "data-v3-0ed9-2024-04-04": 5585, + "free-trial-v3-d8d7-2024-04-04": 3864, + "inimai---open-app-copy-c50c-2024-11-28": 3611, + "localized-paywall-e901-2024-04-04": 4016, + "price-tester-1b8e-2024-04-04": 3712, + "products-v3-60c5-2024-04-04": 4319, + "superwall-template-9f9f-2024-05-21": 3509, + "url-paywall-v3-3810-2024-04-04": 4421, + "video-v3-72b4-2024-04-04": 4168 }, - "preloadCompleteEventMs": 839, + "preloadCompleteEventMs": 1228, "run": 7 }, { - "allReadyMs": 7473, + "allReadyMs": 5140, "cold": true, - "configureMs": 1190, + "configureMs": 1755, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5953, - "data-v3-0ed9-2024-04-04": 6814, - "free-trial-v3-d8d7-2024-04-04": 5342, - "inimai---open-app-copy-c50c-2024-11-28": 5035, - "localized-paywall-e901-2024-04-04": 7473, - "price-tester-1b8e-2024-04-04": 6055, - "products-v3-60c5-2024-04-04": 6206, - "superwall-template-9f9f-2024-05-21": 4883, - "url-paywall-v3-3810-2024-04-04": 5700, - "video-v3-72b4-2024-04-04": 5599 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4988, + "data-v3-0ed9-2024-04-04": 4583, + "free-trial-v3-d8d7-2024-04-04": 4178, + "inimai---open-app-copy-c50c-2024-11-28": 3468, + "localized-paywall-e901-2024-04-04": 5140, + "price-tester-1b8e-2024-04-04": 3367, + "products-v3-60c5-2024-04-04": 4330, + "superwall-template-9f9f-2024-05-21": 2957, + "url-paywall-v3-3810-2024-04-04": 3772, + "video-v3-72b4-2024-04-04": 3311 }, - "preloadCompleteEventMs": 1662, + "preloadCompleteEventMs": 670, "run": 8 }, { - "allReadyMs": 5949, + "allReadyMs": 5570, "cold": true, - "configureMs": 1773, + "configureMs": 1795, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5190, - "data-v3-0ed9-2024-04-04": 5949, - "free-trial-v3-d8d7-2024-04-04": 4684, - "inimai---open-app-copy-c50c-2024-11-28": 4076, - "localized-paywall-e901-2024-04-04": 4228, - "price-tester-1b8e-2024-04-04": 4734, - "products-v3-60c5-2024-04-04": 4886, - "superwall-template-9f9f-2024-05-21": 5443, - "url-paywall-v3-3810-2024-04-04": 4430, - "video-v3-72b4-2024-04-04": 5645 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4659, + "data-v3-0ed9-2024-04-04": 4405, + "free-trial-v3-d8d7-2024-04-04": 4811, + "inimai---open-app-copy-c50c-2024-11-28": 3696, + "localized-paywall-e901-2024-04-04": 5570, + "price-tester-1b8e-2024-04-04": 4101, + "products-v3-60c5-2024-04-04": 5216, + "superwall-template-9f9f-2024-05-21": 3899, + "url-paywall-v3-3810-2024-04-04": 4912, + "video-v3-72b4-2024-04-04": 5064 }, - "preloadCompleteEventMs": 1261, + "preloadCompleteEventMs": 839, "run": 9 }, { - "allReadyMs": 5908, + "allReadyMs": 5091, "cold": true, - "configureMs": 1826, + "configureMs": 1731, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5149, - "data-v3-0ed9-2024-04-04": 5453, - "free-trial-v3-d8d7-2024-04-04": 4897, - "inimai---open-app-copy-c50c-2024-11-28": 3884, - "localized-paywall-e901-2024-04-04": 5908, - "price-tester-1b8e-2024-04-04": 4694, - "products-v3-60c5-2024-04-04": 4188, - "superwall-template-9f9f-2024-05-21": 3783, - "url-paywall-v3-3810-2024-04-04": 4087, - "video-v3-72b4-2024-04-04": 4390 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4231, + "data-v3-0ed9-2024-04-04": 4686, + "free-trial-v3-d8d7-2024-04-04": 3826, + "inimai---open-app-copy-c50c-2024-11-28": 3623, + "localized-paywall-e901-2024-04-04": 4383, + "price-tester-1b8e-2024-04-04": 4787, + "products-v3-60c5-2024-04-04": 5091, + "superwall-template-9f9f-2024-05-21": 3521, + "url-paywall-v3-3810-2024-04-04": 4889, + "video-v3-72b4-2024-04-04": 4990 }, - "preloadCompleteEventMs": 798, + "preloadCompleteEventMs": 716, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 32.07398582767803, - "coldMeanMs": 8232.3, - "maxMs": 13052, - "meanMs": 8232.3, - "medianMs": 7284.5, - "minMs": 5908, + "coefficientOfVariationPct": 26.540019017822143, + "coldMeanMs": 6382.5, + "maxMs": 10612, + "meanMs": 6382.5, + "medianMs": 5684.5, + "minMs": 5091, "sampleCount": 10, - "stdDevMs": 2640.4267352919383, + "stdDevMs": 1693.9167138124983, "warmMeanMs": null }, "tier": "LOW" diff --git a/.benchmark/results/preload-benchmark-mid.json b/.benchmark/results/preload-benchmark-mid.json index 7c2889339..4c08f65eb 100644 --- a/.benchmark/results/preload-benchmark-mid.json +++ b/.benchmark/results/preload-benchmark-mid.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 10809, + "allReadyMs": 14565, "cold": true, - "configureMs": 2494, + "configureMs": 2321, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 8000, - "data-v3-0ed9-2024-04-04": 10352, - "free-trial-v3-d8d7-2024-04-04": 8971, - "inimai---open-app-copy-c50c-2024-11-28": 9176, - "localized-paywall-e901-2024-04-04": 7238, - "price-tester-1b8e-2024-04-04": 8258, - "products-v3-60c5-2024-04-04": 7033, - "superwall-template-9f9f-2024-05-21": 6670, - "url-paywall-v3-3810-2024-04-04": 10809, - "video-v3-72b4-2024-04-04": 8920 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9504, + "data-v3-0ed9-2024-04-04": 8690, + "free-trial-v3-d8d7-2024-04-04": 13852, + "inimai---open-app-copy-c50c-2024-11-28": 14565, + "localized-paywall-e901-2024-04-04": 14004, + "price-tester-1b8e-2024-04-04": 9147, + "products-v3-60c5-2024-04-04": 10575, + "superwall-template-9f9f-2024-05-21": 8944, + "url-paywall-v3-3810-2024-04-04": 10149, + "video-v3-72b4-2024-04-04": 9758 }, - "preloadCompleteEventMs": 2505, + "preloadCompleteEventMs": 1808, "run": 1 }, { - "allReadyMs": 9280, + "allReadyMs": 8063, "cold": true, - "configureMs": 2566, + "configureMs": 1781, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9073, - "data-v3-0ed9-2024-04-04": 7279, - "free-trial-v3-d8d7-2024-04-04": 8652, - "inimai---open-app-copy-c50c-2024-11-28": 6140, - "localized-paywall-e901-2024-04-04": 9280, - "price-tester-1b8e-2024-04-04": 9175, - "products-v3-60c5-2024-04-04": 7687, - "superwall-template-9f9f-2024-05-21": 6653, - "url-paywall-v3-3810-2024-04-04": 4733, - "video-v3-72b4-2024-04-04": 7535 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 8063, + "data-v3-0ed9-2024-04-04": 7504, + "free-trial-v3-d8d7-2024-04-04": 6024, + "inimai---open-app-copy-c50c-2024-11-28": 5720, + "localized-paywall-e901-2024-04-04": 6176, + "price-tester-1b8e-2024-04-04": 6581, + "products-v3-60c5-2024-04-04": 6995, + "superwall-template-9f9f-2024-05-21": 5466, + "url-paywall-v3-3810-2024-04-04": 6733, + "video-v3-72b4-2024-04-04": 6480 }, - "preloadCompleteEventMs": 2025, + "preloadCompleteEventMs": 980, "run": 2 }, { - "allReadyMs": 7425, + "allReadyMs": 11530, "cold": true, - "configureMs": 1615, + "configureMs": 2707, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7222, - "data-v3-0ed9-2024-04-04": 7425, - "free-trial-v3-d8d7-2024-04-04": 6863, - "inimai---open-app-copy-c50c-2024-11-28": 5997, - "localized-paywall-e901-2024-04-04": 6968, - "price-tester-1b8e-2024-04-04": 6660, - "products-v3-60c5-2024-04-04": 5642, - "superwall-template-9f9f-2024-05-21": 5794, - "url-paywall-v3-3810-2024-04-04": 6559, - "video-v3-72b4-2024-04-04": 6098 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 10666, + "data-v3-0ed9-2024-04-04": 8671, + "free-trial-v3-d8d7-2024-04-04": 9904, + "inimai---open-app-copy-c50c-2024-11-28": 7955, + "localized-paywall-e901-2024-04-04": 9496, + "price-tester-1b8e-2024-04-04": 8824, + "products-v3-60c5-2024-04-04": 11530, + "superwall-template-9f9f-2024-05-21": 7597, + "url-paywall-v3-3810-2024-04-04": 10158, + "video-v3-72b4-2024-04-04": 10971 }, - "preloadCompleteEventMs": 2738, + "preloadCompleteEventMs": 1893, "run": 3 }, { - "allReadyMs": 5652, + "allReadyMs": 5794, "cold": true, - "configureMs": 1276, + "configureMs": 1570, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4487, - "data-v3-0ed9-2024-04-04": 4994, - "free-trial-v3-d8d7-2024-04-04": 4640, - "inimai---open-app-copy-c50c-2024-11-28": 4032, - "localized-paywall-e901-2024-04-04": 5652, - "price-tester-1b8e-2024-04-04": 4083, - "products-v3-60c5-2024-04-04": 4184, - "superwall-template-9f9f-2024-05-21": 3930, - "url-paywall-v3-3810-2024-04-04": 3778, - "video-v3-72b4-2024-04-04": 4285 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5794, + "data-v3-0ed9-2024-04-04": 5186, + "free-trial-v3-d8d7-2024-04-04": 5490, + "inimai---open-app-copy-c50c-2024-11-28": 3966, + "localized-paywall-e901-2024-04-04": 4781, + "price-tester-1b8e-2024-04-04": 3763, + "products-v3-60c5-2024-04-04": 4680, + "superwall-template-9f9f-2024-05-21": 4169, + "url-paywall-v3-3810-2024-04-04": 5389, + "video-v3-72b4-2024-04-04": 4933 }, - "preloadCompleteEventMs": 1427, + "preloadCompleteEventMs": 1165, "run": 4 }, { - "allReadyMs": 4489, + "allReadyMs": 6903, "cold": true, - "configureMs": 1640, + "configureMs": 1797, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3881, - "data-v3-0ed9-2024-04-04": 4489, - "free-trial-v3-d8d7-2024-04-04": 3223, - "inimai---open-app-copy-c50c-2024-11-28": 3121, - "localized-paywall-e901-2024-04-04": 3628, - "price-tester-1b8e-2024-04-04": 3527, - "products-v3-60c5-2024-04-04": 2969, - "superwall-template-9f9f-2024-05-21": 3476, - "url-paywall-v3-3810-2024-04-04": 3730, - "video-v3-72b4-2024-04-04": 4084 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5231, + "data-v3-0ed9-2024-04-04": 6802, + "free-trial-v3-d8d7-2024-04-04": 6396, + "inimai---open-app-copy-c50c-2024-11-28": 4519, + "localized-paywall-e901-2024-04-04": 6903, + "price-tester-1b8e-2024-04-04": 5686, + "products-v3-60c5-2024-04-04": 5889, + "superwall-template-9f9f-2024-05-21": 4721, + "url-paywall-v3-3810-2024-04-04": 4316, + "video-v3-72b4-2024-04-04": 5788 }, - "preloadCompleteEventMs": 653, + "preloadCompleteEventMs": 1660, "run": 5 }, { - "allReadyMs": 5030, + "allReadyMs": 7060, "cold": true, - "configureMs": 1512, + "configureMs": 2049, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4164, - "data-v3-0ed9-2024-04-04": 4572, - "free-trial-v3-d8d7-2024-04-04": 4370, - "inimai---open-app-copy-c50c-2024-11-28": 3300, - "localized-paywall-e901-2024-04-04": 5030, - "price-tester-1b8e-2024-04-04": 3606, - "products-v3-60c5-2024-04-04": 3759, - "superwall-template-9f9f-2024-05-21": 3505, - "url-paywall-v3-3810-2024-04-04": 4265, - "video-v3-72b4-2024-04-04": 3249 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4065, + "data-v3-0ed9-2024-04-04": 5946, + "free-trial-v3-d8d7-2024-04-04": 5541, + "inimai---open-app-copy-c50c-2024-11-28": 4419, + "localized-paywall-e901-2024-04-04": 5185, + "price-tester-1b8e-2024-04-04": 6099, + "products-v3-60c5-2024-04-04": 7060, + "superwall-template-9f9f-2024-05-21": 4268, + "url-paywall-v3-3810-2024-04-04": 5084, + "video-v3-72b4-2024-04-04": 5338 }, - "preloadCompleteEventMs": 924, + "preloadCompleteEventMs": 1130, "run": 6 }, { - "allReadyMs": 4492, + "allReadyMs": 5605, "cold": true, - "configureMs": 1406, + "configureMs": 1177, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4492, - "data-v3-0ed9-2024-04-04": 3884, - "free-trial-v3-d8d7-2024-04-04": 3477, - "inimai---open-app-copy-c50c-2024-11-28": 4036, - "localized-paywall-e901-2024-04-04": 3580, - "price-tester-1b8e-2024-04-04": 3376, - "products-v3-60c5-2024-04-04": 3122, - "superwall-template-9f9f-2024-05-21": 4239, - "url-paywall-v3-3810-2024-04-04": 4340, - "video-v3-72b4-2024-04-04": 3528 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5200, + "data-v3-0ed9-2024-04-04": 5605, + "free-trial-v3-d8d7-2024-04-04": 4128, + "inimai---open-app-copy-c50c-2024-11-28": 3824, + "localized-paywall-e901-2024-04-04": 4691, + "price-tester-1b8e-2024-04-04": 3926, + "products-v3-60c5-2024-04-04": 3469, + "superwall-template-9f9f-2024-05-21": 3672, + "url-paywall-v3-3810-2024-04-04": 4590, + "video-v3-72b4-2024-04-04": 4897 }, - "preloadCompleteEventMs": 968, + "preloadCompleteEventMs": 641, "run": 7 }, { - "allReadyMs": 4599, + "allReadyMs": 5650, "cold": true, - "configureMs": 1413, + "configureMs": 2615, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4295, - "data-v3-0ed9-2024-04-04": 4599, - "free-trial-v3-d8d7-2024-04-04": 3688, - "inimai---open-app-copy-c50c-2024-11-28": 3233, - "localized-paywall-e901-2024-04-04": 3536, - "price-tester-1b8e-2024-04-04": 3486, - "products-v3-60c5-2024-04-04": 3789, - "superwall-template-9f9f-2024-05-21": 3385, - "url-paywall-v3-3810-2024-04-04": 4397, - "video-v3-72b4-2024-04-04": 4093 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4990, + "data-v3-0ed9-2024-04-04": 5650, + "free-trial-v3-d8d7-2024-04-04": 4635, + "inimai---open-app-copy-c50c-2024-11-28": 3710, + "localized-paywall-e901-2024-04-04": 4173, + "price-tester-1b8e-2024-04-04": 4480, + "products-v3-60c5-2024-04-04": 5142, + "superwall-template-9f9f-2024-05-21": 3912, + "url-paywall-v3-3810-2024-04-04": 4378, + "video-v3-72b4-2024-04-04": 4736 }, - "preloadCompleteEventMs": 943, + "preloadCompleteEventMs": 987, "run": 8 }, { - "allReadyMs": 6006, + "allReadyMs": 5953, "cold": true, - "configureMs": 1716, + "configureMs": 1752, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5294, - "data-v3-0ed9-2024-04-04": 6006, - "free-trial-v3-d8d7-2024-04-04": 5395, - "inimai---open-app-copy-c50c-2024-11-28": 4584, - "localized-paywall-e901-2024-04-04": 5497, - "price-tester-1b8e-2024-04-04": 4280, - "products-v3-60c5-2024-04-04": 5091, - "superwall-template-9f9f-2024-05-21": 4483, - "url-paywall-v3-3810-2024-04-04": 5602, - "video-v3-72b4-2024-04-04": 5703 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5397, + "data-v3-0ed9-2024-04-04": 5953, + "free-trial-v3-d8d7-2024-04-04": 4941, + "inimai---open-app-copy-c50c-2024-11-28": 4179, + "localized-paywall-e901-2024-04-04": 5498, + "price-tester-1b8e-2024-04-04": 4789, + "products-v3-60c5-2024-04-04": 5144, + "superwall-template-9f9f-2024-05-21": 4077, + "url-paywall-v3-3810-2024-04-04": 4381, + "video-v3-72b4-2024-04-04": 4687 }, - "preloadCompleteEventMs": 1706, + "preloadCompleteEventMs": 934, "run": 9 }, { - "allReadyMs": 4722, + "allReadyMs": 6119, "cold": true, - "configureMs": 1042, + "configureMs": 1805, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4469, - "data-v3-0ed9-2024-04-04": 4722, - "free-trial-v3-d8d7-2024-04-04": 4064, - "inimai---open-app-copy-c50c-2024-11-28": 3457, - "localized-paywall-e901-2024-04-04": 3912, - "price-tester-1b8e-2024-04-04": 4216, - "products-v3-60c5-2024-04-04": 4318, - "superwall-template-9f9f-2024-05-21": 3659, - "url-paywall-v3-3810-2024-04-04": 3304, - "video-v3-72b4-2024-04-04": 3861 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5816, + "data-v3-0ed9-2024-04-04": 5358, + "free-trial-v3-d8d7-2024-04-04": 4801, + "inimai---open-app-copy-c50c-2024-11-28": 3989, + "localized-paywall-e901-2024-04-04": 4953, + "price-tester-1b8e-2024-04-04": 4243, + "products-v3-60c5-2024-04-04": 6119, + "superwall-template-9f9f-2024-05-21": 3888, + "url-paywall-v3-3810-2024-04-04": 4192, + "video-v3-72b4-2024-04-04": 4446 }, - "preloadCompleteEventMs": 998, + "preloadCompleteEventMs": 1117, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 35.577018683093556, - "coldMeanMs": 6250.4, - "maxMs": 10809, - "meanMs": 6250.4, - "medianMs": 5341.0, - "minMs": 4489, + "coefficientOfVariationPct": 38.777496472291425, + "coldMeanMs": 7724.2, + "maxMs": 14565, + "meanMs": 7724.2, + "medianMs": 6511.0, + "minMs": 5605, "sampleCount": 10, - "stdDevMs": 2223.7059757680795, + "stdDevMs": 2995.251382512734, "warmMeanMs": null }, "tier": "MID" From 98827741b236a06377b6d5925678b3fac4a1a161 Mon Sep 17 00:00:00 2001 From: Ian Rumac Date: Wed, 22 Jul 2026 10:58:58 +0200 Subject: [PATCH 09/12] Improve tests, cleanup comments --- .../superapp/test/PaywallHostFragment.kt | 13 ----------- .../example/superapp/test/RepresentTests.kt | 22 +------------------ app/src/main/AndroidManifest.xml | 6 +++++ 3 files changed, 7 insertions(+), 34 deletions(-) diff --git a/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt b/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt index 4ddbbdd3c..41f662fad 100644 --- a/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt +++ b/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt @@ -17,19 +17,6 @@ import kotlinx.coroutines.launch * Minimal test-host screen that EMBEDS a paywall inside a [Fragment] via the public * embed API ([PaywallBuilder] -> [com.superwall.sdk.Superwall.getPaywall]), NOT via * [com.superwall.sdk.paywall.presentation.register]. - * - * This mirrors the customer's fragment-hosted setup that surfaced the regression - * fixed in PR #434: the embedded `getPaywallView` path returns the SAME cached - * `PaywallView` on a re-present, and before the fix the stale `LoadingPurchase` - * overlay / `presentationDidFinishPrepare` flag were never cleared on that path - * (the reset used to live in `present()`, which the embed API never calls). The fix - * moved the reset upstream into `PaywallManager.getPaywallView`'s cache-hit branch, - * so this embedded flow now exercises it. - * - * Display prep mirrors `PaywallComposable`: `PaywallBuilder.build()` internally runs - * `getPaywall()` (which triggers the cache-hit reset), `setupWith`, and - * `beforeViewCreated()`; we then add the returned view to the fragment container and - * call `onViewCreated()`. */ class PaywallHostFragment : Fragment() { // Parameterised so the whole flow keys off a single placement constant. diff --git a/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt b/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt index a173ad906..e3bed08b9 100644 --- a/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt +++ b/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt @@ -38,27 +38,7 @@ import org.junit.runner.RunWith import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds -/** - * Emulator (Firebase Test Lab) regression tests for PR #434 - * (`fix/paywall-transient-state-reset-on-represent`). - * - * Repro: after a consumable purchase, re-presenting the SAME paywall in one app - * session left the buy button dead — a stale `LoadingPurchase` loading overlay (and - * stale `presentationDidFinishPrepare`) carried onto the re-presented CACHED paywall - * and swallowed the tap. The fix resets that transient state upstream in - * `PaywallManager.getPaywallView`'s cache-hit branch, so BOTH the full-screen - * `register()` path and the embedded `getPaywall`/`getPaywallView` path are covered. - * - * These tests drive the EMBEDDED path — the one the customer hit, and the one that was - * previously unfixed because the embed API never calls `present()`. A fragment - * ([PaywallHostFragment]) embeds the paywall via `PaywallBuilder`/`getPaywall`, - * purchases via Superwall test mode (billing is unavailable on CI emulators), then - * re-obtains/re-attaches the embedded paywall and re-taps buy. - * - * Assertions are event/state based (no golden screenshots) so they can be validated - * on FTL without locally generated baseline images. - */ -@RunWith(AndroidJUnit4::class) +//@RunWith(AndroidJUnit4::class) class RepresentTests { companion object { /** diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 718027d43..58ef72e0a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -52,6 +52,12 @@ android:label="@string/title_activity_uitest" android:theme="@style/Theme.MyApplication" /> + + From dfa6e6e4ad9685435ebf56432a9370039fe20bb0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 22 Jul 2026 09:10:47 +0000 Subject: [PATCH 10/12] Update paywall preload benchmark report [skip ci] --- .benchmark/REPORT.md | 6 +- .../results/preload-benchmark-high.json | 274 +++++++++--------- .benchmark/results/preload-benchmark-low.json | 274 +++++++++--------- .benchmark/results/preload-benchmark-mid.json | 274 +++++++++--------- 4 files changed, 414 insertions(+), 414 deletions(-) diff --git a/.benchmark/REPORT.md b/.benchmark/REPORT.md index 4dde391a8..61d5f3f0f 100644 --- a/.benchmark/REPORT.md +++ b/.benchmark/REPORT.md @@ -4,9 +4,9 @@ Time from `preloadAllPaywalls()` until every paywall reaches `PaywallLoadingStat | Tier | Paywalls | Mean | Baseline | Δ | Limit | Cold mean | Warm mean | Median | StdDev | CV | Samples | Status | |------|----------|------|----------|---|-------|-----------|-----------|--------|--------|----|---------|--------| -| LOW | 10 | 5.68s | 6.34s | -10.3% | +30% | 6.38s | — | 5.68s | 1.69s | 26.5% | 10 (10×1) | 🟢 improved | -| MID | 10 | 6.51s | 8.78s | -25.8% | +15% | 7.72s | — | 6.51s | 3.00s | 38.8% | 10 (10×1) | 🟢 improved | -| HIGH | 10 | 6.76s | 6.72s | +0.7% | +20% | 7.90s | — | 6.76s | 3.62s | 45.8% | 10 (10×1) | ✅ OK | +| LOW | 10 | 7.20s | 6.34s | +13.6% | +30% | 7.86s | — | 7.20s | 2.49s | 31.7% | 10 (10×1) | ✅ OK | +| MID | 10 | 6.03s | 8.78s | -31.3% | +15% | 6.92s | — | 6.03s | 2.76s | 40.0% | 10 (10×1) | 🟢 improved | +| HIGH | 10 | 6.36s | 6.72s | -5.3% | +20% | 6.73s | — | 6.36s | 2.21s | 32.8% | 10 (10×1) | 🟢 improved | ### Devices diff --git a/.benchmark/results/preload-benchmark-high.json b/.benchmark/results/preload-benchmark-high.json index d31809dcd..19e2a3512 100644 --- a/.benchmark/results/preload-benchmark-high.json +++ b/.benchmark/results/preload-benchmark-high.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 17460, + "allReadyMs": 12422, "cold": true, - "configureMs": 2826, + "configureMs": 2614, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 13994, - "data-v3-0ed9-2024-04-04": 17460, - "free-trial-v3-d8d7-2024-04-04": 9948, - "inimai---open-app-copy-c50c-2024-11-28": 10367, - "localized-paywall-e901-2024-04-04": 9279, - "price-tester-1b8e-2024-04-04": 11828, - "products-v3-60c5-2024-04-04": 12192, - "superwall-template-9f9f-2024-05-21": 8702, - "url-paywall-v3-3810-2024-04-04": 10996, - "video-v3-72b4-2024-04-04": 12701 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 12422, + "data-v3-0ed9-2024-04-04": 11606, + "free-trial-v3-d8d7-2024-04-04": 10149, + "inimai---open-app-copy-c50c-2024-11-28": 7040, + "localized-paywall-e901-2024-04-04": 10358, + "price-tester-1b8e-2024-04-04": 10875, + "products-v3-60c5-2024-04-04": 6888, + "superwall-template-9f9f-2024-05-21": 7706, + "url-paywall-v3-3810-2024-04-04": 8504, + "video-v3-72b4-2024-04-04": 10720 }, - "preloadCompleteEventMs": 1533, + "preloadCompleteEventMs": 1928, "run": 1 }, { - "allReadyMs": 7335, + "allReadyMs": 6417, "cold": true, - "configureMs": 1586, + "configureMs": 1581, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4835, - "data-v3-0ed9-2024-04-04": 7335, - "free-trial-v3-d8d7-2024-04-04": 5957, - "inimai---open-app-copy-c50c-2024-11-28": 4374, - "localized-paywall-e901-2024-04-04": 5038, - "price-tester-1b8e-2024-04-04": 5549, - "products-v3-60c5-2024-04-04": 5446, - "superwall-template-9f9f-2024-05-21": 6929, - "url-paywall-v3-3810-2024-04-04": 5753, - "video-v3-72b4-2024-04-04": 6110 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6011, + "data-v3-0ed9-2024-04-04": 6417, + "free-trial-v3-d8d7-2024-04-04": 5198, + "inimai---open-app-copy-c50c-2024-11-28": 4163, + "localized-paywall-e901-2024-04-04": 5300, + "price-tester-1b8e-2024-04-04": 4009, + "products-v3-60c5-2024-04-04": 5656, + "superwall-template-9f9f-2024-05-21": 4942, + "url-paywall-v3-3810-2024-04-04": 4576, + "video-v3-72b4-2024-04-04": 5503 }, - "preloadCompleteEventMs": 1180, + "preloadCompleteEventMs": 1011, "run": 2 }, { - "allReadyMs": 7669, + "allReadyMs": 7917, "cold": true, - "configureMs": 2090, + "configureMs": 1980, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7262, - "data-v3-0ed9-2024-04-04": 7669, - "free-trial-v3-d8d7-2024-04-04": 4348, - "inimai---open-app-copy-c50c-2024-11-28": 5418, - "localized-paywall-e901-2024-04-04": 5991, - "price-tester-1b8e-2024-04-04": 4603, - "products-v3-60c5-2024-04-04": 6296, - "superwall-template-9f9f-2024-05-21": 5737, - "url-paywall-v3-3810-2024-04-04": 4858, - "video-v3-72b4-2024-04-04": 5010 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7308, + "data-v3-0ed9-2024-04-04": 6902, + "free-trial-v3-d8d7-2024-04-04": 6291, + "inimai---open-app-copy-c50c-2024-11-28": 4787, + "localized-paywall-e901-2024-04-04": 7917, + "price-tester-1b8e-2024-04-04": 4635, + "products-v3-60c5-2024-04-04": 5723, + "superwall-template-9f9f-2024-05-21": 5211, + "url-paywall-v3-3810-2024-04-04": 6495, + "video-v3-72b4-2024-04-04": 7003 }, - "preloadCompleteEventMs": 1156, + "preloadCompleteEventMs": 1539, "run": 3 }, { - "allReadyMs": 9955, + "allReadyMs": 6911, "cold": true, - "configureMs": 1539, + "configureMs": 2074, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9345, - "data-v3-0ed9-2024-04-04": 8633, - "free-trial-v3-d8d7-2024-04-04": 6583, - "inimai---open-app-copy-c50c-2024-11-28": 6225, - "localized-paywall-e901-2024-04-04": 9955, - "price-tester-1b8e-2024-04-04": 5660, - "products-v3-60c5-2024-04-04": 6888, - "superwall-template-9f9f-2024-05-21": 7560, - "url-paywall-v3-3810-2024-04-04": 7971, - "video-v3-72b4-2024-04-04": 7153 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5795, + "data-v3-0ed9-2024-04-04": 6911, + "free-trial-v3-d8d7-2024-04-04": 4931, + "inimai---open-app-copy-c50c-2024-11-28": 4370, + "localized-paywall-e901-2024-04-04": 4728, + "price-tester-1b8e-2024-04-04": 4982, + "products-v3-60c5-2024-04-04": 5236, + "superwall-template-9f9f-2024-05-21": 4269, + "url-paywall-v3-3810-2024-04-04": 4576, + "video-v3-72b4-2024-04-04": 5134 }, - "preloadCompleteEventMs": 991, + "preloadCompleteEventMs": 1091, "run": 4 }, { - "allReadyMs": 7326, + "allReadyMs": 6631, "cold": true, - "configureMs": 1650, + "configureMs": 1404, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6961, - "data-v3-0ed9-2024-04-04": 6505, - "free-trial-v3-d8d7-2024-04-04": 6049, - "inimai---open-app-copy-c50c-2024-11-28": 5538, - "localized-paywall-e901-2024-04-04": 7114, - "price-tester-1b8e-2024-04-04": 6200, - "products-v3-60c5-2024-04-04": 6708, - "superwall-template-9f9f-2024-05-21": 5386, - "url-paywall-v3-3810-2024-04-04": 5132, - "video-v3-72b4-2024-04-04": 7326 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6175, + "data-v3-0ed9-2024-04-04": 6631, + "free-trial-v3-d8d7-2024-04-04": 5364, + "inimai---open-app-copy-c50c-2024-11-28": 4533, + "localized-paywall-e901-2024-04-04": 5414, + "price-tester-1b8e-2024-04-04": 5668, + "products-v3-60c5-2024-04-04": 5820, + "superwall-template-9f9f-2024-05-21": 5059, + "url-paywall-v3-3810-2024-04-04": 5617, + "video-v3-72b4-2024-04-04": 5922 }, - "preloadCompleteEventMs": 1206, + "preloadCompleteEventMs": 601, "run": 5 }, { - "allReadyMs": 5813, + "allReadyMs": 5498, "cold": true, - "configureMs": 1701, + "configureMs": 1391, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5813, - "data-v3-0ed9-2024-04-04": 5407, - "free-trial-v3-d8d7-2024-04-04": 4848, - "inimai---open-app-copy-c50c-2024-11-28": 3780, - "localized-paywall-e901-2024-04-04": 4594, - "price-tester-1b8e-2024-04-04": 4899, - "products-v3-60c5-2024-04-04": 3628, - "superwall-template-9f9f-2024-05-21": 3984, - "url-paywall-v3-3810-2024-04-04": 5052, - "video-v3-72b4-2024-04-04": 5509 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5092, + "data-v3-0ed9-2024-04-04": 4585, + "free-trial-v3-d8d7-2024-04-04": 5396, + "inimai---open-app-copy-c50c-2024-11-28": 3773, + "localized-paywall-e901-2024-04-04": 5498, + "price-tester-1b8e-2024-04-04": 4281, + "products-v3-60c5-2024-04-04": 5244, + "superwall-template-9f9f-2024-05-21": 3672, + "url-paywall-v3-3810-2024-04-04": 4026, + "video-v3-72b4-2024-04-04": 3925 }, - "preloadCompleteEventMs": 713, + "preloadCompleteEventMs": 873, "run": 6 }, { - "allReadyMs": 5210, + "allReadyMs": 5174, "cold": true, - "configureMs": 1766, + "configureMs": 1793, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4652, - "data-v3-0ed9-2024-04-04": 5108, - "free-trial-v3-d8d7-2024-04-04": 4194, - "inimai---open-app-copy-c50c-2024-11-28": 3279, - "localized-paywall-e901-2024-04-04": 5210, - "price-tester-1b8e-2024-04-04": 4245, - "products-v3-60c5-2024-04-04": 4804, - "superwall-template-9f9f-2024-05-21": 3483, - "url-paywall-v3-3810-2024-04-04": 4347, - "video-v3-72b4-2024-04-04": 4042 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4311, + "data-v3-0ed9-2024-04-04": 4565, + "free-trial-v3-d8d7-2024-04-04": 3803, + "inimai---open-app-copy-c50c-2024-11-28": 3549, + "localized-paywall-e901-2024-04-04": 5174, + "price-tester-1b8e-2024-04-04": 3447, + "products-v3-60c5-2024-04-04": 4717, + "superwall-template-9f9f-2024-05-21": 5022, + "url-paywall-v3-3810-2024-04-04": 4006, + "video-v3-72b4-2024-04-04": 3904 }, - "preloadCompleteEventMs": 688, + "preloadCompleteEventMs": 883, "run": 7 }, { - "allReadyMs": 6200, + "allReadyMs": 5108, "cold": true, - "configureMs": 1812, + "configureMs": 1656, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 3959, - "data-v3-0ed9-2024-04-04": 6200, - "free-trial-v3-d8d7-2024-04-04": 5438, - "inimai---open-app-copy-c50c-2024-11-28": 4111, - "localized-paywall-e901-2024-04-04": 5540, - "price-tester-1b8e-2024-04-04": 5286, - "products-v3-60c5-2024-04-04": 5794, - "superwall-template-9f9f-2024-05-21": 4314, - "url-paywall-v3-3810-2024-04-04": 4982, - "video-v3-72b4-2024-04-04": 5896 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4552, + "data-v3-0ed9-2024-04-04": 4805, + "free-trial-v3-d8d7-2024-04-04": 4197, + "inimai---open-app-copy-c50c-2024-11-28": 3324, + "localized-paywall-e901-2024-04-04": 3631, + "price-tester-1b8e-2024-04-04": 4247, + "products-v3-60c5-2024-04-04": 3222, + "superwall-template-9f9f-2024-05-21": 5108, + "url-paywall-v3-3810-2024-04-04": 3476, + "video-v3-72b4-2024-04-04": 4044 }, - "preloadCompleteEventMs": 1010, + "preloadCompleteEventMs": 589, "run": 8 }, { - "allReadyMs": 5965, + "allReadyMs": 6305, "cold": true, - "configureMs": 1849, + "configureMs": 1512, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5152, - "data-v3-0ed9-2024-04-04": 5965, - "free-trial-v3-d8d7-2024-04-04": 5458, - "inimai---open-app-copy-c50c-2024-11-28": 3983, - "localized-paywall-e901-2024-04-04": 5254, - "price-tester-1b8e-2024-04-04": 4441, - "products-v3-60c5-2024-04-04": 4543, - "superwall-template-9f9f-2024-05-21": 4238, - "url-paywall-v3-3810-2024-04-04": 3830, - "video-v3-72b4-2024-04-04": 5610 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4071, + "data-v3-0ed9-2024-04-04": 6305, + "free-trial-v3-d8d7-2024-04-04": 4782, + "inimai---open-app-copy-c50c-2024-11-28": 4884, + "localized-paywall-e901-2024-04-04": 5441, + "price-tester-1b8e-2024-04-04": 4122, + "products-v3-60c5-2024-04-04": 4985, + "superwall-template-9f9f-2024-05-21": 4478, + "url-paywall-v3-3810-2024-04-04": 4630, + "video-v3-72b4-2024-04-04": 3513 }, - "preloadCompleteEventMs": 1060, + "preloadCompleteEventMs": 1152, "run": 9 }, { - "allReadyMs": 6069, + "allReadyMs": 4940, "cold": true, - "configureMs": 1428, + "configureMs": 1820, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6069, - "data-v3-0ed9-2024-04-04": 5714, - "free-trial-v3-d8d7-2024-04-04": 5409, - "inimai---open-app-copy-c50c-2024-11-28": 4037, - "localized-paywall-e901-2024-04-04": 5206, - "price-tester-1b8e-2024-04-04": 4750, - "products-v3-60c5-2024-04-04": 4547, - "superwall-template-9f9f-2024-05-21": 4292, - "url-paywall-v3-3810-2024-04-04": 3935, - "video-v3-72b4-2024-04-04": 4699 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4028, + "data-v3-0ed9-2024-04-04": 4940, + "free-trial-v3-d8d7-2024-04-04": 3774, + "inimai---open-app-copy-c50c-2024-11-28": 3113, + "localized-paywall-e901-2024-04-04": 4231, + "price-tester-1b8e-2024-04-04": 2962, + "products-v3-60c5-2024-04-04": 4180, + "superwall-template-9f9f-2024-05-21": 4585, + "url-paywall-v3-3810-2024-04-04": 3521, + "video-v3-72b4-2024-04-04": 3266 }, - "preloadCompleteEventMs": 956, + "preloadCompleteEventMs": 594, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 45.81337610611249, - "coldMeanMs": 7900.2, - "maxMs": 17460, - "meanMs": 7900.2, - "medianMs": 6763.0, - "minMs": 5210, + "coefficientOfVariationPct": 32.806642844462296, + "coldMeanMs": 6732.3, + "maxMs": 12422, + "meanMs": 6732.3, + "medianMs": 6361.0, + "minMs": 4940, "sampleCount": 10, - "stdDevMs": 3619.3483391350987, + "stdDevMs": 2208.641616217735, "warmMeanMs": null }, "tier": "HIGH" diff --git a/.benchmark/results/preload-benchmark-low.json b/.benchmark/results/preload-benchmark-low.json index c93fab565..541d9a435 100644 --- a/.benchmark/results/preload-benchmark-low.json +++ b/.benchmark/results/preload-benchmark-low.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 10612, + "allReadyMs": 13684, "cold": true, - "configureMs": 2538, + "configureMs": 2443, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9322, - "data-v3-0ed9-2024-04-04": 7125, - "free-trial-v3-d8d7-2024-04-04": 9784, - "inimai---open-app-copy-c50c-2024-11-28": 5319, - "localized-paywall-e901-2024-04-04": 10612, - "price-tester-1b8e-2024-04-04": 7278, - "products-v3-60c5-2024-04-04": 5984, - "superwall-template-9f9f-2024-05-21": 5576, - "url-paywall-v3-3810-2024-04-04": 10300, - "video-v3-72b4-2024-04-04": 6137 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 10485, + "data-v3-0ed9-2024-04-04": 12796, + "free-trial-v3-d8d7-2024-04-04": 7871, + "inimai---open-app-copy-c50c-2024-11-28": 7255, + "localized-paywall-e901-2024-04-04": 9406, + "price-tester-1b8e-2024-04-04": 8867, + "products-v3-60c5-2024-04-04": 13684, + "superwall-template-9f9f-2024-05-21": 7044, + "url-paywall-v3-3810-2024-04-04": 11109, + "video-v3-72b4-2024-04-04": 9868 }, - "preloadCompleteEventMs": 1545, + "preloadCompleteEventMs": 2338, "run": 1 }, { - "allReadyMs": 6934, + "allReadyMs": 10019, "cold": true, - "configureMs": 1995, + "configureMs": 3148, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6581, - "data-v3-0ed9-2024-04-04": 6934, - "free-trial-v3-d8d7-2024-04-04": 6124, - "inimai---open-app-copy-c50c-2024-11-28": 4606, - "localized-paywall-e901-2024-04-04": 5872, - "price-tester-1b8e-2024-04-04": 5720, - "products-v3-60c5-2024-04-04": 6277, - "superwall-template-9f9f-2024-05-21": 5518, - "url-paywall-v3-3810-2024-04-04": 4504, - "video-v3-72b4-2024-04-04": 4961 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9311, + "data-v3-0ed9-2024-04-04": 9715, + "free-trial-v3-d8d7-2024-04-04": 8268, + "inimai---open-app-copy-c50c-2024-11-28": 6535, + "localized-paywall-e901-2024-04-04": 10019, + "price-tester-1b8e-2024-04-04": 6273, + "products-v3-60c5-2024-04-04": 8577, + "superwall-template-9f9f-2024-05-21": 7194, + "url-paywall-v3-3810-2024-04-04": 8425, + "video-v3-72b4-2024-04-04": 7501 }, - "preloadCompleteEventMs": 1223, + "preloadCompleteEventMs": 1807, "run": 2 }, { - "allReadyMs": 7726, + "allReadyMs": 7768, "cold": true, - "configureMs": 1880, + "configureMs": 2110, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7423, - "data-v3-0ed9-2024-04-04": 7726, - "free-trial-v3-d8d7-2024-04-04": 6662, - "inimai---open-app-copy-c50c-2024-11-28": 5699, - "localized-paywall-e901-2024-04-04": 6968, - "price-tester-1b8e-2024-04-04": 5441, - "products-v3-60c5-2024-04-04": 6866, - "superwall-template-9f9f-2024-05-21": 5953, - "url-paywall-v3-3810-2024-04-04": 6257, - "video-v3-72b4-2024-04-04": 7120 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7415, + "data-v3-0ed9-2024-04-04": 7768, + "free-trial-v3-d8d7-2024-04-04": 6259, + "inimai---open-app-copy-c50c-2024-11-28": 4413, + "localized-paywall-e901-2024-04-04": 6006, + "price-tester-1b8e-2024-04-04": 6465, + "products-v3-60c5-2024-04-04": 5594, + "superwall-template-9f9f-2024-05-21": 5027, + "url-paywall-v3-3810-2024-04-04": 6410, + "video-v3-72b4-2024-04-04": 6621 }, - "preloadCompleteEventMs": 2030, + "preloadCompleteEventMs": 1442, "run": 3 }, { - "allReadyMs": 5650, + "allReadyMs": 7715, "cold": true, - "configureMs": 1551, + "configureMs": 1625, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5397, - "data-v3-0ed9-2024-04-04": 5650, - "free-trial-v3-d8d7-2024-04-04": 4333, - "inimai---open-app-copy-c50c-2024-11-28": 3922, - "localized-paywall-e901-2024-04-04": 4125, - "price-tester-1b8e-2024-04-04": 4383, - "products-v3-60c5-2024-04-04": 4536, - "superwall-template-9f9f-2024-05-21": 4992, - "url-paywall-v3-3810-2024-04-04": 3821, - "video-v3-72b4-2024-04-04": 5144 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6230, + "data-v3-0ed9-2024-04-04": 7715, + "free-trial-v3-d8d7-2024-04-04": 4750, + "inimai---open-app-copy-c50c-2024-11-28": 5257, + "localized-paywall-e901-2024-04-04": 5510, + "price-tester-1b8e-2024-04-04": 4851, + "products-v3-60c5-2024-04-04": 5003, + "superwall-template-9f9f-2024-05-21": 7303, + "url-paywall-v3-3810-2024-04-04": 4239, + "video-v3-72b4-2024-04-04": 5712 }, - "preloadCompleteEventMs": 1063, + "preloadCompleteEventMs": 974, "run": 4 }, { - "allReadyMs": 5719, + "allReadyMs": 8867, "cold": true, - "configureMs": 1662, + "configureMs": 1925, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5105, - "data-v3-0ed9-2024-04-04": 5611, - "free-trial-v3-d8d7-2024-04-04": 4700, - "inimai---open-app-copy-c50c-2024-11-28": 3889, - "localized-paywall-e901-2024-04-04": 5719, - "price-tester-1b8e-2024-04-04": 4802, - "products-v3-60c5-2024-04-04": 3788, - "superwall-template-9f9f-2024-05-21": 4142, - "url-paywall-v3-3810-2024-04-04": 5257, - "video-v3-72b4-2024-04-04": 4903 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 8362, + "data-v3-0ed9-2024-04-04": 8055, + "free-trial-v3-d8d7-2024-04-04": 7649, + "inimai---open-app-copy-c50c-2024-11-28": 7093, + "localized-paywall-e901-2024-04-04": 8715, + "price-tester-1b8e-2024-04-04": 7497, + "products-v3-60c5-2024-04-04": 6532, + "superwall-template-9f9f-2024-05-21": 7346, + "url-paywall-v3-3810-2024-04-04": 8867, + "video-v3-72b4-2024-04-04": 7750 }, - "preloadCompleteEventMs": 855, + "preloadCompleteEventMs": 3777, "run": 5 }, { - "allReadyMs": 5798, + "allReadyMs": 5738, "cold": true, - "configureMs": 2576, + "configureMs": 1785, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5696, - "data-v3-0ed9-2024-04-04": 4578, - "free-trial-v3-d8d7-2024-04-04": 5038, - "inimai---open-app-copy-c50c-2024-11-28": 3971, - "localized-paywall-e901-2024-04-04": 5139, - "price-tester-1b8e-2024-04-04": 3869, - "products-v3-60c5-2024-04-04": 5494, - "superwall-template-9f9f-2024-05-21": 4173, - "url-paywall-v3-3810-2024-04-04": 5290, - "video-v3-72b4-2024-04-04": 5798 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5283, + "data-v3-0ed9-2024-04-04": 5738, + "free-trial-v3-d8d7-2024-04-04": 4119, + "inimai---open-app-copy-c50c-2024-11-28": 3511, + "localized-paywall-e901-2024-04-04": 4677, + "price-tester-1b8e-2024-04-04": 4220, + "products-v3-60c5-2024-04-04": 4321, + "superwall-template-9f9f-2024-05-21": 3713, + "url-paywall-v3-3810-2024-04-04": 3967, + "video-v3-72b4-2024-04-04": 4930 }, - "preloadCompleteEventMs": 1189, + "preloadCompleteEventMs": 817, "run": 6 }, { - "allReadyMs": 5585, + "allReadyMs": 6679, "cold": true, - "configureMs": 1786, + "configureMs": 1902, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4877, - "data-v3-0ed9-2024-04-04": 5585, - "free-trial-v3-d8d7-2024-04-04": 3864, - "inimai---open-app-copy-c50c-2024-11-28": 3611, - "localized-paywall-e901-2024-04-04": 4016, - "price-tester-1b8e-2024-04-04": 3712, - "products-v3-60c5-2024-04-04": 4319, - "superwall-template-9f9f-2024-05-21": 3509, - "url-paywall-v3-3810-2024-04-04": 4421, - "video-v3-72b4-2024-04-04": 4168 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6224, + "data-v3-0ed9-2024-04-04": 6679, + "free-trial-v3-d8d7-2024-04-04": 5769, + "inimai---open-app-copy-c50c-2024-11-28": 4650, + "localized-paywall-e901-2024-04-04": 5870, + "price-tester-1b8e-2024-04-04": 4397, + "products-v3-60c5-2024-04-04": 4346, + "superwall-template-9f9f-2024-05-21": 4903, + "url-paywall-v3-3810-2024-04-04": 5360, + "video-v3-72b4-2024-04-04": 6376 }, - "preloadCompleteEventMs": 1228, + "preloadCompleteEventMs": 1359, "run": 7 }, { - "allReadyMs": 5140, + "allReadyMs": 5555, "cold": true, - "configureMs": 1755, + "configureMs": 1623, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4988, - "data-v3-0ed9-2024-04-04": 4583, - "free-trial-v3-d8d7-2024-04-04": 4178, - "inimai---open-app-copy-c50c-2024-11-28": 3468, - "localized-paywall-e901-2024-04-04": 5140, - "price-tester-1b8e-2024-04-04": 3367, - "products-v3-60c5-2024-04-04": 4330, - "superwall-template-9f9f-2024-05-21": 2957, - "url-paywall-v3-3810-2024-04-04": 3772, - "video-v3-72b4-2024-04-04": 3311 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5555, + "data-v3-0ed9-2024-04-04": 4797, + "free-trial-v3-d8d7-2024-04-04": 3937, + "inimai---open-app-copy-c50c-2024-11-28": 5252, + "localized-paywall-e901-2024-04-04": 4088, + "price-tester-1b8e-2024-04-04": 4038, + "products-v3-60c5-2024-04-04": 4544, + "superwall-template-9f9f-2024-05-21": 5049, + "url-paywall-v3-3810-2024-04-04": 4291, + "video-v3-72b4-2024-04-04": 4392 }, - "preloadCompleteEventMs": 670, + "preloadCompleteEventMs": 973, "run": 8 }, { - "allReadyMs": 5570, + "allReadyMs": 6490, "cold": true, - "configureMs": 1795, + "configureMs": 1726, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4659, - "data-v3-0ed9-2024-04-04": 4405, - "free-trial-v3-d8d7-2024-04-04": 4811, - "inimai---open-app-copy-c50c-2024-11-28": 3696, - "localized-paywall-e901-2024-04-04": 5570, - "price-tester-1b8e-2024-04-04": 4101, - "products-v3-60c5-2024-04-04": 5216, - "superwall-template-9f9f-2024-05-21": 3899, - "url-paywall-v3-3810-2024-04-04": 4912, - "video-v3-72b4-2024-04-04": 5064 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6490, + "data-v3-0ed9-2024-04-04": 5985, + "free-trial-v3-d8d7-2024-04-04": 5277, + "inimai---open-app-copy-c50c-2024-11-28": 4313, + "localized-paywall-e901-2024-04-04": 4465, + "price-tester-1b8e-2024-04-04": 4364, + "products-v3-60c5-2024-04-04": 4872, + "superwall-template-9f9f-2024-05-21": 4111, + "url-paywall-v3-3810-2024-04-04": 4973, + "video-v3-72b4-2024-04-04": 4668 }, - "preloadCompleteEventMs": 839, + "preloadCompleteEventMs": 1097, "run": 9 }, { - "allReadyMs": 5091, + "allReadyMs": 6062, "cold": true, - "configureMs": 1731, + "configureMs": 1465, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4231, - "data-v3-0ed9-2024-04-04": 4686, - "free-trial-v3-d8d7-2024-04-04": 3826, - "inimai---open-app-copy-c50c-2024-11-28": 3623, - "localized-paywall-e901-2024-04-04": 4383, - "price-tester-1b8e-2024-04-04": 4787, - "products-v3-60c5-2024-04-04": 5091, - "superwall-template-9f9f-2024-05-21": 3521, - "url-paywall-v3-3810-2024-04-04": 4889, - "video-v3-72b4-2024-04-04": 4990 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5857, + "data-v3-0ed9-2024-04-04": 5452, + "free-trial-v3-d8d7-2024-04-04": 4896, + "inimai---open-app-copy-c50c-2024-11-28": 4238, + "localized-paywall-e901-2024-04-04": 6062, + "price-tester-1b8e-2024-04-04": 4137, + "products-v3-60c5-2024-04-04": 5604, + "superwall-template-9f9f-2024-05-21": 4491, + "url-paywall-v3-3810-2024-04-04": 5047, + "video-v3-72b4-2024-04-04": 5149 }, - "preloadCompleteEventMs": 716, + "preloadCompleteEventMs": 1025, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 26.540019017822143, - "coldMeanMs": 6382.5, - "maxMs": 10612, - "meanMs": 6382.5, - "medianMs": 5684.5, - "minMs": 5091, + "coefficientOfVariationPct": 31.729301370688717, + "coldMeanMs": 7857.7, + "maxMs": 13684, + "meanMs": 7857.7, + "medianMs": 7197.0, + "minMs": 5555, "sampleCount": 10, - "stdDevMs": 1693.9167138124983, + "stdDevMs": 2493.1933138046074, "warmMeanMs": null }, "tier": "LOW" diff --git a/.benchmark/results/preload-benchmark-mid.json b/.benchmark/results/preload-benchmark-mid.json index 4c08f65eb..a2b1a7e17 100644 --- a/.benchmark/results/preload-benchmark-mid.json +++ b/.benchmark/results/preload-benchmark-mid.json @@ -11,226 +11,226 @@ "runCount": 10, "samples": [ { - "allReadyMs": 14565, + "allReadyMs": 14525, "cold": true, - "configureMs": 2321, + "configureMs": 3672, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 9504, - "data-v3-0ed9-2024-04-04": 8690, - "free-trial-v3-d8d7-2024-04-04": 13852, - "inimai---open-app-copy-c50c-2024-11-28": 14565, - "localized-paywall-e901-2024-04-04": 14004, - "price-tester-1b8e-2024-04-04": 9147, - "products-v3-60c5-2024-04-04": 10575, - "superwall-template-9f9f-2024-05-21": 8944, - "url-paywall-v3-3810-2024-04-04": 10149, - "video-v3-72b4-2024-04-04": 9758 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 8123, + "data-v3-0ed9-2024-04-04": 9318, + "free-trial-v3-d8d7-2024-04-04": 14525, + "inimai---open-app-copy-c50c-2024-11-28": 6515, + "localized-paywall-e901-2024-04-04": 13857, + "price-tester-1b8e-2024-04-04": 6261, + "products-v3-60c5-2024-04-04": 7024, + "superwall-template-9f9f-2024-05-21": 10570, + "url-paywall-v3-3810-2024-04-04": 9734, + "video-v3-72b4-2024-04-04": 8480 }, - "preloadCompleteEventMs": 1808, + "preloadCompleteEventMs": 1266, "run": 1 }, { - "allReadyMs": 8063, + "allReadyMs": 7657, "cold": true, - "configureMs": 1781, + "configureMs": 1416, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 8063, - "data-v3-0ed9-2024-04-04": 7504, - "free-trial-v3-d8d7-2024-04-04": 6024, - "inimai---open-app-copy-c50c-2024-11-28": 5720, - "localized-paywall-e901-2024-04-04": 6176, - "price-tester-1b8e-2024-04-04": 6581, - "products-v3-60c5-2024-04-04": 6995, - "superwall-template-9f9f-2024-05-21": 5466, - "url-paywall-v3-3810-2024-04-04": 6733, - "video-v3-72b4-2024-04-04": 6480 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 7402, + "data-v3-0ed9-2024-04-04": 6842, + "free-trial-v3-d8d7-2024-04-04": 7657, + "inimai---open-app-copy-c50c-2024-11-28": 4610, + "localized-paywall-e901-2024-04-04": 5877, + "price-tester-1b8e-2024-04-04": 6131, + "products-v3-60c5-2024-04-04": 5420, + "superwall-template-9f9f-2024-05-21": 4964, + "url-paywall-v3-3810-2024-04-04": 6487, + "video-v3-72b4-2024-04-04": 7046 }, - "preloadCompleteEventMs": 980, + "preloadCompleteEventMs": 1850, "run": 2 }, { - "allReadyMs": 11530, + "allReadyMs": 6774, "cold": true, - "configureMs": 2707, + "configureMs": 1607, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 10666, - "data-v3-0ed9-2024-04-04": 8671, - "free-trial-v3-d8d7-2024-04-04": 9904, - "inimai---open-app-copy-c50c-2024-11-28": 7955, - "localized-paywall-e901-2024-04-04": 9496, - "price-tester-1b8e-2024-04-04": 8824, - "products-v3-60c5-2024-04-04": 11530, - "superwall-template-9f9f-2024-05-21": 7597, - "url-paywall-v3-3810-2024-04-04": 10158, - "video-v3-72b4-2024-04-04": 10971 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 6317, + "data-v3-0ed9-2024-04-04": 6774, + "free-trial-v3-d8d7-2024-04-04": 5809, + "inimai---open-app-copy-c50c-2024-11-28": 5090, + "localized-paywall-e901-2024-04-04": 5505, + "price-tester-1b8e-2024-04-04": 5657, + "products-v3-60c5-2024-04-04": 5962, + "superwall-template-9f9f-2024-05-21": 4988, + "url-paywall-v3-3810-2024-04-04": 6470, + "video-v3-72b4-2024-04-04": 6063 }, - "preloadCompleteEventMs": 1893, + "preloadCompleteEventMs": 1472, "run": 3 }, { - "allReadyMs": 5794, + "allReadyMs": 5980, "cold": true, - "configureMs": 1570, + "configureMs": 1872, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5794, - "data-v3-0ed9-2024-04-04": 5186, - "free-trial-v3-d8d7-2024-04-04": 5490, - "inimai---open-app-copy-c50c-2024-11-28": 3966, - "localized-paywall-e901-2024-04-04": 4781, - "price-tester-1b8e-2024-04-04": 3763, - "products-v3-60c5-2024-04-04": 4680, - "superwall-template-9f9f-2024-05-21": 4169, - "url-paywall-v3-3810-2024-04-04": 5389, - "video-v3-72b4-2024-04-04": 4933 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5013, + "data-v3-0ed9-2024-04-04": 5980, + "free-trial-v3-d8d7-2024-04-04": 4097, + "inimai---open-app-copy-c50c-2024-11-28": 4709, + "localized-paywall-e901-2024-04-04": 4352, + "price-tester-1b8e-2024-04-04": 4250, + "products-v3-60c5-2024-04-04": 5166, + "superwall-template-9f9f-2024-05-21": 3586, + "url-paywall-v3-3810-2024-04-04": 3739, + "video-v3-72b4-2024-04-04": 4200 }, - "preloadCompleteEventMs": 1165, + "preloadCompleteEventMs": 1127, "run": 4 }, { - "allReadyMs": 6903, + "allReadyMs": 6088, "cold": true, - "configureMs": 1797, + "configureMs": 1604, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5231, - "data-v3-0ed9-2024-04-04": 6802, - "free-trial-v3-d8d7-2024-04-04": 6396, - "inimai---open-app-copy-c50c-2024-11-28": 4519, - "localized-paywall-e901-2024-04-04": 6903, - "price-tester-1b8e-2024-04-04": 5686, - "products-v3-60c5-2024-04-04": 5889, - "superwall-template-9f9f-2024-05-21": 4721, - "url-paywall-v3-3810-2024-04-04": 4316, - "video-v3-72b4-2024-04-04": 5788 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5781, + "data-v3-0ed9-2024-04-04": 6088, + "free-trial-v3-d8d7-2024-04-04": 5014, + "inimai---open-app-copy-c50c-2024-11-28": 4302, + "localized-paywall-e901-2024-04-04": 5369, + "price-tester-1b8e-2024-04-04": 4658, + "products-v3-60c5-2024-04-04": 4811, + "superwall-template-9f9f-2024-05-21": 4556, + "url-paywall-v3-3810-2024-04-04": 4201, + "video-v3-72b4-2024-04-04": 5521 }, - "preloadCompleteEventMs": 1660, + "preloadCompleteEventMs": 1153, "run": 5 }, { - "allReadyMs": 7060, + "allReadyMs": 5303, "cold": true, - "configureMs": 2049, + "configureMs": 2237, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4065, - "data-v3-0ed9-2024-04-04": 5946, - "free-trial-v3-d8d7-2024-04-04": 5541, - "inimai---open-app-copy-c50c-2024-11-28": 4419, - "localized-paywall-e901-2024-04-04": 5185, - "price-tester-1b8e-2024-04-04": 6099, - "products-v3-60c5-2024-04-04": 7060, - "superwall-template-9f9f-2024-05-21": 4268, - "url-paywall-v3-3810-2024-04-04": 5084, - "video-v3-72b4-2024-04-04": 5338 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5303, + "data-v3-0ed9-2024-04-04": 5100, + "free-trial-v3-d8d7-2024-04-04": 3981, + "inimai---open-app-copy-c50c-2024-11-28": 4694, + "localized-paywall-e901-2024-04-04": 4032, + "price-tester-1b8e-2024-04-04": 3321, + "products-v3-60c5-2024-04-04": 4286, + "superwall-template-9f9f-2024-05-21": 3778, + "url-paywall-v3-3810-2024-04-04": 4490, + "video-v3-72b4-2024-04-04": 4388 }, - "preloadCompleteEventMs": 1130, + "preloadCompleteEventMs": 829, "run": 6 }, { - "allReadyMs": 5605, + "allReadyMs": 5828, "cold": true, - "configureMs": 1177, + "configureMs": 1769, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5200, - "data-v3-0ed9-2024-04-04": 5605, - "free-trial-v3-d8d7-2024-04-04": 4128, - "inimai---open-app-copy-c50c-2024-11-28": 3824, - "localized-paywall-e901-2024-04-04": 4691, - "price-tester-1b8e-2024-04-04": 3926, - "products-v3-60c5-2024-04-04": 3469, - "superwall-template-9f9f-2024-05-21": 3672, - "url-paywall-v3-3810-2024-04-04": 4590, - "video-v3-72b4-2024-04-04": 4897 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4915, + "data-v3-0ed9-2024-04-04": 5828, + "free-trial-v3-d8d7-2024-04-04": 4152, + "inimai---open-app-copy-c50c-2024-11-28": 4457, + "localized-paywall-e901-2024-04-04": 4254, + "price-tester-1b8e-2024-04-04": 4711, + "products-v3-60c5-2024-04-04": 5118, + "superwall-template-9f9f-2024-05-21": 3898, + "url-paywall-v3-3810-2024-04-04": 3593, + "video-v3-72b4-2024-04-04": 5219 }, - "preloadCompleteEventMs": 641, + "preloadCompleteEventMs": 1094, "run": 7 }, { - "allReadyMs": 5650, + "allReadyMs": 6084, "cold": true, - "configureMs": 2615, + "configureMs": 1906, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4990, - "data-v3-0ed9-2024-04-04": 5650, - "free-trial-v3-d8d7-2024-04-04": 4635, - "inimai---open-app-copy-c50c-2024-11-28": 3710, - "localized-paywall-e901-2024-04-04": 4173, - "price-tester-1b8e-2024-04-04": 4480, - "products-v3-60c5-2024-04-04": 5142, - "superwall-template-9f9f-2024-05-21": 3912, - "url-paywall-v3-3810-2024-04-04": 4378, - "video-v3-72b4-2024-04-04": 4736 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4611, + "data-v3-0ed9-2024-04-04": 6084, + "free-trial-v3-d8d7-2024-04-04": 5170, + "inimai---open-app-copy-c50c-2024-11-28": 3697, + "localized-paywall-e901-2024-04-04": 5220, + "price-tester-1b8e-2024-04-04": 4104, + "products-v3-60c5-2024-04-04": 4967, + "superwall-template-9f9f-2024-05-21": 3901, + "url-paywall-v3-3810-2024-04-04": 4358, + "video-v3-72b4-2024-04-04": 4205 }, - "preloadCompleteEventMs": 987, + "preloadCompleteEventMs": 1022, "run": 8 }, { - "allReadyMs": 5953, + "allReadyMs": 5352, "cold": true, - "configureMs": 1752, + "configureMs": 1733, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5397, - "data-v3-0ed9-2024-04-04": 5953, - "free-trial-v3-d8d7-2024-04-04": 4941, - "inimai---open-app-copy-c50c-2024-11-28": 4179, - "localized-paywall-e901-2024-04-04": 5498, - "price-tester-1b8e-2024-04-04": 4789, - "products-v3-60c5-2024-04-04": 5144, - "superwall-template-9f9f-2024-05-21": 4077, - "url-paywall-v3-3810-2024-04-04": 4381, - "video-v3-72b4-2024-04-04": 4687 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 4946, + "data-v3-0ed9-2024-04-04": 5352, + "free-trial-v3-d8d7-2024-04-04": 4541, + "inimai---open-app-copy-c50c-2024-11-28": 3777, + "localized-paywall-e901-2024-04-04": 4338, + "price-tester-1b8e-2024-04-04": 3421, + "products-v3-60c5-2024-04-04": 4186, + "superwall-template-9f9f-2024-05-21": 3675, + "url-paywall-v3-3810-2024-04-04": 5047, + "video-v3-72b4-2024-04-04": 4693 }, - "preloadCompleteEventMs": 934, + "preloadCompleteEventMs": 1132, "run": 9 }, { - "allReadyMs": 6119, + "allReadyMs": 5564, "cold": true, - "configureMs": 1805, + "configureMs": 1165, "index": 0, "paywallCount": 10, "perPaywallReadyMs": { - "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5816, - "data-v3-0ed9-2024-04-04": 5358, - "free-trial-v3-d8d7-2024-04-04": 4801, - "inimai---open-app-copy-c50c-2024-11-28": 3989, - "localized-paywall-e901-2024-04-04": 4953, - "price-tester-1b8e-2024-04-04": 4243, - "products-v3-60c5-2024-04-04": 6119, - "superwall-template-9f9f-2024-05-21": 3888, - "url-paywall-v3-3810-2024-04-04": 4192, - "video-v3-72b4-2024-04-04": 4446 + "based-on-teleprompter-bigvu-template-2b72-2024-04-04": 5055, + "data-v3-0ed9-2024-04-04": 5564, + "free-trial-v3-d8d7-2024-04-04": 4238, + "inimai---open-app-copy-c50c-2024-11-28": 4085, + "localized-paywall-e901-2024-04-04": 4339, + "price-tester-1b8e-2024-04-04": 3679, + "products-v3-60c5-2024-04-04": 4799, + "superwall-template-9f9f-2024-05-21": 3933, + "url-paywall-v3-3810-2024-04-04": 4645, + "video-v3-72b4-2024-04-04": 4543 }, - "preloadCompleteEventMs": 1117, + "preloadCompleteEventMs": 1089, "run": 10 } ], "schemaVersion": 1, "stats": { - "coefficientOfVariationPct": 38.777496472291425, - "coldMeanMs": 7724.2, - "maxMs": 14565, - "meanMs": 7724.2, - "medianMs": 6511.0, - "minMs": 5605, + "coefficientOfVariationPct": 39.974661479048976, + "coldMeanMs": 6915.5, + "maxMs": 14525, + "meanMs": 6915.5, + "medianMs": 6032.0, + "minMs": 5303, "sampleCount": 10, - "stdDevMs": 2995.251382512734, + "stdDevMs": 2764.447714583632, "warmMeanMs": null }, "tier": "MID" From 0964503e5e8c8a3266429be860a954a15508443c Mon Sep 17 00:00:00 2001 From: Ian Rumac Date: Wed, 22 Jul 2026 13:31:52 +0200 Subject: [PATCH 11/12] Improve tests, ensure getPresentationResult doesnt break live pw --- app/build.gradle.kts | 3 - .../superapp/test/PaywallHostFragment.kt | 11 +- .../example/superapp/test/RepresentTests.kt | 130 +++++++++++++---- app/src/debug/AndroidManifest.xml | 7 + .../superapp/test/PaywallHostActivity.kt | 26 ++++ app/src/main/AndroidManifest.xml | 6 - .../test/PaywallFragmentTestActivity.kt | 137 ------------------ gradle/libs.versions.toml | 3 - .../sdk/paywall/manager/PaywallManager.kt | 9 +- .../sdk/paywall/manager/PaywallManagerTest.kt | 27 ++++ 10 files changed, 174 insertions(+), 185 deletions(-) create mode 100644 app/src/debug/java/com/superwall/superapp/test/PaywallHostActivity.kt delete mode 100644 app/src/main/java/com/superwall/superapp/test/PaywallFragmentTestActivity.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ab45ed252..d69a10500 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -113,15 +113,12 @@ dependencies { androidTestImplementation(libs.test.runner) androidTestImplementation(libs.mockk.android) androidTestImplementation(libs.mockk.core) - androidTestImplementation(libs.androidx.fragment.testing) androidTestUtil(libs.orchestrator) // Debug // debugImplementation(libs.leakcanary.android) debugImplementation(libs.ui.tooling) debugImplementation(libs.ui.test.manifest) - // Provides FragmentScenario's empty host activity in the debug manifest. - debugImplementation(libs.androidx.fragment.testing.manifest) } tasks.register("pullEventTimelines") { diff --git a/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt b/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt index 41f662fad..a06ac463e 100644 --- a/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt +++ b/app/src/androidTest/java/com/example/superapp/test/PaywallHostFragment.kt @@ -44,14 +44,9 @@ class PaywallHostFragment : Fragment() { savedInstanceState: Bundle?, ): View = FrameLayout(requireContext()).also { this.container = it } - override fun onViewCreated( - view: View, - savedInstanceState: Bundle?, - ) { - super.onViewCreated(view, savedInstanceState) - // On view-create, embed the paywall exactly as the customer's fragment does. - present() - } + // NOTE: no auto-present on view-create. The SDK's config fetch is gated on the app + // being in the FOREGROUND (Network.getConfig -> awaitUntilAppInForeground), so the + // test must launch this host first, await Configured, and only then call [present]. /** * Obtains the embedded paywall via the public [PaywallBuilder]/`getPaywall` API and diff --git a/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt b/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt index e3bed08b9..8a38b561a 100644 --- a/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt +++ b/app/src/androidTest/java/com/example/superapp/test/RepresentTests.kt @@ -1,15 +1,13 @@ package com.example.superapp.test import android.app.Application -import androidx.fragment.app.testing.launchFragmentInContainer +import androidx.test.core.app.ActivityScenario import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import androidx.test.uiautomator.By import androidx.test.uiautomator.UiDevice -import androidx.test.uiautomator.UiSelector import androidx.test.uiautomator.Until import com.example.superapp.utils.awaitUntilWebviewAppears -import com.example.superapp.utils.clickButtonWith import com.superwall.sdk.Superwall import com.superwall.sdk.analytics.superwall.SuperwallEvent import com.superwall.sdk.analytics.superwall.SuperwallEventInfo @@ -22,6 +20,7 @@ import com.superwall.sdk.models.entitlements.SubscriptionStatus import com.superwall.sdk.paywall.view.delegate.PaywallLoadingState import com.superwall.sdk.store.testmode.TestModeBehavior import com.superwall.superapp.Keys +import com.superwall.superapp.test.PaywallHostActivity import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async @@ -38,7 +37,7 @@ import org.junit.runner.RunWith import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds -//@RunWith(AndroidJUnit4::class) +@RunWith(AndroidJUnit4::class) class RepresentTests { companion object { /** @@ -63,9 +62,10 @@ class RepresentTests { // Test-mode purchase drawer confirm button (set in TestModePurchaseDrawer). private const val CONFIRM_PURCHASE_TEXT = "Confirm Purchase" - // Unique substring of the test-mode activation modal (dashboard hint row), - // used to detect the modal without colliding with paywall/webview text. - private const val TEST_MODE_MODAL_HINT = "Configure test mode users" + // Unique substring of the test-mode activation modal (its title row reads + // "✏️ Test Mode Active"), used to detect the modal without colliding with + // paywall/webview text. + private const val TEST_MODE_MODAL_HINT = "Test Mode Active" private val EVENT_TIMEOUT = 30.seconds private val UI_TIMEOUT_MS = 30_000L @@ -110,23 +110,26 @@ class RepresentTests { @Test fun test_represent_after_consumable_purchase_reinvokes_purchase() = runBlocking { + // Launch the host FIRST: the SDK only fetches config once the app is in the + // foreground (Network.getConfig gates on awaitUntilAppInForeground), so waiting + // for Configured before showing an activity deadlocks. + val scenario = launchHost() awaitConfigured() - val scenario = launchFragmentInContainer() - // First embedded presentation. + scenario.presentPaywall() dismissTestModeActivationModalIfPresent() assertTrue("First paywall never appeared", awaitUntilWebviewAppears()) delay(1.seconds) // First purchase. - clickButtonWith(BUY_BUTTON_TEXT) + tapText(BUY_BUTTON_TEXT) assertTrue( "Purchase drawer did not appear on the FIRST buy tap", awaitTextAppears(CONFIRM_PURCHASE_TEXT), ) val firstComplete = awaitEventAsync { it is SuperwallEvent.TransactionComplete } - clickButtonWith(CONFIRM_PURCHASE_TEXT) + tapText(CONFIRM_PURCHASE_TEXT) assertNotNull("First purchase never completed", firstComplete.await()) // The embedded paywall isn't dismissed (no full-screen activity to finish); // just wait for the test-mode drawer to close so the re-tap detects a FRESH drawer. @@ -135,13 +138,13 @@ class RepresentTests { // Re-obtain/re-attach the SAME placement via the embedded API (reuses the cached // PaywallView through PaywallManager.getPaywallView's cache-hit reset). - scenario.onFragment { it.present() } + scenario.presentPaywall() dismissTestModeActivationModalIfPresent() assertTrue("Re-presented paywall never appeared", awaitUntilWebviewAppears()) delay(1.seconds) // Tap buy AGAIN — dead pre-fix, alive post-fix (PR #434). - clickButtonWith(BUY_BUTTON_TEXT) + tapText(BUY_BUTTON_TEXT) assertTrue( "Re-presented paywall's buy tap did NOT re-invoke the purchase flow — " + "stale transient presentation state regression (PR #434)", @@ -159,28 +162,29 @@ class RepresentTests { @Test fun test_represent_resets_loading_state() = runBlocking { + // Foreground-first, same as test 1 (config fetch is gated on foreground). + val scenario = launchHost() awaitConfigured() - val scenario = launchFragmentInContainer() - + scenario.presentPaywall() dismissTestModeActivationModalIfPresent() assertTrue("First paywall never appeared", awaitUntilWebviewAppears()) delay(1.seconds) // Purchase once so a LoadingPurchase state exists to (previously) leak. - clickButtonWith(BUY_BUTTON_TEXT) + tapText(BUY_BUTTON_TEXT) assertTrue( "Purchase drawer did not appear on the buy tap", awaitTextAppears(CONFIRM_PURCHASE_TEXT), ) val complete = awaitEventAsync { it is SuperwallEvent.TransactionComplete } - clickButtonWith(CONFIRM_PURCHASE_TEXT) + tapText(CONFIRM_PURCHASE_TEXT) assertNotNull("Purchase never completed", complete.await()) awaitTextDisappears(CONFIRM_PURCHASE_TEXT) delay(1.seconds) // Re-obtain/re-attach the cached embedded paywall (exercises the cache-hit reset). - scenario.onFragment { it.present() } + scenario.presentPaywall() dismissTestModeActivationModalIfPresent() assertTrue("Re-presented paywall never appeared", awaitUntilWebviewAppears()) delay(1.seconds) @@ -199,27 +203,81 @@ class RepresentTests { // region helpers private suspend fun awaitConfigured() { - Superwall.instance.configurationStateListener.first { it is ConfigurationStatus.Configured } - // Force a DEFINITE entitlement status. On CI emulators Google Play Billing is - // unavailable (developer error 5), so the status otherwise stays `Unknown` and + // Force a DEFINITE entitlement status up front. On CI emulators Google Play Billing + // is unavailable (developer error 5), so the status otherwise stays `Unknown` and // paywall presentation is SKIPPED with `subscription_status_timeout` (the status - // stayed "unknown" for >5s). `Inactive` means "no entitlements" so the non-gated - // paywall still presents. Mirrors every paywall-presenting test in `UITestHandler`. + // stayed "unknown" for >5s) — including the implicit app_install attempt that fires + // during configure. `Inactive` means "no entitlements" so the non-gated paywall + // still presents. Mirrors every paywall-presenting test in `UITestHandler`. Superwall.instance.setSubscriptionStatus(SubscriptionStatus.Inactive) + // Bounded wait: a hang here must fail loudly with the actual state, not stall the + // suite forever (configurationStateListener never emits Configured if config load + // fails or wedges — `first {}` would otherwise suspend indefinitely). + val configured = + withTimeoutOrNull(EVENT_TIMEOUT) { + Superwall.instance.configurationStateListener.first { it is ConfigurationStatus.Configured } + } + assertNotNull( + "Superwall never reached Configured within $EVENT_TIMEOUT; " + + "last state = ${Superwall.instance.configurationState}", + configured, + ) + } + + /** + * Launches the debug-source-set host activity (it must live in the app APK so + * ActivityScenario can launch it into the app's process — see the KDoc on + * [PaywallHostActivity]) and commits [PaywallHostFragment] into its container, + * keeping all test logic in this source set. + */ + private fun launchHost(): ActivityScenario { + val scenario = ActivityScenario.launch(PaywallHostActivity::class.java) + scenario.onActivity { + it.supportFragmentManager + .beginTransaction() + .replace(PaywallHostActivity.CONTAINER_ID, PaywallHostFragment()) + .commitNow() + } + return scenario + } + + private fun ActivityScenario.presentPaywall() { + onActivity { + val fragment = + it.supportFragmentManager.findFragmentById(PaywallHostActivity.CONTAINER_ID) + (fragment as PaywallHostFragment).present() + } } private fun device() = UiDevice.getInstance(getInstrumentation()) /** * The ALWAYS test-mode activation modal auto-presents once (per just-activated - * session) and is non-cancelable. Detect it via its unique dashboard hint text and - * tap "Continue" to get past it. Best-effort: absent modal is not an error. + * session) and is non-cancelable (TestModeModal sets cancelable=false). Its + * "Continue" button sits BELOW THE FOLD of the collapsed bottom sheet, so after + * detecting the modal by its title, swipe the sheet up until the button is on + * screen, then tap it. Best-effort: absent modal is not an error. */ private suspend fun dismissTestModeActivationModalIfPresent() { val d = device() val modal = d.wait(Until.findObject(By.textContains(TEST_MODE_MODAL_HINT)), 10_000) if (modal != null) { - d.findObject(UiSelector().textContains("Continue")).click() + var continueButton = d.findObject(By.text("Continue")) + var swipes = 0 + while (continueButton == null && swipes < 6) { + d.swipe( + d.displayWidth / 2, + (d.displayHeight * 0.85).toInt(), + d.displayWidth / 2, + (d.displayHeight * 0.25).toInt(), + 15, + ) + d.waitForIdle() + continueButton = d.findObject(By.text("Continue")) + swipes++ + } + assertNotNull("Test-mode modal is up but its Continue button never appeared", continueButton) + continueButton!!.click() d.waitForIdle() delay(500.milliseconds) } @@ -230,6 +288,26 @@ class RepresentTests { timeoutMs: Long = UI_TIMEOUT_MS, ): Boolean = device().wait(Until.findObject(By.textContains(text)), timeoutMs) != null + /** + * Waits for [text] (webview or native) and taps it. Uses the By/Until API — the + * legacy [UiSelector]-based [clickButtonWith] takes a one-shot accessibility + * snapshot that can miss webview content. On failure, dumps the accessibility + * hierarchy to logcat so the actual on-screen tree is visible in CI logs. + */ + private fun tapText( + text: String, + timeoutMs: Long = UI_TIMEOUT_MS, + ) { + val obj = device().wait(Until.findObject(By.textContains(text)), timeoutMs) + if (obj == null) { + val dump = java.io.ByteArrayOutputStream() + device().dumpWindowHierarchy(dump) + println("!! tapText(\"$text\") FAILED. Accessibility hierarchy:\n$dump") + } + assertNotNull("Tap target \"$text\" never appeared within ${timeoutMs}ms", obj) + obj!!.click() + } + /** * Waits until [text] is no longer on screen (best-effort, bounded by [timeoutMs]). * Used after confirming a test-mode purchase so the subsequent buy re-tap detects a diff --git a/app/src/debug/AndroidManifest.xml b/app/src/debug/AndroidManifest.xml index fe90dc87a..018c29c4b 100644 --- a/app/src/debug/AndroidManifest.xml +++ b/app/src/debug/AndroidManifest.xml @@ -27,5 +27,12 @@ android:name="com.superwall.superapp.benchmark.BenchmarkForegroundActivity" android:exported="false" android:theme="@android:style/Theme.Material.Light" /> + + + diff --git a/app/src/debug/java/com/superwall/superapp/test/PaywallHostActivity.kt b/app/src/debug/java/com/superwall/superapp/test/PaywallHostActivity.kt new file mode 100644 index 000000000..f09d9f5d7 --- /dev/null +++ b/app/src/debug/java/com/superwall/superapp/test/PaywallHostActivity.kt @@ -0,0 +1,26 @@ +package com.superwall.superapp.test + +import android.os.Bundle +import android.view.View +import android.widget.FrameLayout +import androidx.fragment.app.FragmentActivity + +/** + * Bare fragment host for the `RepresentTests` androidTest suite. Debug-source-set only — + * ships in no release build and pulls in no test libraries. Like + * [com.superwall.superapp.benchmark.BenchmarkForegroundActivity], it must live in the app + * (not the test APK) so ActivityScenario can launch it into the app's process. + * + * The activity is deliberately empty: the test commits its own fragment into + * [CONTAINER_ID], keeping all test logic in the androidTest source set. + */ +class PaywallHostActivity : FragmentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(FrameLayout(this).apply { id = CONTAINER_ID }) + } + + companion object { + val CONTAINER_ID = View.generateViewId() + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 58ef72e0a..718027d43 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -52,12 +52,6 @@ android:label="@string/title_activity_uitest" android:theme="@style/Theme.MyApplication" /> - - diff --git a/app/src/main/java/com/superwall/superapp/test/PaywallFragmentTestActivity.kt b/app/src/main/java/com/superwall/superapp/test/PaywallFragmentTestActivity.kt deleted file mode 100644 index 445f3b5e4..000000000 --- a/app/src/main/java/com/superwall/superapp/test/PaywallFragmentTestActivity.kt +++ /dev/null @@ -1,137 +0,0 @@ -package com.superwall.superapp.test - -import android.os.Bundle -import android.view.Gravity -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Button -import android.widget.FrameLayout -import android.widget.LinearLayout -import androidx.appcompat.app.AppCompatActivity -import androidx.fragment.app.Fragment -import androidx.fragment.app.commit -import androidx.lifecycle.lifecycleScope -import com.superwall.sdk.paywall.presentation.get_paywall.builder.PaywallBuilder -import com.superwall.sdk.paywall.presentation.internal.state.PaywallResult -import com.superwall.sdk.paywall.view.PaywallView -import com.superwall.sdk.paywall.view.delegate.PaywallViewCallback -import kotlinx.coroutines.launch - -/** - * Manual, in-app analog of the `PaywallHostFragment` used by the `RepresentTests` - * androidTest suite. Lets you reproduce the PR #434 re-present regression by hand: - * embed a paywall in a [Fragment] via the public `getPaywall`/[PaywallBuilder] API, - * buy, then tap "Re-present paywall" to re-attach the SAME cached [PaywallView] and - * confirm the buy button is still alive. - * - * The androidTest [com.example.superapp.test.PaywallHostFragment] can't be launched by - * the running app (it lives in the androidTest source set), so this mirrors it in main. - */ -class PaywallFragmentTestActivity : AppCompatActivity() { - private val containerId = View.generateViewId() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - val root = - LinearLayout(this).apply { - orientation = LinearLayout.VERTICAL - layoutParams = - LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT, - ) - } - - val represent = - Button(this).apply { - text = "Re-present paywall" - setOnClickListener { - (supportFragmentManager.findFragmentById(containerId) as? EmbeddedPaywallFragment) - ?.present() - } - } - - val container = - FrameLayout(this).apply { - id = containerId - layoutParams = - LinearLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - 0, - ).apply { weight = 1f } - } - - root.addView(represent) - root.addView(container) - setContentView(root) - - if (savedInstanceState == null) { - supportFragmentManager.commit { - replace(containerId, EmbeddedPaywallFragment()) - } - } - } -} - -/** - * Embeds a paywall inside a [Fragment] via the public embed API - * ([PaywallBuilder] -> `Superwall.getPaywall`), NOT via `register`. Mirrors the - * customer's fragment-hosted setup from PR #434. Re-attaches the SAME cached - * [PaywallView] on each [present] call. - */ -class EmbeddedPaywallFragment : Fragment() { - // Same placement the RepresentTests suite uses. - var placement: String = "non_recurring_product" - - private lateinit var container: FrameLayout - private var paywallView: PaywallView? = null - - private val delegate = - object : PaywallViewCallback { - override fun onFinished( - paywall: PaywallView, - result: PaywallResult, - shouldDismiss: Boolean, - ) { - // no-op: keep the host alive for re-embedding. - } - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?, - ): View = FrameLayout(requireContext()).also { this.container = it } - - override fun onViewCreated( - view: View, - savedInstanceState: Bundle?, - ) { - super.onViewCreated(view, savedInstanceState) - present() - } - - fun present() { - viewLifecycleOwner.lifecycleScope.launch { - embedPaywall() - } - } - - private suspend fun embedPaywall() { - // Detach any previously-embedded instance before re-embedding the (cached) view. - paywallView?.let { (it.parent as? ViewGroup)?.removeView(it) } - - PaywallBuilder(placement) - .delegate(delegate) - .activity(requireActivity()) - .build() - .onSuccess { view -> - paywallView = view - (view.parent as? ViewGroup)?.removeView(view) - container.addView(view) - view.onViewCreated() - } - } -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ab33017f0..268687245 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -43,7 +43,6 @@ dokka = "2.1.0" detekt = "1.23.7" robolectric = "4.13" activity_ktx_version = "1.10.1" -fragment_version = "1.8.5" [libraries] # SQL @@ -111,8 +110,6 @@ test_core = { module = "androidx.test:core", version.ref = "test_runner_version" test_rules = { module = "androidx.test:rules", version.ref = "test_rules_version" } ui_test_junit4 = { module = "androidx.compose.ui:ui-test-junit4" } mockk_android = { module = "io.mockk:mockk-android", version.ref = "mockk_version" } -androidx-fragment-testing = { module = "androidx.fragment:fragment-testing", version.ref = "fragment_version" } -androidx-fragment-testing-manifest = { module = "androidx.fragment:fragment-testing-manifest", version.ref = "fragment_version" } # Debug ui_tooling = { module = "androidx.compose.ui:ui-tooling" } diff --git a/superwall/src/main/java/com/superwall/sdk/paywall/manager/PaywallManager.kt b/superwall/src/main/java/com/superwall/sdk/paywall/manager/PaywallManager.kt index 59f8d5313..bba42bb30 100644 --- a/superwall/src/main/java/com/superwall/sdk/paywall/manager/PaywallManager.kt +++ b/superwall/src/main/java/com/superwall/sdk/paywall/manager/PaywallManager.kt @@ -86,8 +86,13 @@ class PaywallManager( // leaked by a previous presentation that stopped without a finishing // teardown. This covers both the register()/full-screen path and the // embedded getPaywallView/getPaywall path, which both funnel through here. - // Guarded by !isPreloading so preloading never resets a live view. - view.resetTransientPresentationState() + // Guarded by !isPreloading so preloading never resets a live view, and by + // isForPresentation because getPresentationResult() (a pure query API) + // also fetches through here — a result check while this paywall is + // on screen mid-purchase must not wipe its live spinner or prepare flags. + if (isForPresentation) { + view.resetTransientPresentationState() + } } return@mapAsync view } diff --git a/superwall/src/test/java/com/superwall/sdk/paywall/manager/PaywallManagerTest.kt b/superwall/src/test/java/com/superwall/sdk/paywall/manager/PaywallManagerTest.kt index 72ea28d8c..3e5a4667e 100644 --- a/superwall/src/test/java/com/superwall/sdk/paywall/manager/PaywallManagerTest.kt +++ b/superwall/src/test/java/com/superwall/sdk/paywall/manager/PaywallManagerTest.kt @@ -191,6 +191,33 @@ class PaywallManagerTest { verify { mockView.resetTransientPresentationState() } } + @Test + fun test_getPaywallView_doesNotResetTransientState_forPresentationResultChecks() = + runTest { + // getPresentationResult() (a pure query API) fetches through getPaywallView with + // isPreloading = false but isForPresentation = false. A result check must never + // reset a live cached view's transient state (e.g. a spinner mid-purchase). + val paywall = + mockk { + every { identifier } returns "test_paywall" + } + val request = + mockk { + every { isDebuggerLaunched } returns false + } + val mockView = mockk(relaxed = true) + val delegate = mockk() + + coEvery { paywallRequestManager.getPaywall(any(), any()) } returns Either.Success(paywall) + every { cache.getPaywallView(any()) } returns mockView + every { mockView.callback = any() } just Runs + every { mockView.updateState(any()) } just Runs + + paywallManager.getPaywallView(request, isForPresentation = false, isPreloading = false, delegate) + + verify(exactly = 0) { mockView.resetTransientPresentationState() } + } + @Test fun test_getPaywallView_doesNotResetTransientState_whenPreloading() = runTest { From 3e0586c96e505d1640263733b82731131ad694c0 Mon Sep 17 00:00:00 2001 From: Ian Rumac Date: Wed, 22 Jul 2026 13:42:09 +0200 Subject: [PATCH 12/12] Ensure benchmark only runs on labels --- .github/workflows/preload-benchmark.yml | 26 +++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/.github/workflows/preload-benchmark.yml b/.github/workflows/preload-benchmark.yml index a1f972a0b..32f606cf1 100644 --- a/.github/workflows/preload-benchmark.yml +++ b/.github/workflows/preload-benchmark.yml @@ -1,4 +1,5 @@ -# Paywall preload benchmark — runs on PRs into main or develop. +# Paywall preload benchmark — opt-in only. Runs on PRs into main or develop +# that carry the `release` or `benchmark` label, or on manual dispatch. # # Measures the time from Superwall.preloadAllPaywalls() until every paywall for # the dev app's embedded API key reaches PaywallLoadingState.Ready, on 3 @@ -19,14 +20,16 @@ name: Paywall Preload Benchmark on: - # PRs into main (release) and develop (feature) both run the benchmark, so - # preload regressions surface before they land anywhere. + # PRs into main (release) and develop (feature) run the benchmark only when + # opted in with the `release` or `benchmark` label — it burns 3 emulators for + # up to 40 minutes, so it's not worth paying on every PR push. `labeled` is in + # the trigger list so adding the label to an open PR starts the run. pull_request: branches: [ main, develop ] - # Merges re-run the benchmark AND roll the baseline forward automatically, - # so release PRs always gate against the latest mainline numbers. - push: - branches: [ main, develop ] + types: [ opened, synchronize, reopened, labeled ] + # No push trigger: a merge into main/develop carries no labels, so it could + # never satisfy the opt-in. Roll the baseline forward with a manual dispatch + # (update_baseline: true) off the branch you want to become the new mainline. workflow_dispatch: inputs: update_baseline: @@ -43,6 +46,13 @@ jobs: build-apks: runs-on: ubuntu-latest timeout-minutes: 20 + # Opt-in guard: PRs need the `release` or `benchmark` label; manual + # dispatches always run. The downstream jobs `needs` this one, so they skip + # with it. + if: >- + github.event_name == 'workflow_dispatch' || + contains(github.event.pull_request.labels.*.name, 'release') || + contains(github.event.pull_request.labels.*.name, 'benchmark') steps: - name: Checkout code @@ -254,7 +264,7 @@ jobs: --config .benchmark/config.json \ --report .benchmark/REPORT.md \ --normalized-out .benchmark/results \ - ${{ (github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.update_baseline)) && '--update-baseline' || '' }} + ${{ (github.event_name == 'workflow_dispatch' && inputs.update_baseline) && '--update-baseline' || '' }} echo "exit_code=$?" >> "$GITHUB_OUTPUT" - name: Publish report to job summary