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
9 changes: 7 additions & 2 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 Down
279 changes: 279 additions & 0 deletions e2e/react-native/android/checkout-completion.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,279 @@
appId: com.shopify.checkoutkitreactnative
name: Checkout submits and shows result
tags:
- android
- checkout

env:
# CI shipping fixture
COUNTRY_LABEL: "United States"
ADDRESS_LINE1: "700 S Flower St"
CITY: "Los Angeles"
STATE_FIELD_LABEL: "State"
STATE_LABEL: "California"
POSTAL_CODE: "90017"
POSTAL_FIELD_LABEL: "ZIP code"

# CI payment fixture
CARD_NUMBER: "1"
CARD_EXPIRY_DISPLAY: "12 / 30"
CARD_SECURITY_CODE: "123"
CARDHOLDER_NAME: "Maestro Shopify"

# Accepted terminal checkout states for this smoke test.
POST_SUBMIT_RESULT_PATTERN: ".*(Thank you|Your order|Order confirmed|confirmation|Shipping not available|There was a problem|declined|couldn.t process).*"
---
# Timeout tiers:
# 3000 - animation settles
# 5000 - local in-page interactions and optional probes
# 15000 - sample-app checkout transitions
# 60000 - cold starts, first checkout paint, final submit

# Product and cart
- launchApp:
clearState: true
- extendedWaitUntil:
visible:
id: product-0-add-to-cart-button
timeout: 60000
- scrollUntilVisible:
element:
id: product-0-add-to-cart-button
direction: DOWN
timeout: 5000
centerElement: true
- tapOn:
id: product-0-add-to-cart-button
enabled: true
- waitForAnimationToEnd:
timeout: 3000
- runFlow:
when:
visible:
id: header-cart-icon
commands:
- tapOn:
id: header-cart-icon
- runFlow:
when:
notVisible:
id: checkout-button
commands:
- tapOn:
id: cart-tab
- extendedWaitUntil:
visible:
id: checkout-button
timeout: 15000
- tapOn:
id: checkout-button
enabled: true

# Contact
- extendedWaitUntil:
visible:
text: "^Email( or mobile phone number)?$"
timeout: 60000
- tapOn: "Email or mobile phone number"
- inputText: "maestro.e2e@shopify.com"
- extendedWaitUntil:
visible: "^maestro.e2e@shopify.com$"
timeout: 5000
- scrollUntilVisible:
element:
text: "^First name( \\(optional\\))?$"
direction: DOWN
timeout: 5000
visibilityPercentage: 100
centerElement: true
- tapOn: "First name (optional)"
- inputText: "Maestro"
- extendedWaitUntil:
visible: "^Maestro$"
timeout: 5000
- scrollUntilVisible:
element:
text: "^Last name$"
direction: DOWN
timeout: 5000
visibilityPercentage: 100
centerElement: true
- tapOn: "Last name"
- inputText: "Shopify"
- extendedWaitUntil:
visible: "^Shopify$"
timeout: 5000

# Shipping address
- scrollUntilVisible:
element:
text: "Country/Region"
direction: DOWN
timeout: 5000
- tapOn: "Country/Region"
- waitForAnimationToEnd:
timeout: 3000
- scrollUntilVisible:
element:
text: "^${COUNTRY_LABEL}$"
direction: UP
timeout: 5000
visibilityPercentage: 10
optional: true
- scrollUntilVisible:
element:
text: "^${COUNTRY_LABEL}$"
direction: DOWN
timeout: 5000
visibilityPercentage: 10
optional: true
- tapOn:
text: "^${COUNTRY_LABEL}$"
- waitForAnimationToEnd:
timeout: 3000

- scrollUntilVisible:
element:
text: "Address"
direction: DOWN
timeout: 5000
- tapOn: "Address"
- eraseText: 80
- inputText: "${ADDRESS_LINE1}"
- waitForAnimationToEnd:
timeout: 3000
- extendedWaitUntil:
visible: "^${ADDRESS_LINE1}$"
timeout: 5000
- runFlow:
when:
visible: "Close suggestions"
commands:
- tapOn: "Close suggestions"
- waitForAnimationToEnd:
timeout: 3000
- extendedWaitUntil:
notVisible:
id: shipping-address1-autocomplete-title
timeout: 5000
- extendedWaitUntil:
notVisible:
id: shipping-address1-options
timeout: 5000
- scrollUntilVisible:
element:
text: "^City$"
direction: DOWN
timeout: 5000
centerElement: true
- tapOn: "City"
- eraseText: 80
- inputText: "${CITY}"
- extendedWaitUntil:
visible: "^${CITY}$"
timeout: 5000
- scrollUntilVisible:
element:
text: "^${STATE_FIELD_LABEL}$"
direction: DOWN
timeout: 5000
centerElement: true
- runFlow:
when:
notVisible: "^${STATE_LABEL}$"
commands:
- tapOn: "State"
- waitForAnimationToEnd:
timeout: 3000
- scrollUntilVisible:
element:
text: "^${STATE_LABEL}$"
direction: UP
timeout: 5000
visibilityPercentage: 100
optional: true
- scrollUntilVisible:
element:
text: "^${STATE_LABEL}$"
direction: DOWN
timeout: 5000
visibilityPercentage: 100
optional: true
- tapOn:
text: "^${STATE_LABEL}$"
- waitForAnimationToEnd:
timeout: 3000
- extendedWaitUntil:
notVisible: "Select a state"
timeout: 5000
- extendedWaitUntil:
visible: "^${STATE_LABEL}$"
timeout: 5000
- scrollUntilVisible:
element:
text: "^${POSTAL_FIELD_LABEL}$"
direction: DOWN
timeout: 5000
centerElement: true
- tapOn: "ZIP code"
- eraseText: 80
- inputText: "${POSTAL_CODE}"
- extendedWaitUntil:
visible: "^${POSTAL_CODE}$"
timeout: 5000
- waitForAnimationToEnd:
timeout: 3000

# Payment
- scrollUntilVisible:
element:
id: number
direction: DOWN
timeout: 5000
centerElement: true
- tapOn:
text: "Card number"
index: -1
- inputText: "${CARD_NUMBER}"
- tapOn:
id: expiry
- inputText: "1"
- waitForAnimationToEnd:
timeout: 3000
- inputText: "2"
- waitForAnimationToEnd:
timeout: 3000
- inputText: "3"
- waitForAnimationToEnd:
timeout: 3000
- inputText: "0"
- extendedWaitUntil:
visible: "^${CARD_EXPIRY_DISPLAY}$"
timeout: 5000
- tapOn:
text: "Security code"
index: -1
- inputText: "${CARD_SECURITY_CODE}"
- extendedWaitUntil:
visible: "^${CARD_SECURITY_CODE}$"
timeout: 5000
- scrollUntilVisible:
element:
id: name
direction: DOWN
timeout: 5000
centerElement: true
- extendedWaitUntil:
visible: "^${CARDHOLDER_NAME}$"
timeout: 5000
- scrollUntilVisible:
element:
text: "^Pay now$"
direction: DOWN
timeout: 5000
centerElement: true
- tapOn: "Pay now"
- extendedWaitUntil:
visible: "${POST_SUBMIT_RESULT_PATTERN}"
timeout: 60000
- tapOn: "Close Checkout"
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