Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ sample ships to both platforms; its flows are split because some assertions
are platform-specific (iOS accessibility-label patterns vs Android resource
strings).

The React Native Android checkout flow submits payment and waits for the order
confirmation screen. The React Native iOS checkout flow currently stops at
`Pay now`; the store/address path can show a checkout-web shipping availability
banner after submit, which is outside the Checkout Kit integration contract.

Folders are created when their first flow lands. Don't pre-create empty
directories.

Expand All @@ -35,7 +40,7 @@ Use these in the `appId:` header of every flow. Don't invent new bundle ids.
| `swift/` | `com.shopify.example.MobileBuyIntegration` |
| `android/` | `com.shopify.checkout_kit_mobile_buy_integration_sample` |
| `react-native/ios/` | `com.shopify.example.CheckoutKitReactNative` |
| `react-native/android/` | `com.shopify.example.CheckoutKitReactNative` |
| `react-native/android/` | `com.shopify.checkoutkitreactnative` |

## Running

Expand All @@ -48,7 +53,7 @@ terminal.
| React Native, iOS | `platforms/react-native/` | `pnpm e2e:ios` |
| Swift, iOS | TBD | TBD |
| Android (native) | TBD | TBD |
| RN, Android | TBD | TBD |
| RN, Android | `platforms/react-native/` | `pnpm e2e:android` |

Maestro itself is a system CLI, not an npm dependency. Install once with:

Expand All @@ -61,7 +66,8 @@ curl -fsSL "https://get.maestro.mobile.dev" | bash
1. Drop a new `<name>.yaml` under the right folder.
2. Set `appId:` from the table above.
3. Keep timeouts in the existing tiers (in-app interactions ~10s, network
transitions ~30s, cold starts and checkout first-paint ~60s).
transitions ~30s, cold starts, checkout first-paint, and order confirmation
~60s).
4. If the flow needs an npm script wrapper, add an `e2e:<platform>` script to
the matching `package.json` next to existing scripts. The script should
point at the folder, not an individual file, so the whole folder runs.
Expand Down
173 changes: 173 additions & 0 deletions e2e/react-native/android/checkout-completion.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
appId: com.shopify.checkoutkitreactnative
name: Checkout completes
tags:
- android
- checkout

# Override these for store-specific product and shipping-address data.
env:
PRODUCT_INDEX: ${PRODUCT_INDEX || "1"}
COUNTRY: ${COUNTRY || "United States"}
ADDRESS_LINE1: ${ADDRESS_LINE1 || "350 5th Ave"}
CITY: ${CITY || "New York"}
POSTAL_CODE: ${POSTAL_CODE || "10118"}
POSTAL_FIELD: ${POSTAL_FIELD || "ZIP code"}
---
# Timeout tiers:
# 10000 - in-app interactions (taps, animations)
# 30000 - checkout step transitions (network)
# 60000 - cold starts, first checkout paint, final confirmation

# Product and cart
- launchApp:
clearState: true
- extendedWaitUntil:
visible:
id: product-0-add-to-cart-button
timeout: 60000
- scrollUntilVisible:
element:
id: product-${PRODUCT_INDEX}-add-to-cart-button
direction: DOWN
timeout: 10000
centerElement: true
- tapOn:
id: product-${PRODUCT_INDEX}-add-to-cart-button
enabled: true
- waitForAnimationToEnd:
timeout: 10000
- tapOn:
id: cart-tab
- extendedWaitUntil:
visible:
id: checkout-button
timeout: 30000
- tapOn:
id: checkout-button
enabled: true

# Contact
- extendedWaitUntil:
visible:
text: "^Email( or mobile phone number)?$"
timeout: 60000
- tapOn:
text: "^Email( or mobile phone number)?$"
- inputText: "maestro.e2e@shopify.com"
- hideKeyboard
- tapOn:
text: "^First name( \\(optional\\))?$"
- inputText: "Maestro"
- hideKeyboard
- tapOn:
text: "^Last name$"
- inputText: "Shopify"
- hideKeyboard

# Shipping address
- scrollUntilVisible:
element:
text: "Country/Region"
direction: DOWN
timeout: 10000
- tapOn:
text: "Country/Region"
index: 1
- waitForAnimationToEnd:
timeout: 3000
- scrollUntilVisible:
element:
text: "^${COUNTRY}$"
direction: UP
timeout: 10000
visibilityPercentage: 50
centerElement: true
optional: true
- runFlow:
when:
notVisible: "^${COUNTRY}$"
commands:
- scrollUntilVisible:
element:
text: "^${COUNTRY}$"
direction: DOWN
timeout: 30000
visibilityPercentage: 50
centerElement: true
- tapOn:
text: "^${COUNTRY}$"
- waitForAnimationToEnd:
timeout: 3000

- scrollUntilVisible:
element:
text: "Address"
direction: DOWN
timeout: 10000
- tapOn:
text: "Address"
index: -1
- eraseText: 80
- scrollUntilVisible:
element:
text: "^${POSTAL_FIELD}$"
direction: DOWN
timeout: 10000
centerElement: true
- inputText: "${ADDRESS_LINE1} ${CITY} ${POSTAL_CODE}"
- extendedWaitUntil:
visible: ".*${ADDRESS_LINE1}, ${CITY}.*${POSTAL_CODE}.*${COUNTRY}.*"
timeout: 30000
- waitForAnimationToEnd:
timeout: 2000
- tapOn:
text: ".*${ADDRESS_LINE1}, ${CITY}.*${POSTAL_CODE}.*${COUNTRY}.*"
index: 0
retryTapIfNoChange: true
- waitForAnimationToEnd:
timeout: 5000
- extendedWaitUntil:
visible: "^${POSTAL_CODE}$"
timeout: 15000
- hideKeyboard
- waitForAnimationToEnd:
timeout: 5000

# Payment
- scrollUntilVisible:
element:
text: "^Card number$"
direction: DOWN
timeout: 30000
centerElement: true
- tapOn:
text: "^Card number$"
- inputText: "4242424242424242"
- hideKeyboard
- tapOn: "Expiration date (MM / YY)"
- inputText: "1230"
- hideKeyboard
- tapOn:
text: "^Security code$"
- inputText: "123"
- hideKeyboard
- scrollUntilVisible:
element:
text: "^Name on card$"
direction: DOWN
timeout: 30000
centerElement: true
- scrollUntilVisible:
element:
text: "^Pay now$"
direction: DOWN
timeout: 30000
- extendedWaitUntil:
visible: "^Pay now$"
timeout: 30000
- tapOn:
text: "^Pay now$"
enabled: true
- extendedWaitUntil:
visible: ".*(Thank you|[Oo]rder (is )?confirmed).*"
timeout: 60000
3 changes: 2 additions & 1 deletion platforms/react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
"compare-snapshot": "./scripts/compare_snapshot",
"turbo": "turbo",
"test": "jest",
"e2e:ios": "maestro --platform ios test --config ../../e2e/config.yaml ../../e2e/react-native/ios"
"e2e:ios": "maestro --platform ios test --config ../../e2e/config.yaml ../../e2e/react-native/ios",
"e2e:android": "maestro --platform android test --config ../../e2e/config.yaml ../../e2e/react-native/android"
},
"devDependencies": {
"@babel/core": "^7.25.2",
Expand Down
Loading