diff --git a/e2e/README.md b/e2e/README.md index 9a317eccf..38fc359b3 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -52,7 +52,7 @@ enforces it. | Group | Tags | Rule | |---|---|---| -| Journey | `launch`, `cart`, `checkout`, `account` | Exactly one per test | +| Journey | `launch`, `cart`, `checkout`, `account`, `preload` | Exactly one per test | | Cost tier | `smoke`, `full` | Exactly one per test | | Quarantine | `flaky`, `wip` | Excluded by default, in `config.yaml` | | Platform capability | `ios-only`, `android-only` | Needs a `# Platform capability:` comment | diff --git a/e2e/config/matrix.yml b/e2e/config/matrix.yml index c342e7d8d..7e04a9739 100644 --- a/e2e/config/matrix.yml +++ b/e2e/config/matrix.yml @@ -45,6 +45,14 @@ applications: app_id: com.shopify.checkoutkit.androiddemo artifact_env: E2E_KOTLIN_ANDROID_APP_PATH ready_marker: checkout-kit-sample-ready + # The preload journey reads the native samples' PreloadState callbacks, which only the + # Swift and Kotlin samples surface, so the two native rows adopt it ahead of the others. + # An override replaces the default list rather than extending it, so it restates the + # defaults; dropping `checkout` here would silently retire that coverage on this row. + include_tags: + - launch + - checkout + - preload changed_files_filters: - android - protocolKotlin @@ -57,6 +65,11 @@ applications: app_id: com.shopify.checkoutkit.swiftdemo artifact_env: E2E_SWIFT_IOS_APP_PATH ready_marker: checkout-kit-sample-ready + # See kotlin-android: the override restates the defaults and adds the preload journey. + include_tags: + - launch + - checkout + - preload changed_files_filters: - swift - protocolSwift diff --git a/e2e/flows/checkout/assert-native-preload-ready.yaml b/e2e/flows/checkout/assert-native-preload-ready.yaml new file mode 100644 index 000000000..2c961c3d6 --- /dev/null +++ b/e2e/flows/checkout/assert-native-preload-ready.yaml @@ -0,0 +1,29 @@ +appId: ${E2E_APP_ID} +--- +- extendedWaitUntil: + visible: + id: preload-state-ready + timeout: 60000 + +# Pins the starting value, so a marker stuck on "observed" cannot pass the assertion below. +- assertVisible: + id: preload-cache-hit-none + +- tapOn: + id: checkout-button + +- extendedWaitUntil: + visible: "^(Email( or mobile phone number)?|Delivery|Card number)$" + timeout: 60000 + +# Preload completing is not proof that presentation reused it, so each sample republishes the +# SDK's own cache-hit diagnostic as this identifier. Swift installs a Logger and observes the +# message directly; Kotlin reads it from the app's own Logcat, which Android scopes to the +# calling UID. Same assertion on both platforms. +- tapOn: + id: shopify_checkout_kit_close_button + +- extendedWaitUntil: + visible: + id: preload-cache-hit-observed + timeout: 30000 diff --git a/e2e/test/e2e_matrix_to_browserstack_run_plan_test.rb b/e2e/test/e2e_matrix_to_browserstack_run_plan_test.rb index 99228a2b8..2bb307077 100644 --- a/e2e/test/e2e_matrix_to_browserstack_run_plan_test.rb +++ b/e2e/test/e2e_matrix_to_browserstack_run_plan_test.rb @@ -44,14 +44,26 @@ def test_a_run_executes_the_workspace_root_so_the_config_glob_resolves end def test_runs_carry_default_tags_and_the_other_platform_exclusion + # The native rows override their include list to adopt the preload journey, so the + # defaults are asserted on a row that still inherits them. + default_run = run_for("react-native-ios") ios_run = run_for("swift-ios") android_run = run_for("kotlin-android") - assert_equal ["launch", "checkout"], ios_run.fetch("include_tags") + assert_equal ["launch", "checkout"], default_run.fetch("include_tags") assert_equal ["flaky", "wip", "full", "android-only"], ios_run.fetch("exclude_tags") assert_equal ["flaky", "wip", "full", "ios-only"], android_run.fetch("exclude_tags") end + # Only the Swift and Kotlin samples expose the PreloadState callbacks the preload journey + # asserts on. React Native adopts the tag once its wrapper surfaces them. + def test_the_native_applications_adopt_the_preload_journey + assert_equal ["launch", "checkout", "preload"], run_for("swift-ios").fetch("include_tags") + assert_equal ["launch", "checkout", "preload"], run_for("kotlin-android").fetch("include_tags") + refute_includes run_for("react-native-ios").fetch("include_tags"), "preload" + refute_includes run_for("react-native-android").fetch("include_tags"), "preload" + end + def test_an_application_overrides_the_default_tags config = base_config config.fetch("applications").first["include_tags"] = ["launch", "checkout"] diff --git a/e2e/test/maestro_test_tags_test.rb b/e2e/test/maestro_test_tags_test.rb index cf17b50af..58210dfcc 100644 --- a/e2e/test/maestro_test_tags_test.rb +++ b/e2e/test/maestro_test_tags_test.rb @@ -5,7 +5,7 @@ class MaestroTestTagsTest < Minitest::Test E2E_ROOT = File.expand_path("..", __dir__) - JOURNEY_TAGS = ["launch", "cart", "checkout", "account"].freeze + JOURNEY_TAGS = ["launch", "cart", "checkout", "account", "preload"].freeze COST_TIER_TAGS = ["smoke", "full"].freeze QUARANTINE_TAGS = ["flaky", "wip"].freeze PLATFORM_TAGS = ["ios-only", "android-only"].freeze diff --git a/e2e/tests/shared/native-preload-ready.yaml b/e2e/tests/shared/native-preload-ready.yaml new file mode 100644 index 000000000..0585d0b71 --- /dev/null +++ b/e2e/tests/shared/native-preload-ready.yaml @@ -0,0 +1,14 @@ +appId: ${E2E_APP_ID} +name: Native preload ready reuse +tags: + - preload + - smoke + +env: + # Preload caches a checkout per buyer, so the identity is pinned rather than left to + # whatever the sample was last configured with. The cached entry this test asserts on + # is only reused when presentation resolves the same buyer the preload ran for. + E2E_CART_PARAMS: "productIndex=0&quantity=1&buyerIdentityMode=guest" +--- +- runFlow: ../../flows/app/bootstrap-cart-from-link.yaml +- runFlow: ../../flows/checkout/assert-native-preload-ready.yaml