From 8533bd4f99cf70a58c9c458709092b8ecd782657 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Thu, 22 Oct 2026 08:20:49 +0200 Subject: [PATCH] ci: fix ios feature flow steps for the drawer, search, selection, calendar and contacts --- .maestro/features/01-folders.yaml | 8 +++--- .maestro/features/05-search.yaml | 2 +- .maestro/features/07-move-delete-tag.yaml | 13 +++++++-- .maestro/features/09-calendar.yaml | 33 ++++++++++++++++------- .maestro/features/10-contacts.yaml | 31 +++++++++++++-------- scripts/e2e/helper.mjs | 6 ++++- 6 files changed, 64 insertions(+), 29 deletions(-) diff --git a/.maestro/features/01-folders.yaml b/.maestro/features/01-folders.yaml index ec0f26d5..05925db9 100644 --- a/.maestro/features/01-folders.yaml +++ b/.maestro/features/01-folders.yaml @@ -14,7 +14,8 @@ tags: - assertVisible: "Sent([ ,].*)?" - assertVisible: "Drafts([ ,].*)?" - assertVisible: "Archive([ ,].*)?" -- assertVisible: "Projects([ ,].*)?" +# Parent folders read "Collapse, Projects" (the chevron comes first). +- assertVisible: ".*Projects.*" - tapOn: "Archive([ ,].*)?" - extendedWaitUntil: visible: ".*Invoice 2025-12.*" @@ -26,10 +27,7 @@ tags: when: notVisible: "Alpha([ ,].*)?" commands: - - tapOn: - text: "Expand" - rightOf: "Projects([ ,].*)?" - optional: true + - tapOn: "Expand, Projects.*" - tapOn: "Alpha([ ,].*)?" - extendedWaitUntil: visible: ".*Project Alpha kickoff.*" diff --git a/.maestro/features/05-search.yaml b/.maestro/features/05-search.yaml index 309918c2..c190cb14 100644 --- a/.maestro/features/05-search.yaml +++ b/.maestro/features/05-search.yaml @@ -14,6 +14,7 @@ tags: - assertNotVisible: ".*Weekly digest.*" - takeScreenshot: search-01-hit - tapOn: "Clear search" +- tapOn: "Search mail..." - inputText: "zzqx-no-such-mail" - pressKey: Enter - extendedWaitUntil: @@ -24,4 +25,3 @@ tags: - extendedWaitUntil: visible: ".*Weekly digest.*" timeout: 30000 -- hideKeyboard diff --git a/.maestro/features/07-move-delete-tag.yaml b/.maestro/features/07-move-delete-tag.yaml index b0253bcd..60115b25 100644 --- a/.maestro/features/07-move-delete-tag.yaml +++ b/.maestro/features/07-move-delete-tag.yaml @@ -55,7 +55,16 @@ tags: timeout: 10000 - takeScreenshot: actions-04-selected - tapOn: "Star" -- tapOn: "Clear selection" +# A bulk action ends selection mode by itself. +- runFlow: + when: + visible: "Clear selection" + commands: + - tapOn: "Clear selection" - longPressOn: ".*Grüße aus München.*" - tapOn: "Unstar|Star" -- tapOn: "Clear selection" +- runFlow: + when: + visible: "Clear selection" + commands: + - tapOn: "Clear selection" diff --git a/.maestro/features/09-calendar.yaml b/.maestro/features/09-calendar.yaml index c1c8de93..31e7ac49 100644 --- a/.maestro/features/09-calendar.yaml +++ b/.maestro/features/09-calendar.yaml @@ -8,6 +8,15 @@ tags: - evalScript: ${output.event = 'E2E event ' + DEVICE + ' ' + Date.now() % 100000} - tapOn: id: tab-calendar +# The first visit asks for notification permission (event reminders). +- extendedWaitUntil: + visible: ".*Would Like to Send You Notifications.*|Go to today" + timeout: 30000 +- runFlow: + when: + visible: ".*Would Like to Send You Notifications.*" + commands: + - tapOn: "Allow" - extendedWaitUntil: visible: "Go to today" timeout: 30000 @@ -36,7 +45,6 @@ tags: timeout: 10000 - tapOn: "Title" - inputText: ${output.event} -- hideKeyboard - scrollUntilVisible: element: "Add reminder" direction: DOWN @@ -64,22 +72,29 @@ tags: - takeScreenshot: calendar-06-detail - assertVisible: ".*15 minutes before.*" -# Edit the title +# Edit: add a location (an empty field, so no cursor games in the title) - tapOn: "Edit" - extendedWaitUntil: visible: "Edit event" timeout: 10000 -- tapOn: ${output.event} -- inputText: " edited" -- hideKeyboard +- scrollUntilVisible: + element: "Place or address" + direction: DOWN + timeout: 10000 +- tapOn: "Place or address" +- inputText: "Room 42" - tapOn: "Save" - extendedWaitUntil: - visible: ".*${output.event} edited.*" + visible: ".*Room 42.*" timeout: 20000 - takeScreenshot: calendar-07-edited -# Delete -- tapOn: ".*${output.event} edited.*" +# Delete (the detail sheet is still open after saving) +- runFlow: + when: + notVisible: "Delete" + commands: + - tapOn: ".*${output.event}.*" - extendedWaitUntil: visible: "Delete" timeout: 10000 @@ -91,7 +106,7 @@ tags: text: "Delete" below: "Delete this event.*" - extendedWaitUntil: - notVisible: ".*${output.event} edited.*" + notVisible: ".*${output.event}.*" timeout: 20000 - takeScreenshot: calendar-08-deleted - tapOn: diff --git a/.maestro/features/10-contacts.yaml b/.maestro/features/10-contacts.yaml index 6d6c4779..9a04c3bd 100644 --- a/.maestro/features/10-contacts.yaml +++ b/.maestro/features/10-contacts.yaml @@ -27,17 +27,26 @@ tags: - extendedWaitUntil: visible: "Save" timeout: 10000 -- tapOn: - text: "First name" - index: 1 -- inputText: "E2E" -- tapOn: - text: "Last name" - index: 1 -- inputText: ${output.last} -- tapOn: "email@example.com" -- inputText: "e2e.contact@example.net" -- hideKeyboard +- runFlow: + file: ../subflows/type.yaml + env: + FIELD: contact-first-name + TEXT: E2E +- runFlow: + file: ../subflows/type.yaml + env: + FIELD: contact-last-name + TEXT: ${output.last} +- scrollUntilVisible: + element: + id: contact-email-0 + direction: DOWN + timeout: 10000 +- runFlow: + file: ../subflows/type.yaml + env: + FIELD: contact-email-0 + TEXT: e2e.contact@example.net - takeScreenshot: contacts-03-form - tapOn: "Save" - extendedWaitUntil: diff --git a/scripts/e2e/helper.mjs b/scripts/e2e/helper.mjs index 9c23c068..e5326fe1 100644 --- a/scripts/e2e/helper.mjs +++ b/scripts/e2e/helper.mjs @@ -287,9 +287,13 @@ async function sendMail({ from = 'userb', to, subject, text, html, attach }) { async function findMail({ as = 'userb', subject, timeout = 30 }) { const s = await jmapSession(as); const deadline = Date.now() + timeout * 1000; + // Stalwart's subject filter finds nothing for "Re: x" or "Fwd: x" (it + // indexes the base subject), so search without the prefixes and compare + // the full subject below. + const base = subject.replace(/^((re|fwd?|aw|wg)\s*:\s*)+/i, ''); for (;;) { const [[, q], [, got]] = await jmap(as, [ - ['Email/query', { accountId: s.accountId, filter: { subject }, sort: [{ property: 'receivedAt', isAscending: false }], limit: 5 }, '0'], + ['Email/query', { accountId: s.accountId, filter: { subject: base }, sort: [{ property: 'receivedAt', isAscending: false }], limit: 10 }, '0'], ['Email/get', { accountId: s.accountId, '#ids': { resultOf: '0', name: 'Email/query', path: '/ids' }, properties: ['subject', 'attachments', 'mailboxIds', 'from'] }, '1'], ]); const hit = got.list.find((m) => m.subject === subject);