create-agent-skills 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,246 @@
1
+ # E-commerce Checkout Flow Example
2
+
3
+ Complete checkout flow with scrolling, form filling, and payment.
4
+
5
+ ## Flow File: checkout-test.yaml
6
+
7
+ ```yaml
8
+ appId: com.example.shop
9
+ name: "User can complete checkout with credit card"
10
+ tags:
11
+ - checkout
12
+ - payment
13
+ - e2e
14
+ - critical
15
+ env:
16
+ CARD_NUMBER: "4111111111111111"
17
+ CARD_EXPIRY: "12/28"
18
+ CARD_CVV: "123"
19
+ SHIPPING_ADDRESS: "123 Main Street"
20
+ SHIPPING_CITY: "San Francisco"
21
+ SHIPPING_ZIP: "94102"
22
+ ---
23
+ # Prerequisite: User is logged in and has items in cart
24
+ - launchApp
25
+
26
+ # Navigate to cart
27
+ - tapOn:
28
+ id: "cart_icon"
29
+
30
+ # Verify cart has items
31
+ - assertVisible:
32
+ id: "cart_items_list"
33
+
34
+ # Verify total is displayed
35
+ - assertVisible: "Total: \\$[0-9]+\\.[0-9]{2}"
36
+
37
+ # Proceed to checkout
38
+ - tapOn:
39
+ id: "checkout_button"
40
+ enabled: true
41
+
42
+ # === SHIPPING SECTION ===
43
+ - assertVisible: "Shipping Address"
44
+
45
+ # Fill shipping form
46
+ - tapOn:
47
+ id: "address_input"
48
+ - inputText: "${SHIPPING_ADDRESS}"
49
+
50
+ - tapOn:
51
+ id: "city_input"
52
+ - inputText: "${SHIPPING_CITY}"
53
+
54
+ - tapOn:
55
+ id: "zip_input"
56
+ - inputText: "${SHIPPING_ZIP}"
57
+
58
+ - hideKeyboard
59
+
60
+ # Scroll to continue button if needed
61
+ - scrollUntilVisible:
62
+ element:
63
+ id: "continue_to_payment"
64
+ direction: DOWN
65
+
66
+ - tapOn:
67
+ id: "continue_to_payment"
68
+
69
+ # === PAYMENT SECTION ===
70
+ - assertVisible: "Payment Method"
71
+
72
+ # Select credit card
73
+ - tapOn:
74
+ below: "Payment Method"
75
+ text: "Credit Card"
76
+
77
+ # Fill card details
78
+ - tapOn:
79
+ id: "card_number_input"
80
+ - inputText: "${CARD_NUMBER}"
81
+
82
+ - tapOn:
83
+ id: "card_expiry_input"
84
+ - inputText: "${CARD_EXPIRY}"
85
+
86
+ - tapOn:
87
+ id: "card_cvv_input"
88
+ - inputText: "${CARD_CVV}"
89
+
90
+ - hideKeyboard
91
+
92
+ # === ORDER REVIEW ===
93
+ - scrollUntilVisible:
94
+ element:
95
+ id: "place_order_button"
96
+ direction: DOWN
97
+
98
+ # Verify order summary
99
+ - assertVisible: "Order Summary"
100
+ - assertVisible:
101
+ id: "order_total"
102
+
103
+ # Take screenshot before placing order
104
+ - takeScreenshot: "order_review"
105
+
106
+ # Place order
107
+ - tapOn:
108
+ id: "place_order_button"
109
+ enabled: true
110
+
111
+ # Wait for order processing
112
+ - extendedWaitUntil:
113
+ visible: "Order Confirmed"
114
+ timeout: 30000
115
+
116
+ # Verify confirmation
117
+ - assertVisible: "Order #[0-9]+"
118
+ - assertVisible: "Thank you for your order"
119
+
120
+ # Capture confirmation
121
+ - takeScreenshot: "order_confirmation"
122
+ ```
123
+
124
+ ## Subflow: add-product-to-cart.yaml
125
+
126
+ ```yaml
127
+ # subflows/add-product-to-cart.yaml
128
+ # Requires PRODUCT_NAME and optional QUANTITY
129
+
130
+ - scrollUntilVisible:
131
+ element: "${PRODUCT_NAME}"
132
+ direction: DOWN
133
+ timeout: 15000
134
+
135
+ - tapOn: "${PRODUCT_NAME}"
136
+
137
+ # Wait for product detail page
138
+ - assertVisible:
139
+ id: "product_detail_screen"
140
+
141
+ # Increase quantity if specified
142
+ - runFlow:
143
+ when:
144
+ true: ${QUANTITY && QUANTITY > 1}
145
+ commands:
146
+ - repeat:
147
+ times: ${QUANTITY - 1}
148
+ commands:
149
+ - tapOn:
150
+ id: "quantity_increase"
151
+
152
+ # Add to cart
153
+ - tapOn:
154
+ id: "add_to_cart_button"
155
+
156
+ # Verify added
157
+ - assertVisible: "Added to cart"
158
+
159
+ # Go back to continue shopping or proceed
160
+ - back
161
+ ```
162
+
163
+ ## Using with Login Subflow
164
+
165
+ ```yaml
166
+ appId: com.example.shop
167
+ name: "Complete purchase flow from login to confirmation"
168
+ tags:
169
+ - e2e
170
+ - purchase
171
+ env:
172
+ EMAIL: customer@example.com
173
+ PASSWORD: CustomerPass123!
174
+ PRODUCT_NAME: "Blue Wireless Headphones"
175
+ QUANTITY: 1
176
+ CARD_NUMBER: "4111111111111111"
177
+ CARD_EXPIRY: "12/28"
178
+ CARD_CVV: "123"
179
+ ---
180
+ - launchApp:
181
+ clearState: true
182
+
183
+ # Login
184
+ - runFlow:
185
+ file: ../subflows/login-steps.yaml
186
+ env:
187
+ EMAIL: ${EMAIL}
188
+ PASSWORD: ${PASSWORD}
189
+
190
+ # Add product to cart
191
+ - runFlow:
192
+ file: ../subflows/add-product-to-cart.yaml
193
+ env:
194
+ PRODUCT_NAME: ${PRODUCT_NAME}
195
+ QUANTITY: ${QUANTITY}
196
+
197
+ # Go to cart and checkout
198
+ - tapOn:
199
+ id: "cart_icon"
200
+
201
+ - runFlow: ../subflows/checkout-steps.yaml
202
+ ```
203
+
204
+ ## Handling Cart Edge Cases
205
+
206
+ ```yaml
207
+ appId: com.example.shop
208
+ name: "Empty cart shows appropriate message"
209
+ tags:
210
+ - cart
211
+ - edge-case
212
+ ---
213
+ - launchApp:
214
+ clearState: true
215
+
216
+ # Skip login for guest browsing
217
+ - runFlow:
218
+ when:
219
+ visible: "Continue as Guest"
220
+ commands:
221
+ - tapOn: "Continue as Guest"
222
+
223
+ # Navigate to cart
224
+ - tapOn:
225
+ id: "cart_icon"
226
+
227
+ # Verify empty cart state
228
+ - assertVisible: "Your cart is empty"
229
+ - assertVisible:
230
+ id: "start_shopping_button"
231
+
232
+ # Checkout button should be disabled or hidden
233
+ - assertNotVisible:
234
+ id: "checkout_button"
235
+ enabled: true
236
+ ```
237
+
238
+ ## Key Patterns Used
239
+
240
+ 1. **Scroll before interact** - `scrollUntilVisible` before tapping buttons at bottom
241
+ 2. **Form filling pattern** - Tap field → Input text → Next field
242
+ 3. **Regex assertions** - `"Order #[0-9]+"` for dynamic content
243
+ 4. **Conditional flows** - Handle optional UI elements
244
+ 5. **Screenshots at key points** - Before and after critical actions
245
+ 6. **Extended waits** - For payment processing (30s timeout)
246
+ 7. **Relative selectors** - `below: "Payment Method"` for context
@@ -0,0 +1,164 @@
1
+ # Login Flow Example
2
+
3
+ This example demonstrates a complete login flow test with best practices.
4
+
5
+ ## Flow File: login-test.yaml
6
+
7
+ ```yaml
8
+ appId: com.example.myapp
9
+ name: "User can login with valid credentials"
10
+ tags:
11
+ - smoke
12
+ - auth
13
+ - critical
14
+ env:
15
+ TEST_EMAIL: testuser@example.com
16
+ TEST_PASSWORD: SecurePass123!
17
+ ---
18
+ # Start fresh
19
+ - launchApp:
20
+ clearState: true
21
+
22
+ # Wait for app to load
23
+ - assertVisible:
24
+ id: "splash_screen"
25
+ optional: true
26
+ - extendedWaitUntil:
27
+ visible:
28
+ id: "login_screen"
29
+ timeout: 10000
30
+
31
+ # Enter email
32
+ - tapOn:
33
+ id: "email_input"
34
+ - inputText: "${TEST_EMAIL}"
35
+
36
+ # Enter password
37
+ - tapOn:
38
+ id: "password_input"
39
+ - inputText: "${TEST_PASSWORD}"
40
+
41
+ # Hide keyboard if needed
42
+ - hideKeyboard
43
+
44
+ # Submit login
45
+ - tapOn:
46
+ id: "login_button"
47
+ enabled: true
48
+
49
+ # Wait for login to complete
50
+ - extendedWaitUntil:
51
+ visible:
52
+ id: "home_screen"
53
+ timeout: 15000
54
+
55
+ # Verify successful login
56
+ - assertVisible: "Welcome back"
57
+ - assertVisible:
58
+ id: "user_profile_icon"
59
+
60
+ # Take screenshot for report
61
+ - takeScreenshot: "login_success"
62
+ ```
63
+
64
+ ## Subflow: login-steps.yaml
65
+
66
+ Reusable login component for other tests:
67
+
68
+ ```yaml
69
+ # subflows/login-steps.yaml
70
+ # Requires EMAIL and PASSWORD env variables from parent flow
71
+
72
+ - tapOn:
73
+ id: "email_input"
74
+ - inputText: "${EMAIL}"
75
+
76
+ - tapOn:
77
+ id: "password_input"
78
+ - inputText: "${PASSWORD}"
79
+
80
+ - hideKeyboard
81
+
82
+ - tapOn:
83
+ id: "login_button"
84
+
85
+ - extendedWaitUntil:
86
+ visible:
87
+ id: "home_screen"
88
+ timeout: 15000
89
+ ```
90
+
91
+ ## Using the Subflow
92
+
93
+ ```yaml
94
+ appId: com.example.myapp
95
+ name: "User can access settings after login"
96
+ env:
97
+ EMAIL: testuser@example.com
98
+ PASSWORD: SecurePass123!
99
+ ---
100
+ - launchApp:
101
+ clearState: true
102
+
103
+ # Reuse login subflow
104
+ - runFlow: ../subflows/login-steps.yaml
105
+
106
+ # Continue with test-specific steps
107
+ - tapOn:
108
+ id: "menu_button"
109
+ - tapOn: "Settings"
110
+ - assertVisible: "Account Settings"
111
+ ```
112
+
113
+ ## Handling Login Errors
114
+
115
+ ```yaml
116
+ appId: com.example.myapp
117
+ name: "Invalid login shows error message"
118
+ tags:
119
+ - auth
120
+ - negative
121
+ env:
122
+ INVALID_EMAIL: wrong@example.com
123
+ INVALID_PASSWORD: wrongpassword
124
+ ---
125
+ - launchApp:
126
+ clearState: true
127
+
128
+ - tapOn:
129
+ id: "email_input"
130
+ - inputText: "${INVALID_EMAIL}"
131
+
132
+ - tapOn:
133
+ id: "password_input"
134
+ - inputText: "${INVALID_PASSWORD}"
135
+
136
+ - tapOn:
137
+ id: "login_button"
138
+
139
+ # Verify error is shown
140
+ - assertVisible:
141
+ text: "Invalid email or password"
142
+ - assertVisible:
143
+ id: "error_banner"
144
+
145
+ # Verify still on login screen
146
+ - assertVisible:
147
+ id: "login_screen"
148
+
149
+ # Verify login button still available (not navigated away)
150
+ - assertVisible:
151
+ id: "login_button"
152
+ enabled: true
153
+ ```
154
+
155
+ ## Best Practices Applied
156
+
157
+ 1. **Clear state** - Start fresh with `clearState: true`
158
+ 2. **Use IDs** - `id: "login_button"` instead of text
159
+ 3. **Environment variables** - Credentials in `env` section
160
+ 4. **Explicit waits** - `extendedWaitUntil` for async operations
161
+ 5. **Screenshots** - Capture proof of success
162
+ 6. **Subflows** - Reusable login component
163
+ 7. **Meaningful tags** - `smoke`, `auth`, `critical`
164
+ 8. **Descriptive names** - Clear test intent
@@ -0,0 +1,245 @@
1
+ # Project Structure Template
2
+
3
+ Recommended Maestro test project structure for maintainable test suites.
4
+
5
+ ## Directory Structure
6
+
7
+ ```
8
+ project-root/
9
+ ├── .maestro/
10
+ │ ├── config.yaml # Workspace configuration
11
+ │ ├── flows/ # Test flows (runnable tests)
12
+ │ │ ├── auth/
13
+ │ │ │ ├── login.yaml
14
+ │ │ │ ├── logout.yaml
15
+ │ │ │ ├── forgot-password.yaml
16
+ │ │ │ └── register.yaml
17
+ │ │ ├── onboarding/
18
+ │ │ │ ├── first-time-user.yaml
19
+ │ │ │ └── skip-onboarding.yaml
20
+ │ │ ├── checkout/
21
+ │ │ │ ├── guest-checkout.yaml
22
+ │ │ │ ├── member-checkout.yaml
23
+ │ │ │ └── failed-payment.yaml
24
+ │ │ └── profile/
25
+ │ │ ├── edit-profile.yaml
26
+ │ │ └── change-password.yaml
27
+ │ ├── subflows/ # Reusable components (not run directly)
28
+ │ │ ├── auth/
29
+ │ │ │ ├── login-steps.yaml
30
+ │ │ │ ├── logout-steps.yaml
31
+ │ │ │ └── fill-registration-form.yaml
32
+ │ │ ├── navigation/
33
+ │ │ │ ├── go-to-home.yaml
34
+ │ │ │ ├── go-to-cart.yaml
35
+ │ │ │ ├── go-to-profile.yaml
36
+ │ │ │ └── go-to-settings.yaml
37
+ │ │ ├── common/
38
+ │ │ │ ├── dismiss-popups.yaml
39
+ │ │ │ ├── accept-cookies.yaml
40
+ │ │ │ └── handle-permissions.yaml
41
+ │ │ └── cart/
42
+ │ │ ├── add-to-cart.yaml
43
+ │ │ ├── remove-from-cart.yaml
44
+ │ │ └── update-quantity.yaml
45
+ │ └── scripts/ # JavaScript helpers
46
+ │ ├── data-generators.js
47
+ │ ├── date-helpers.js
48
+ │ └── api-helpers.js
49
+ ├── test-results/ # Output directory (gitignored)
50
+ │ ├── screenshots/
51
+ │ ├── recordings/
52
+ │ └── reports/
53
+ └── .gitignore
54
+ ```
55
+
56
+ ## config.yaml
57
+
58
+ ```yaml
59
+ # .maestro/config.yaml
60
+
61
+ # Include all flows, exclude work-in-progress
62
+ flows:
63
+ - 'flows/**/*.yaml'
64
+ - '!flows/**/*-wip.yaml'
65
+ - '!flows/**/*.draft.yaml'
66
+
67
+ # Default tags to include/exclude
68
+ includeTags: [] # Empty = include all
69
+ excludeTags:
70
+ - flaky
71
+ - manual
72
+
73
+ # Execution order for dependent tests
74
+ executionOrder:
75
+ continueOnFailure: false # Stop on first failure for CI
76
+ flowsOrder:
77
+ - flows/auth/login.yaml # Login first
78
+ - flows/onboarding/*.yaml # Then onboarding
79
+
80
+ # Output directory
81
+ testOutputDir: ../test-results
82
+
83
+ # Platform settings
84
+ platform:
85
+ ios:
86
+ disableAnimations: true
87
+ snapshotKeyHonorModalViews: false
88
+ android:
89
+ disableAnimations: true
90
+ ```
91
+
92
+ ## PR-specific config: pr-config.yaml
93
+
94
+ ```yaml
95
+ # .maestro/pr-config.yaml
96
+ # Faster subset for pull request checks
97
+
98
+ flows:
99
+ - 'flows/**/*.yaml'
100
+
101
+ includeTags:
102
+ - smoke
103
+ - critical
104
+
105
+ excludeTags:
106
+ - slow
107
+ - flaky
108
+
109
+ executionOrder:
110
+ continueOnFailure: true # Run all tests, report failures
111
+ ```
112
+
113
+ ## Subflow Template
114
+
115
+ ```yaml
116
+ # .maestro/subflows/auth/login-steps.yaml
117
+ #
118
+ # Reusable login component
119
+ # Required env: EMAIL, PASSWORD
120
+ # Assumes: App is launched and on login screen
121
+
122
+ - tapOn:
123
+ id: "email_input"
124
+ - inputText: "${EMAIL}"
125
+
126
+ - tapOn:
127
+ id: "password_input"
128
+ - inputText: "${PASSWORD}"
129
+
130
+ - hideKeyboard
131
+
132
+ - tapOn:
133
+ id: "login_button"
134
+
135
+ - extendedWaitUntil:
136
+ visible:
137
+ id: "home_screen"
138
+ timeout: 15000
139
+ ```
140
+
141
+ ## Flow Template
142
+
143
+ ```yaml
144
+ # .maestro/flows/auth/login.yaml
145
+
146
+ appId: com.example.myapp
147
+ name: "User can login with valid credentials"
148
+ tags:
149
+ - auth
150
+ - smoke
151
+ - critical
152
+ env:
153
+ EMAIL: testuser@example.com
154
+ PASSWORD: TestPass123!
155
+ ---
156
+ # Setup
157
+ - launchApp:
158
+ clearState: true
159
+
160
+ # Handle any initial popups
161
+ - runFlow:
162
+ when:
163
+ visible: "Allow Notifications"
164
+ file: ../../subflows/common/handle-permissions.yaml
165
+
166
+ # Execute login
167
+ - runFlow:
168
+ file: ../../subflows/auth/login-steps.yaml
169
+
170
+ # Verify success
171
+ - assertVisible: "Welcome"
172
+ - assertVisible:
173
+ id: "home_screen"
174
+
175
+ # Capture result
176
+ - takeScreenshot: "login_success"
177
+ ```
178
+
179
+ ## .gitignore
180
+
181
+ ```gitignore
182
+ # Maestro test outputs
183
+ test-results/
184
+ *.mp4
185
+ *.png
186
+
187
+ # Local environment overrides
188
+ .maestro/config.local.yaml
189
+
190
+ # IDE
191
+ .idea/
192
+ .vscode/
193
+ ```
194
+
195
+ ## Naming Conventions
196
+
197
+ | Type | Convention | Example |
198
+ |------|------------|---------|
199
+ | Flows | `action-subject.yaml` | `login.yaml`, `add-to-cart.yaml` |
200
+ | Subflows | `action-steps.yaml` | `login-steps.yaml`, `checkout-steps.yaml` |
201
+ | Directories | lowercase, plural | `flows/`, `subflows/`, `scripts/` |
202
+ | Tags | lowercase, hyphenated | `smoke`, `e2e`, `auth`, `critical` |
203
+
204
+ ## Tag Strategy
205
+
206
+ ```yaml
207
+ # Execution tags
208
+ - smoke # Quick sanity tests (~5 min)
209
+ - e2e # Full end-to-end flows
210
+ - critical # Must pass for release
211
+
212
+ # Feature tags
213
+ - auth # Authentication flows
214
+ - checkout # Purchase flows
215
+ - profile # User profile tests
216
+
217
+ # Filter tags
218
+ - flaky # Known flaky tests
219
+ - slow # Long-running tests
220
+ - manual # Require manual intervention
221
+ - wip # Work in progress
222
+ ```
223
+
224
+ ## Running Tests
225
+
226
+ ```bash
227
+ # All tests
228
+ maestro test .maestro/flows/
229
+
230
+ # With workspace config
231
+ maestro test --config .maestro/config.yaml .maestro/flows/
232
+
233
+ # PR config (smoke tests only)
234
+ maestro test --config .maestro/pr-config.yaml .maestro/flows/
235
+
236
+ # Specific feature
237
+ maestro test .maestro/flows/auth/
238
+
239
+ # By tags
240
+ maestro test --include-tags=smoke,critical .maestro/flows/
241
+ maestro test --exclude-tags=flaky,slow .maestro/flows/
242
+
243
+ # Continuous mode for development
244
+ maestro test --continuous .maestro/flows/auth/login.yaml
245
+ ```