From fa755514935bea06b475914dec372f8c8445afe9 Mon Sep 17 00:00:00 2001 From: Kieran Osgood Date: Tue, 4 Aug 2026 12:20:21 +0100 Subject: [PATCH 1/2] fix(sample-android): let a guest cart take the shop market The Android sample gave a guest cart a Canadian buyer identity. A country on the buyer identity picks the market, and the market decides the currency, the address form and its labels, so the Kotlin checkout rendered a Canadian form and totalled in CAD. The Swift and React Native samples send no buyer identity for a guest, so this one now sends none either. This is flake B4: the shared E2E fixture is a United States address, and checkout-guest failed on Kotlin Android while React Native Android passed the same test. Co-Authored-By: Claude Opus 5 (1M context) Assisted-By: devx/5b4b8d5b-690a-4389-841e-039723ade1da From 6f6a7d37a81625e583ce0a51054e91de750ea2ac Mon Sep 17 00:00:00 2001 From: Kieran Osgood Date: Wed, 5 Aug 2026 09:40:09 +0100 Subject: [PATCH 2/2] fix(e2e): tap only an enabled element when dismissing an iOS field The checkout page renders a disabled 24 by 22 pixel node whose accessibility text is "selected". The branch matched that node and tapped a fixed point after every text entry, so the next field never opened. Three tests failed across two targets. Guard the selector with a test. Add `e2e/flows/**` to the CI path filter, because no filter watched that directory and none of the flow guards ran. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/ci.yml | 1 + e2e/flows/checkout/dismiss-active-field.yaml | 11 +++++-- e2e/test/maestro_test_tags_test.rb | 30 ++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5b7aa3f5c..2dce65f9e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -113,6 +113,7 @@ jobs: - 'e2e/lib/**' - 'e2e/test/**' - 'e2e/scripts/**' + - 'e2e/flows/**' - 'e2e/tests/**' - 'e2e/config.yaml' - 'e2e/config/matrix.yml' diff --git a/e2e/flows/checkout/dismiss-active-field.yaml b/e2e/flows/checkout/dismiss-active-field.yaml index 40b8c6f90..4d8873829 100644 --- a/e2e/flows/checkout/dismiss-active-field.yaml +++ b/e2e/flows/checkout/dismiss-active-field.yaml @@ -14,12 +14,19 @@ appId: ${E2E_APP_ID} commands: - tapOn: "Done" - waitForAnimationToEnd +# The checkout page also renders a disabled 24 by 22 pixel node whose accessibility text is +# "selected". Without enabled: true the branch taps that node after every text entry, and the +# field that follows never opens. - runFlow: when: platform: ios - visible: "selected" + visible: + text: "selected" + enabled: true commands: - - tapOn: "selected" + - tapOn: + text: "selected" + enabled: true - waitForAnimationToEnd - runFlow: when: diff --git a/e2e/test/maestro_test_tags_test.rb b/e2e/test/maestro_test_tags_test.rb index e7c44130b..cbc1fe62a 100644 --- a/e2e/test/maestro_test_tags_test.rb +++ b/e2e/test/maestro_test_tags_test.rb @@ -155,6 +155,36 @@ def test_the_launch_flow_never_clears_app_state ) end + def test_the_dismiss_flow_only_taps_an_enabled_element + body = File.read(File.join(E2E_ROOT, "flows", "checkout", "dismiss-active-field.yaml")) + + refute_match( + /^\s*(?:visible|tapOn):\s*"selected"\s*$/, + body, + "a bare `selected` selector matches a disabled 24 by 22 pixel node on iOS, and Maestro " \ + "then taps the fixed point behind it after every text entry, so the selector must " \ + "also require enabled: true" + ) + end + + # The scripts filter is the only thing that selects the scripts-test job, and that job is the + # only thing that runs this file. Several guards here read flows/, so the filter must watch it. + def scripts_filter_paths + workflow = YAML.safe_load_file(File.expand_path("../.github/workflows/ci.yml", E2E_ROOT), aliases: true) + step = workflow.fetch("jobs").fetch("changes").fetch("steps").find { |candidate| candidate["id"] == "infra" } + + YAML.safe_load(step.fetch("with").fetch("filters")).fetch("scripts") + end + + def test_ci_runs_the_ruby_suite_when_a_flow_changes + assert_includes( + scripts_filter_paths, + "e2e/flows/**", + "the scripts filter in .github/workflows/ci.yml must watch e2e/flows/**, or a commit that " \ + "only edits a flow runs none of the guards in this file" + ) + end + def test_there_is_at_least_one_test_to_check refute_empty(test_files) refute_empty(shared_test_files)