[ACE-597] Maestro webview checkout regression suite#330
Open
shirly-chen-awx wants to merge 4 commits into
Open
[ACE-597] Maestro webview checkout regression suite#330shirly-chen-awx wants to merge 4 commits into
shirly-chen-awx wants to merge 4 commits into
Conversation
Adds a Maestro suite under `.maestro/WebViewCheckout/` that proves paymentacceptance-checkout-ui mounts correctly inside H5WebViewActivity (android.webkit.WebView). Locally green 4/5 runs on Pixel 6 / Android 34 emulator. The card form / 3DS / digital wallet end-to-end paths are intentionally out of scope here: Airwallex's card element renders inputs in nested cross-origin iframes, which Android WebView's accessibility tree does not surface — so Maestro cannot reach them. Those flows are covered by paymentacceptance-fe-automation-test (Playwright) under mobile-chrome. This suite owns the webview-specific risk: does checkout-ui mount and initialize at all? Both READMEs explain the limitation and three options for unblocking full card-flow automation in the future. JIRA: https://airwallex.atlassian.net/browse/ACE-597 Co-authored-by: Cursor <cursoragent@cursor.com>
Extends the P0 with a tap-level smoke test for the Google Pay button: asserts the button is present, tappable, and that checkout-ui's onClick handler runs without crashing the WebView (post-condition checks the HPP element is still mounted afterwards). Confirmed via `adb logcat` that the chromium console fires the `button_name=google_pay` click analytics event, proving the PaymentRequest bridge is wired. Native sheet doesn't open on this AVD because `google_apis` system-image lacks Google Wallet — README docs the `google_apis_playstore` setup to extend coverage to the native sheet level. Also bumps the `Order Information` extendedWaitUntil timeout from 60s to 90s after observing Cloudflare CDN re-route through 3G/HSPA paths with 75% packet loss on the emulator's cellular interface. JIRA: https://airwallex.atlassian.net/browse/ACE-597 Co-authored-by: Cursor <cursoragent@cursor.com>
Investigated the native GPay sheet path empirically on both google_apis and google_apis_playstore AVDs. Confirmed: - canMakePayment() returns true in both - checkout-ui's onClick handler fires the analytics event in both - sheet only opens when (a) playstore AVD + (b) Google account signed in + (c) Google Wallet installed with a tokenized test card from developers.google.com/pay test-card-suite None of those are reproducible on shared CI without baking a custom AVD image with pre-seeded credentials, so the regression stays at tap-level smoke. README now lists the exact 4-step provisioning recipe + the 4-line yaml extension to assert sheet appearance once PA stands up dedicated mobile CI hardware. JIRA: https://airwallex.atlassian.net/browse/ACE-597 Co-authored-by: Cursor <cursoragent@cursor.com>
Android card flow runs the test card 4012000300000088 (Y-Y-SUCCESS, OTP
1234) end-to-end inside the native WebView -- PAN/Expiry/CVC entry ->
tokenization -> DDC -> 3DS challenge sheet -> Submit -> native success
view with a real PaymentIntent (int_hkdmpt4f9hip47fh6au).
Implemented as a shell script (test_webview_card_3ds_success.sh) rather
than a Maestro yaml, because Maestro's inputText action on Android
WebView updates the iframe DOM value but does NOT trigger React's
onChange event for inputs inside the PCI cross-origin iframes
(checkout.airwallex.com). The DOM looks filled but checkout-ui's
controlled-input state stays empty, so validation fails and Pay stays
disabled.
`adb shell input text` (raw kernel-level InputConnection events) routes
through the IME pipeline and does trigger onChange correctly, so the
script:
1. Uses Maestro for the navigation prologue (launch app ->
H5DemoActivity -> tap Check out).
2. Drops to `adb shell input tap` / `adb shell input text` for every
iframe-internal interaction (PAN/Expiry/CVC, 3DS OTP, Submit).
3. Re-dumps `uiautomator` between steps so coordinates stay correct
as the form reflows around the soft keyboard.
README updated with:
- coverage table flipped to ✅ for card / 3DS / native success rows
- new "Iframe limitation & the `adb shell input` workaround" section
documenting the Maestro inputText limitation and the iOS/Android
behaviour diff
- run instructions for the new P1 test
- timing + stability stats (2/2 green, ~210s wall time)
JIRA: ACE-597
Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a regression suite under
.maestro/WebViewCheckout/that proves paymentacceptance-checkout-ui mounts and drives real payments correctly insideH5WebViewActivity(android.webkit.WebView).flow_open_h5_webview.yaml— reusable Maestro flow: cold-launch sample app → H5 demo → load/shopping-cartin WebView.test_webview_checkout_renders.yaml— P0 (Maestro): asserts checkout-ui HPP mounts + Pay button (currency-formatted) visible + Google Pay tap-level smoke.test_webview_card_3ds_success.sh— P1 (Maestro + adb): full card flow with test card4012000300000088(Y-Y-SUCCESS, OTP1234) — PAN/Expiry/CVC entry → tokenization → DDC → 3DS challenge sheet → Submit → native success view with a real PaymentIntent.README.md— design rationale, run instructions, iframe limitation + theadb shell inputworkaround, known bring-up issues.JIRA: ACE-597.
Why P1 is a shell script, not a Maestro yaml
The original PR descoped card flow because Airwallex's card element renders PAN / Expiry / CVC in nested cross-origin iframes (PCI requirement). Investigation found:
EditText/AXTextFieldsurfaced in a11y tree?tapOn pointfocuses the inner field?inputTexttriggers ReactonChange?adb shell input text(kernel-level InputConnection) triggers ReactonChange?So iOS card flow is pure Maestro, and Android card flow is a shell script that:
adb shell input tap/adb shell input textfor every iframe-internal interaction (PAN, Expiry, CVC, 3DS OTP, Submit)uiautomatorbetween steps so coordinates stay correct as the form reflows around the soft keyboardThe same 3DS Challenge iframe (Cardinal Commerce) IS surfaced in Android's a11y tree, so the script can find the OTP input and Submit button by resource-id / text rather than by coordinate guessing.
Local test result
Real PaymentIntent generated:
int_hkdmpt4f9hip47fh6au. Verification screenshots (card fields filled / 3DS challenge / native success) attached to ACE-597.Test plan
maestro check-syntaxclean on all yaml filesset -euo pipefail, idempotent across re-runs (cold-launches the app)test_webview_checkout_renders.yaml: 4/5 green on Pixel 6 / API 34 (1 transient network fail, fixed via timeout bump)test_webview_card_3ds_success.sh: 2/2 green on Pixel 6 / API 34 (~210s, real PI generated)Notes for reviewer
.gitignorechange ignores Maestro'stakeScreenshotoutputwebview_checkout_renders.pngwritten to the repo root.manual_firstper ticket); each test can be invoked from a one-liner job.adb+maestroin PATH. No API keys needed.