diff --git a/.maestro/signin/02-password-errors.yaml b/.maestro/signin/02-password-errors.yaml index bc0182bf..b80936cb 100644 --- a/.maestro/signin/02-password-errors.yaml +++ b/.maestro/signin/02-password-errors.yaml @@ -38,10 +38,18 @@ tags: visible: "Sign in with a password instead" timeout: 20000 - tapOn: "Sign in with a password instead" +- extendedWaitUntil: + visible: + id: login-password-input + timeout: 10000 - runFlow: - file: ../subflows/password-form.yaml + file: ../subflows/type-secret.yaml env: - LOGIN: ${ACCOUNT}@example.org + FIELD: login-password-input + # The email is filled in, so the password field focuses itself. + TAP: "no" + TEXT: ${PASSWORD} +- pressKey: Enter - extendedWaitUntil: visible: "Can't reach mail.does-not-exist.invalid|No mail server at mail.does-not-exist.invalid|Sign-in failed" timeout: 60000 diff --git a/.maestro/signin/03-totp-password.yaml b/.maestro/signin/03-totp-password.yaml index 85514778..b892ee69 100644 --- a/.maestro/signin/03-totp-password.yaml +++ b/.maestro/signin/03-totp-password.yaml @@ -16,7 +16,7 @@ tags: env: LOGIN: ${TOTP_ACCOUNT}@example.org - extendedWaitUntil: - visible: "Two-factor code" + visible: "Authentication code" timeout: 30000 - takeScreenshot: totp-01-code-asked - runFlow: ../subflows/two-factor.yaml diff --git a/.maestro/signin/19-add-link.yaml b/.maestro/signin/19-add-link.yaml index fc183e1b..9ea216ed 100644 --- a/.maestro/signin/19-add-link.yaml +++ b/.maestro/signin/19-add-link.yaml @@ -14,8 +14,16 @@ tags: env: CALL: /pair?user=${ACCOUNT2}&deliver=openurl - extendedWaitUntil: - visible: "Sign in with a link." + visible: "Open in .*Bulwark Mobile.*|Sign in with a link." timeout: 60000 +- runFlow: + when: + visible: "Open in .*Bulwark Mobile.*" + commands: + - tapOn: "Open" +- extendedWaitUntil: + visible: "Sign in with a link." + timeout: 20000 - takeScreenshot: add-link-01-prompt - assertVisible: "This link adds an account.*" - tapOn: diff --git a/.maestro/subflows/clear-field.yaml b/.maestro/subflows/clear-field.yaml new file mode 100644 index 00000000..3fb6022d --- /dev/null +++ b/.maestro/subflows/clear-field.yaml @@ -0,0 +1,13 @@ +# Empty the field with id FIELD. A tap puts the cursor where it lands, and +# eraseText only deletes before the cursor, so select everything first. +appId: org.bulwarkmail.mobile +--- +- longPressOn: + id: ${FIELD} +- runFlow: + when: + visible: "Select All" + commands: + - tapOn: "Select All" + - pressKey: Backspace +- eraseText: 120 diff --git a/.maestro/subflows/confirm-link.yaml b/.maestro/subflows/confirm-link.yaml index d0917c13..452fc8c0 100644 --- a/.maestro/subflows/confirm-link.yaml +++ b/.maestro/subflows/confirm-link.yaml @@ -1,9 +1,18 @@ # A sign-in link from another app asks first. Continue. appId: org.bulwarkmail.mobile --- +# simctl openurl acts like a link from another app: iOS asks first. +- extendedWaitUntil: + visible: "Open in .*Bulwark Mobile.*|Sign in with a link.|Open the sign-in page of.*" + timeout: ${LINK_WAIT || 60000} +- runFlow: + when: + visible: "Open in .*Bulwark Mobile.*" + commands: + - tapOn: "Open" - extendedWaitUntil: visible: "Sign in with a link.|Open the sign-in page of.*" - timeout: ${LINK_WAIT || 60000} + timeout: 20000 - takeScreenshot: link-confirm-prompt - tapOn: text: "Continue" diff --git a/.maestro/subflows/finish-two-factor-if-asked.yaml b/.maestro/subflows/finish-two-factor-if-asked.yaml index d6bd8129..84fa264f 100644 --- a/.maestro/subflows/finish-two-factor-if-asked.yaml +++ b/.maestro/subflows/finish-two-factor-if-asked.yaml @@ -3,10 +3,10 @@ appId: org.bulwarkmail.mobile --- - extendedWaitUntil: - visible: "Two-factor code|Inbox" + visible: "Authentication code|Inbox" timeout: 90000 - runFlow: when: - visible: "Two-factor code" + visible: "Authentication code" commands: - runFlow: two-factor.yaml diff --git a/.maestro/subflows/start.yaml b/.maestro/subflows/start.yaml index c85d5e1f..3dc66523 100644 --- a/.maestro/subflows/start.yaml +++ b/.maestro/subflows/start.yaml @@ -2,6 +2,13 @@ # env CAMERA: allow (default) or deny. appId: org.bulwarkmail.mobile --- +# A system prompt left over from an earlier flow ("Open in …?") stays on +# screen across app launches. +- runFlow: + when: + visible: "Open in .*" + commands: + - tapOn: "Cancel" - launchApp: clearState: true clearKeychain: true diff --git a/.maestro/subflows/two-factor.yaml b/.maestro/subflows/two-factor.yaml index 6e419252..58cf5e64 100644 --- a/.maestro/subflows/two-factor.yaml +++ b/.maestro/subflows/two-factor.yaml @@ -3,7 +3,7 @@ appId: org.bulwarkmail.mobile --- - extendedWaitUntil: - visible: "Two-factor code" + visible: "Authentication code" timeout: 30000 - runScript: file: ../scripts/helper.js diff --git a/.maestro/subflows/type.yaml b/.maestro/subflows/type.yaml index e7c7f5e4..6eed294d 100644 --- a/.maestro/subflows/type.yaml +++ b/.maestro/subflows/type.yaml @@ -20,7 +20,7 @@ appId: org.bulwarkmail.mobile when: true: ${ERASE == 'yes'} commands: - - eraseText: 80 + - runFlow: clear-field.yaml - inputText: ${TEXT} - runFlow: when: @@ -31,11 +31,8 @@ appId: org.bulwarkmail.mobile - retry: maxRetries: 2 commands: - - tapOn: - id: ${FIELD} - - waitForAnimationToEnd: - timeout: 2000 - - eraseText: 80 + - runFlow: + file: clear-field.yaml - waitForAnimationToEnd: timeout: 1000 - inputText: ${TEXT} diff --git a/.maestro/subflows/webmail-login-page.yaml b/.maestro/subflows/webmail-login-page.yaml index 4ef5dddf..cb939892 100644 --- a/.maestro/subflows/webmail-login-page.yaml +++ b/.maestro/subflows/webmail-login-page.yaml @@ -10,9 +10,7 @@ appId: org.bulwarkmail.mobile - inputText: ${LOGIN} - tapOn: "Enter your password" - inputText: ${PASSWORD} -- tapOn: - text: "Sign in" - index: 1 +- tapOn: "Sign in" - runFlow: when: true: ${TOTP == 'yes'} @@ -26,6 +24,5 @@ appId: org.bulwarkmail.mobile CALL: /totp - tapOn: "000000" - inputText: ${output.helper.code} - - tapOn: - text: "Sign in|Verify" - index: 1 + - tapOn: "Sign in|Verify" + diff --git a/scripts/e2e/boot-sim.sh b/scripts/e2e/boot-sim.sh index a96f12ac..b2a98c6c 100644 --- a/scripts/e2e/boot-sim.sh +++ b/scripts/e2e/boot-sim.sh @@ -43,6 +43,28 @@ xcrun simctl spawn "$UDID" defaults write $PREFS KeyboardShowPredictionBar -bool xcrun simctl spawn "$UDID" defaults write com.apple.WebUI AutoFillPasswords -bool false || true xcrun simctl ui "$UDID" appearance "$APPEARANCE" +# The app is built without signing (no certificate on the runner), so it +# carries no entitlements and every keychain call (expo-secure-store, which +# holds the credentials) fails with "A required entitlement isn't present". +# Sign it ad hoc with the keychain entitlement, as Xcode's "Sign to Run +# Locally" does for simulator builds. +ENT="$RUNNER_TEMP/simulator.entitlements" +cat > "$ENT" <<'PLIST' + + + + + application-identifier + 8ZANF9LQ39.org.bulwarkmail.mobile + keychain-access-groups + + 8ZANF9LQ39.org.bulwarkmail.mobile + + + +PLIST +codesign --force --sign - --entitlements "$ENT" --timestamp=none "$APP" +codesign -d --entitlements - "$APP" 2>/dev/null | grep -c keychain-access-groups xcrun simctl install "$UDID" "$APP" # A photo for the compose flow's attachment. xcrun simctl addmedia "$UDID" "$(dirname "$0")/../../assets/icon.png" || true