Skip to content

Commit 814e529

Browse files
committed
Add React Native Android checkout e2e flow
1 parent 69afad3 commit 814e529

3 files changed

Lines changed: 299 additions & 4 deletions

File tree

e2e/README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ sample ships to both platforms; its flows are split because some assertions
2323
are platform-specific (iOS accessibility-label patterns vs Android resource
2424
strings).
2525

26+
The React Native Android checkout flow submits payment and waits for the order
27+
confirmation screen. The React Native iOS checkout flow currently stops at
28+
`Pay now`; the store/address path can show a checkout-web shipping availability
29+
banner after submit, which is outside the Checkout Kit integration contract.
30+
2631
Folders are created when their first flow lands. Don't pre-create empty
2732
directories.
2833

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

4045
## Running
4146

@@ -48,7 +53,7 @@ terminal.
4853
| React Native, iOS | `platforms/react-native/` | `pnpm e2e:ios` |
4954
| Swift, iOS | TBD | TBD |
5055
| Android (native) | TBD | TBD |
51-
| RN, Android | TBD | TBD |
56+
| RN, Android | `platforms/react-native/` | `pnpm e2e:android` |
5257

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

@@ -61,7 +66,8 @@ curl -fsSL "https://get.maestro.mobile.dev" | bash
6166
1. Drop a new `<name>.yaml` under the right folder.
6267
2. Set `appId:` from the table above.
6368
3. Keep timeouts in the existing tiers (in-app interactions ~10s, network
64-
transitions ~30s, cold starts and checkout first-paint ~60s).
69+
transitions ~30s, cold starts, checkout first-paint, and order confirmation
70+
~60s).
6571
4. If the flow needs an npm script wrapper, add an `e2e:<platform>` script to
6672
the matching `package.json` next to existing scripts. The script should
6773
point at the folder, not an individual file, so the whole folder runs.
Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
appId: com.shopify.checkoutkitreactnative
2+
name: Checkout submits and shows result
3+
tags:
4+
- android
5+
- checkout
6+
7+
env:
8+
# CI shipping fixture
9+
COUNTRY_LABEL: "United States"
10+
ADDRESS_LINE1: "700 S Flower St"
11+
CITY: "Los Angeles"
12+
STATE_FIELD_LABEL: "State"
13+
STATE_LABEL: "California"
14+
POSTAL_CODE: "90017"
15+
POSTAL_FIELD_LABEL: "ZIP code"
16+
17+
# CI payment fixture
18+
CARD_NUMBER: "1"
19+
CARD_EXPIRY_DISPLAY: "12 / 30"
20+
CARD_SECURITY_CODE: "123"
21+
CARDHOLDER_NAME: "Maestro Shopify"
22+
23+
# Accepted terminal checkout states for this smoke test.
24+
POST_SUBMIT_RESULT_PATTERN: ".*(Thank you|Your order|Order confirmed|confirmation|Shipping not available|There was a problem|declined|couldn.t process).*"
25+
---
26+
# Timeout tiers:
27+
# 10000 - in-app interactions (taps, animations)
28+
# 30000 - checkout step transitions (network)
29+
# 60000 - cold starts, first checkout paint, final submit
30+
31+
# Product and cart
32+
- launchApp:
33+
clearState: true
34+
- extendedWaitUntil:
35+
visible:
36+
id: product-0-add-to-cart-button
37+
timeout: 60000
38+
- scrollUntilVisible:
39+
element:
40+
id: product-0-add-to-cart-button
41+
direction: DOWN
42+
timeout: 10000
43+
centerElement: true
44+
- tapOn:
45+
id: product-0-add-to-cart-button
46+
enabled: true
47+
- waitForAnimationToEnd:
48+
timeout: 10000
49+
- runFlow:
50+
when:
51+
visible:
52+
id: header-cart-icon
53+
commands:
54+
- tapOn:
55+
id: header-cart-icon
56+
- runFlow:
57+
when:
58+
notVisible:
59+
id: checkout-button
60+
commands:
61+
- tapOn:
62+
id: cart-tab
63+
- extendedWaitUntil:
64+
visible:
65+
id: checkout-button
66+
timeout: 30000
67+
- tapOn:
68+
id: checkout-button
69+
enabled: true
70+
71+
# Contact
72+
- extendedWaitUntil:
73+
visible:
74+
text: "^Email( or mobile phone number)?$"
75+
timeout: 60000
76+
- tapOn:
77+
id: email
78+
- inputText: "maestro.e2e@shopify.com"
79+
- extendedWaitUntil:
80+
visible: "^maestro.e2e@shopify.com$"
81+
timeout: 10000
82+
- scrollUntilVisible:
83+
element:
84+
id: TextField0
85+
direction: DOWN
86+
timeout: 10000
87+
centerElement: true
88+
- tapOn:
89+
id: TextField0
90+
- inputText: "Maestro"
91+
- extendedWaitUntil:
92+
visible:
93+
id: TextField0
94+
text: "^Maestro$"
95+
timeout: 10000
96+
- scrollUntilVisible:
97+
element:
98+
text: "^Last name$"
99+
direction: DOWN
100+
timeout: 10000
101+
visibilityPercentage: 100
102+
centerElement: true
103+
- tapOn:
104+
id: TextField1
105+
- inputText: "Shopify"
106+
- extendedWaitUntil:
107+
visible:
108+
id: TextField1
109+
text: "^Shopify$"
110+
timeout: 10000
111+
112+
# Shipping address
113+
- scrollUntilVisible:
114+
element:
115+
id: Select0
116+
direction: DOWN
117+
timeout: 10000
118+
- tapOn:
119+
id: Select0
120+
- waitForAnimationToEnd:
121+
timeout: 10000
122+
- scrollUntilVisible:
123+
element:
124+
text: "^${COUNTRY_LABEL}$"
125+
direction: UP
126+
timeout: 10000
127+
visibilityPercentage: 10
128+
optional: true
129+
- scrollUntilVisible:
130+
element:
131+
text: "^${COUNTRY_LABEL}$"
132+
direction: DOWN
133+
timeout: 10000
134+
visibilityPercentage: 10
135+
optional: true
136+
- tapOn:
137+
text: "^${COUNTRY_LABEL}$"
138+
- waitForAnimationToEnd:
139+
timeout: 10000
140+
141+
- scrollUntilVisible:
142+
element:
143+
id: shipping-address1
144+
direction: DOWN
145+
timeout: 10000
146+
- tapOn:
147+
id: shipping-address1
148+
- eraseText: 80
149+
- inputText: "${ADDRESS_LINE1}"
150+
- waitForAnimationToEnd:
151+
timeout: 10000
152+
- extendedWaitUntil:
153+
visible: "^${ADDRESS_LINE1}$"
154+
timeout: 10000
155+
- runFlow:
156+
when:
157+
visible: "Close suggestions"
158+
commands:
159+
- tapOn: "Close suggestions"
160+
- waitForAnimationToEnd:
161+
timeout: 10000
162+
- extendedWaitUntil:
163+
notVisible:
164+
id: shipping-address1-autocomplete-title
165+
timeout: 10000
166+
- extendedWaitUntil:
167+
notVisible:
168+
id: shipping-address1-options
169+
timeout: 10000
170+
- scrollUntilVisible:
171+
element:
172+
id: TextField3
173+
direction: DOWN
174+
timeout: 10000
175+
centerElement: true
176+
- tapOn:
177+
id: TextField3
178+
- eraseText: 80
179+
- inputText: "${CITY}"
180+
- extendedWaitUntil:
181+
visible: "^${CITY}$"
182+
timeout: 10000
183+
- scrollUntilVisible:
184+
element:
185+
id: Select1
186+
direction: DOWN
187+
timeout: 10000
188+
centerElement: true
189+
- runFlow:
190+
when:
191+
notVisible: "^${STATE_LABEL}$"
192+
commands:
193+
- tapOn:
194+
id: Select1
195+
- waitForAnimationToEnd:
196+
timeout: 10000
197+
- scrollUntilVisible:
198+
element:
199+
text: "^${STATE_LABEL}$"
200+
direction: UP
201+
timeout: 10000
202+
visibilityPercentage: 100
203+
optional: true
204+
- scrollUntilVisible:
205+
element:
206+
text: "^${STATE_LABEL}$"
207+
direction: DOWN
208+
timeout: 10000
209+
visibilityPercentage: 100
210+
optional: true
211+
- tapOn:
212+
text: "^${STATE_LABEL}$"
213+
- waitForAnimationToEnd:
214+
timeout: 10000
215+
- extendedWaitUntil:
216+
notVisible: "Select a state"
217+
timeout: 10000
218+
- extendedWaitUntil:
219+
visible: "^${STATE_LABEL}$"
220+
timeout: 10000
221+
- scrollUntilVisible:
222+
element:
223+
id: TextField4
224+
direction: DOWN
225+
timeout: 10000
226+
centerElement: true
227+
- tapOn:
228+
id: TextField4
229+
- eraseText: 80
230+
- inputText: "${POSTAL_CODE}"
231+
- extendedWaitUntil:
232+
visible: "^${POSTAL_CODE}$"
233+
timeout: 10000
234+
- waitForAnimationToEnd:
235+
timeout: 10000
236+
237+
# Payment
238+
- scrollUntilVisible:
239+
element:
240+
id: number
241+
direction: DOWN
242+
timeout: 10000
243+
centerElement: true
244+
- tapOn:
245+
id: number
246+
- inputText: "${CARD_NUMBER}"
247+
- tapOn:
248+
id: expiry
249+
- inputText: "1"
250+
- waitForAnimationToEnd:
251+
timeout: 10000
252+
- inputText: "2"
253+
- waitForAnimationToEnd:
254+
timeout: 10000
255+
- inputText: "3"
256+
- waitForAnimationToEnd:
257+
timeout: 10000
258+
- inputText: "0"
259+
- extendedWaitUntil:
260+
visible: "^${CARD_EXPIRY_DISPLAY}$"
261+
timeout: 10000
262+
- tapOn:
263+
id: verification_value
264+
- inputText: "${CARD_SECURITY_CODE}"
265+
- extendedWaitUntil:
266+
visible: "^${CARD_SECURITY_CODE}$"
267+
timeout: 10000
268+
- scrollUntilVisible:
269+
element:
270+
id: name
271+
direction: DOWN
272+
timeout: 10000
273+
centerElement: true
274+
- extendedWaitUntil:
275+
visible: "^${CARDHOLDER_NAME}$"
276+
timeout: 10000
277+
- scrollUntilVisible:
278+
element:
279+
text: "^(Pay now|Complete order)$"
280+
direction: DOWN
281+
timeout: 10000
282+
centerElement: true
283+
- tapOn:
284+
text: "^(Pay now|Complete order)$"
285+
enabled: true
286+
- extendedWaitUntil:
287+
visible: "${POST_SUBMIT_RESULT_PATTERN}"
288+
timeout: 60000

platforms/react-native/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
"compare-snapshot": "./scripts/compare_snapshot",
2626
"turbo": "turbo",
2727
"test": "jest",
28-
"e2e:ios": "maestro --platform ios test --config ../../e2e/config.yaml ../../e2e/react-native/ios"
28+
"e2e:ios": "maestro --platform ios test --config ../../e2e/config.yaml ../../e2e/react-native/ios",
29+
"e2e:android": "maestro --platform android test --config ../../e2e/config.yaml ../../e2e/react-native/android"
2930
},
3031
"devDependencies": {
3132
"@babel/core": "^7.25.2",

0 commit comments

Comments
 (0)