diff --git a/dev.yml b/dev.yml index f0dd1048c..e2257d711 100644 --- a/dev.yml +++ b/dev.yml @@ -93,6 +93,19 @@ commands: /opt/dev/bin/dev react-native test /opt/dev/bin/dev web test + e2e: + desc: Run shared Maestro checkout smoke flows + run: | + echo "Usage: dev e2e {rn-ios|rn-android}" >&2 + exit 1 + subcommands: + rn-ios: + desc: Run the React Native iOS Maestro guest checkout smoke flow + run: /opt/dev/bin/dev react-native e2e ios + rn-android: + desc: Run the React Native Android Maestro guest checkout smoke flow + run: /opt/dev/bin/dev react-native e2e android + apollo: desc: "Apollo GraphQL schema and code generation commands" subcommands: @@ -405,6 +418,18 @@ commands: USE_LOCAL_SDK=1 ./scripts/publish_android_snapshot cd sample/android USE_LOCAL_SDK=1 ./gradlew :shopify_checkout-kit-react-native:test --refresh-dependencies + e2e: + desc: Run React Native sample Maestro guest checkout smoke flows + run: | + echo "Usage: dev rn e2e {ios|android}" >&2 + exit 1 + subcommands: + ios: + desc: Run the React Native iOS Maestro guest checkout smoke flow + run: cd platforms/react-native && ./scripts/e2e_maestro_ios + android: + desc: Run the React Native Android Maestro guest checkout smoke flow + run: cd platforms/react-native && ./scripts/e2e_maestro_android lint: desc: Run all React Native lint checks (Swift, module, sample) aliases: [style] diff --git a/e2e/README.md b/e2e/README.md index 0973a1c1d..fc07ff979 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -1,12 +1,42 @@ # Checkout Kit End-to-End Tests -This directory is reserved for cross-platform end-to-end tests. There is no runnable e2e suite checked in yet. +This directory contains Maestro end-to-end smoke flows for Checkout Kit sample +apps. -Planned coverage: +The current runnable suite starts with React Native. It verifies a full guest +checkout from a seeded cart in the sample app, through Shopify checkout, and +back to the app after completion. -- Swift checkout presentation and protocol lifecycle. -- Android checkout presentation and protocol lifecycle. -- React Native wrapper behavior. -- Web component open/close and `checkout:*` events. +## Run locally -Until this directory contains test code, use the platform test suites and sample apps described in each platform README. +Run the matching command from the repo root. + +React Native iOS: + +```bash +dev e2e rn-ios +``` + +React Native Android: + +```bash +dev e2e rn-android +``` + +The React Native commands start Metro if needed, build and launch the target +sample app, then run Maestro. + +## Files + +- `config.yaml` configures Maestro for shared platform behavior. +- `flows/` contains reusable Maestro subflows for app setup and checkout steps. +- `tests/react-native/full-guest-checkout.yaml` composes the React Native guest + checkout smoke test from those subflows. + +## Scope + +This smoke flow is intended to catch regressions in the React Native sample app +integration surface: cart bootstrap, checkout presentation, checkout +completion, and return to the sample app. It is not a replacement for +checkout-web's browser-based coverage or for future native Swift and Android +sample-app E2E coverage. diff --git a/platforms/react-native/package.json b/platforms/react-native/package.json index 7cefc87e6..37015e77a 100644 --- a/platforms/react-native/package.json +++ b/platforms/react-native/package.json @@ -38,7 +38,9 @@ "pod-install": "bash ./scripts/pod_install", "snapshot": "./scripts/create_snapshot", "compare-snapshot": "./scripts/compare_snapshot", - "test": "jest" + "test": "jest", + "e2e:ios": "maestro --platform ios test --config ../../e2e/config.yaml -e APP_ID=com.shopify.checkoutkit.reactnativedemo -e 'CART_BOOTSTRAP_LINK=com.shopify.checkoutkit.reactnativedemo://cart?productIndex=0&quantity=1' ../../e2e/tests/react-native/full-guest-checkout.yaml", + "e2e:android": "maestro --platform android test --config ../../e2e/config.yaml -e APP_ID=com.shopify.checkoutkit.reactnativedemo -e 'CART_BOOTSTRAP_LINK=com.shopify.checkoutkit.reactnativedemo://cart?productIndex=0&quantity=1' ../../e2e/tests/react-native/full-guest-checkout.yaml" }, "devDependencies": { "@babel/core": "^7.29.7", diff --git a/platforms/react-native/scripts/e2e_maestro_android b/platforms/react-native/scripts/e2e_maestro_android new file mode 100755 index 000000000..94935cd5f --- /dev/null +++ b/platforms/react-native/scripts/e2e_maestro_android @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +METRO_LOG="${TMPDIR:-/tmp}/checkout-kit-rn-android-metro.log" +METRO_PID="" + +metro_running() { + curl --silent --fail http://localhost:8081/status | grep -q "packager-status:running" +} + +cleanup() { + if [ -n "$METRO_PID" ]; then + kill "$METRO_PID" 2>/dev/null || true + fi +} + +wait_for_metro() { + for _ in $(seq 1 60); do + if metro_running; then + return 0 + fi + sleep 1 + done + + echo "Timed out waiting for Metro. Last log lines:" >&2 + tail -n 40 "$METRO_LOG" >&2 || true + return 1 +} + +cd "$ROOT_DIR" + +if ! metro_running; then + pnpm sample start --reset-cache >"$METRO_LOG" 2>&1 & + METRO_PID="$!" + trap cleanup EXIT +fi + +wait_for_metro +pnpm sample android +pnpm e2e:android diff --git a/platforms/react-native/scripts/e2e_maestro_ios b/platforms/react-native/scripts/e2e_maestro_ios new file mode 100755 index 000000000..c319f73ab --- /dev/null +++ b/platforms/react-native/scripts/e2e_maestro_ios @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +METRO_LOG="${TMPDIR:-/tmp}/checkout-kit-rn-ios-metro.log" +METRO_PID="" + +metro_running() { + curl --silent --fail http://localhost:8081/status | grep -q "packager-status:running" +} + +cleanup() { + if [ -n "$METRO_PID" ]; then + kill "$METRO_PID" 2>/dev/null || true + fi +} + +wait_for_metro() { + for _ in $(seq 1 60); do + if metro_running; then + return 0 + fi + sleep 1 + done + + echo "Timed out waiting for Metro. Last log lines:" >&2 + tail -n 40 "$METRO_LOG" >&2 || true + return 1 +} + +cd "$ROOT_DIR" + +if ! metro_running; then + pnpm sample start --reset-cache >"$METRO_LOG" 2>&1 & + METRO_PID="$!" + trap cleanup EXIT +fi + +wait_for_metro +pnpm sample ios --local +pnpm e2e:ios diff --git a/platforms/react-native/scripts/pod_install b/platforms/react-native/scripts/pod_install index f2e9b3159..f1ff76ee2 100755 --- a/platforms/react-native/scripts/pod_install +++ b/platforms/react-native/scripts/pod_install @@ -10,4 +10,9 @@ done cd sample/ios bundle check || bundle install -bundle exec pod install --repo-update + +if [ "${USE_LOCAL_SDK:-0}" = "1" ]; then + bundle exec pod update ShopifyCheckoutKit ShopifyCheckoutKit/AcceleratedCheckouts --repo-update +else + bundle exec pod install --repo-update +fi