-
Notifications
You must be signed in to change notification settings - Fork 115
228 lines (211 loc) · 10.1 KB
/
Copy pathci_e2e_pay_tests.yml
File metadata and controls
228 lines (211 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
name: Maestro E2E Pay Tests
# "(skip-metrics)" tells the E2E KPI job (WalletConnect/actions) to drop this run.
run-name: ${{ ((github.event_name == 'pull_request' && github.event.pull_request.draft) || (github.event_name == 'workflow_dispatch' && github.ref_name != 'develop')) && format('{0} (skip-metrics)', github.event.pull_request.title || github.ref_name) || '' }}
on:
pull_request:
types:
- opened
- synchronize
- reopened
- ready_for_review
branches:
- develop
- main
schedule:
# Run daily at 04:00 UTC (only on the default branch)
- cron: '0 4 * * *'
workflow_dispatch: {}
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref_name }}
cancel-in-progress: true
jobs:
check-balance:
if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
uses: ./.github/workflows/e2e_balance_check.yml
secrets: inherit
e2e-pay-tests:
needs: check-balance
if: always() && (github.event_name != 'pull_request' || github.event.pull_request.draft == false)
runs-on: macos-latest-xlarge
timeout-minutes: 45
permissions:
checks: write
actions: read
steps:
- uses: actions/checkout@v3
- name: Select Xcode 26 (iOS 26 SDK)
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '26'
# Boot the simulator BEFORE the build (not right before `maestro test`).
# A never-booted device posts a one-time "Ready for Apple Intelligence"
# follow-up notification a few minutes after its first boot; when the sim
# was booted seconds before the tests, that banner landed ~8s into the
# first flow, covering the button Maestro was about to tap. Booting early
# lets it fire and auto-dismiss during the ~10 min build instead.
- name: Boot iOS simulator
run: |
# Pick whatever iPhone simulator the runner actually has, so this
# doesn't break each time the Xcode/runner image bumps the model.
# Single awk pass: pull the UDID from the first available iPhone row.
# awk exits 0 even when nothing matches (so the check below stays
# reachable under `set -eo pipefail`), `exit` avoids a head/SIGPIPE
# footgun, and it tolerates parens in the device name (e.g. SE).
SIMULATOR_UDID=$(xcrun simctl list devices available \
| awk '/iPhone/ { if (match($0, /[0-9A-Fa-f-]{36}/)) { print substr($0, RSTART, RLENGTH); exit } }')
if [ -z "$SIMULATOR_UDID" ]; then
echo "ERROR: no available iPhone simulator found"
xcrun simctl list devices available
exit 1
fi
echo "Using simulator: $SIMULATOR_UDID"
xcrun simctl boot "$SIMULATOR_UDID" 2>/dev/null || true
xcrun simctl bootstatus "$SIMULATOR_UDID"
# Belt and suspenders for the same banner: iOS stamps this key when it
# posts the follow-up (verified against a sim's CoreFollowUp items.db —
# the item's creationDate matches this key to the second). Pre-seeding
# it marks the notification as already shown, covering runs where the
# build finishes (warm SPM cache) before the banner would have fired.
# Best-effort: booting early is the primary defense, so a runner image
# where this domain isn't writable must not fail the whole run.
xcrun simctl spawn "$SIMULATOR_UDID" defaults write \
com.apple.generativeexperiences.corefollowup \
DateOfLastAppleIntelligenceReadinessCFU -date "$(date -u '+%Y-%m-%d %H:%M:%S +0000')" \
|| echo "WARNING: could not pre-seed Apple Intelligence CFU timestamp (non-fatal)"
- uses: actions/cache@v3
with:
path: |
**/SourcePackagesCache
key: ${{ runner.os }}-spm-${{ hashFiles('**/Package.resolved') }}
- name: Build WalletApp for simulator (test mode)
id: build
run: |
set -o pipefail && env NSUnbufferedIO=YES \
xcodebuild \
-project "Example/ExampleApp.xcodeproj" \
-scheme "WalletApp" \
-destination "generic/platform=iOS Simulator" \
-derivedDataPath DerivedDataCache \
-clonedSourcePackagesDirPath ../SourcePackagesCache \
RELAY_HOST='relay.walletconnect.com' \
PROJECT_ID='${{ secrets.PROJECT_ID }}' \
TEST_WALLET_PRIVATE_KEY='${{ secrets.TEST_WALLET_PRIVATE_KEY }}' \
SWIFT_ACTIVE_COMPILATION_CONDITIONS='$(inherited) ENABLE_TEST_MODE' \
build \
| xcbeautify
- name: Copy shared Pay test flows
uses: WalletConnect/actions/maestro/pay-tests@4be7c0112f9651fc63b18c137650b75d2fc9b200
- name: Install Maestro
uses: WalletConnect/actions/maestro/setup@4be7c0112f9651fc63b18c137650b75d2fc9b200
with:
version: '2.4.0'
- name: Install app on simulator
run: |
APP_PATH=$(find DerivedDataCache -name "WalletApp.app" -path "*/Debug-iphonesimulator/*" | head -1)
if [ -z "$APP_PATH" ]; then
echo "ERROR: WalletApp.app not found in DerivedDataCache"
find DerivedDataCache -name "*.app" -path "*/Debug-iphonesimulator/*"
exit 1
fi
echo "Installing: $APP_PATH"
xcrun simctl install booted "$APP_PATH"
- name: Run Maestro Pay E2E tests
id: maestro
run: |
maestro test \
--env APP_ID=com.walletconnect.walletapp \
--env WPAY_CUSTOMER_KEY_SINGLE_NOKYC=${{ secrets.WPAY_CUSTOMER_KEY_SINGLE_NOKYC }} \
--env WPAY_MERCHANT_ID_SINGLE_NOKYC=${{ secrets.WPAY_MERCHANT_ID_SINGLE_NOKYC }} \
--env WPAY_CUSTOMER_KEY_MULTI_NOKYC=${{ secrets.WPAY_CUSTOMER_KEY_MULTI_NOKYC }} \
--env WPAY_MERCHANT_ID_MULTI_NOKYC=${{ secrets.WPAY_MERCHANT_ID_MULTI_NOKYC }} \
--env WPAY_CUSTOMER_KEY_MULTI_KYC=${{ secrets.WPAY_CUSTOMER_KEY_MULTI_KYC }} \
--env WPAY_MERCHANT_ID_MULTI_KYC=${{ secrets.WPAY_MERCHANT_ID_MULTI_KYC }} \
--include-tags pay \
--test-output-dir debug-artifacts/maestro-output \
.maestro/
# Reset the USDT Permit2 allowance back to 0 so the next pay_usdt_polygon run
# re-exercises the on-chain `approve` step. Runs even when the suite failed
# (if: always()) so a mid-flow failure can't leave the allowance set.
# continue-on-error so a reset hiccup can't fail an otherwise-green run.
# It signs a transaction, so it's a Node step (not a Maestro runScript); the
# private key goes via env, never the CLI.
- name: Reset USDT Permit2 allowance (Polygon)
if: always()
continue-on-error: true
uses: WalletConnect/actions/maestro/permit2-reset@4be7c0112f9651fc63b18c137650b75d2fc9b200
with:
chain-id: eip155:137
# polygon-rpc.com gates requests (HTTP 401 "tenant disabled") in CI; use publicnode.
rpc-url: https://polygon-bor-rpc.publicnode.com
token-address: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F'
private-key: ${{ secrets.TEST_WALLET_PRIVATE_KEY }}
- name: Capture simulator logs
if: always()
run: |
xcrun simctl spawn booted log collect --output debug-artifacts/sim-logs.logarchive 2>/dev/null || true
- name: Upload debug artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: maestro-pay-test-artifacts
path: |
debug-artifacts/**/*.png
debug-artifacts/**/*.jpg
debug-artifacts/**/*.jpeg
debug-artifacts/**/*.mp4
debug-artifacts/**/*.mov
debug-artifacts/**/*.webm
debug-artifacts/**/*.gif
debug-artifacts/sim-logs.logarchive
retention-days: 14
if-no-files-found: ignore
- name: Send Slack notification
if: failure()
uses: slackapi/slack-github-action@b0fa283ad8fea605de13dc3f449259339835fc52 # v2.1.0
with:
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
{
"text": "E2E Test Report - iOS - Pay",
"blocks": [
{
"type": "header",
"text": { "type": "plain_text", "text": "🧪 E2E Test Report - iOS (pay)" }
},
{
"type": "section",
"fields": [
{ "type": "mrkdwn", "text": "*Project:*\n`Reown Swift`" },
{ "type": "mrkdwn", "text": "*Platform:*\n`iOS`" },
{ "type": "mrkdwn", "text": "*Branch:*\n`${{ github.ref_name }}`" },
{ "type": "mrkdwn", "text": "*Trigger:*\n`${{ github.event_name }}`" }
]
},
{
"type": "section",
"fields": [
{ "type": "mrkdwn", "text": "*Build:*\n`${{ steps.build.outcome == 'success' && '✅ Success' || '❌ Failed' }}`" },
{ "type": "mrkdwn", "text": "*Maestro Tests:*\n`${{ steps.maestro.outcome == 'success' && '✅ Passed' || '❌ Failed' }}`" },
{ "type": "mrkdwn", "text": "*Overall Status:*\n`${{ job.status == 'success' && '✅ Success' || '❌ Failed' }}`" }
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": { "type": "plain_text", "text": "View Workflow Run" },
"url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
},
{
"type": "button",
"text": { "type": "plain_text", "text": "Download Artifacts" },
"url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}#artifacts"
}
]
}
]
}