feat: screenshot automation#14722
Draft
miaulalala wants to merge 28 commits into
Draft
Conversation
Contributor
📖 Documentation PreviewNo RST documentation pages changed in this PR. Last updated: Wed, 20 May 2026 22:00:59 GMT |
susnux
reviewed
May 12, 2026
susnux
reviewed
May 12, 2026
added 2 commits
May 19, 2026 13:48
Add @playwright/test + @nextcloud/e2e-test-server as the screenshot automation stack (no prior automation existed on this repo). - playwright.config.ts — single-worker Chromium, Chrome 142+ UA override (NC 33 shows a browser-compat warning for lower version strings) - playwright/global-setup.ts — Docker container start, NC configuration, brute-force protection disable (key: auth.bruteforce.protection.enabled) - playwright/global-teardown.ts — container stop + pngquant compression - playwright/helpers.ts — docScreenshot, docElementScreenshot, occ, tryOcc, uploadFile, uploadAvatar, ocsRequest, seedChatMessages, etc. AI-Assisted-By: Claude Sonnet 4.6 <claude@anthropic.com> Signed-off-by: Anna Larch <anna@larch.dev>
Three spec files covering the main areas of the user manual: - playwright/e2e/user/files.spec.ts — 12 Files app screenshots - playwright/e2e/user/webinterface.spec.ts — 6 web interface screenshots (login, dashboard, nav bar, unified search, profile menu, customize button) - playwright/e2e/user/talk/conversations.spec.ts — 22 Talk conversations screenshots Implementation notes: - Cookie reuse pattern: login once in beforeAll, cache cookies, restore in beforeEach — avoids brute-force throttle on repeated logins - Talk 1:1 DM creation uses OCS API (POST /v4/room, roomType=1) - Talk chat history requires ?lookIntoFuture=0 (Talk 23 returns HTTP 400 with empty body otherwise) - findOrCreateGroup() called in beforeAll to avoid participant-sync race - Conversation locator uses [title="…"] attribute to avoid strict-mode violations when a user appears in multiple conversations AI-Assisted-By: Claude Sonnet 4.6 <claude@anthropic.com> Signed-off-by: Anna Larch <anna@larch.dev>
miaulalala
added a commit
that referenced
this pull request
May 19, 2026
…e-test-server Replace @nextcloud/cypress (EOL) and cypress with @playwright/test and @nextcloud/e2e-test-server per susnux's review feedback on PR #14722. The Docker container layer (startNextcloud, configureNextcloud, etc.) maps directly from @nextcloud/cypress/docker to @nextcloud/e2e-test-server/docker with no behavioral changes. The user agent override previously required CDP workarounds in Cypress (Network.setUserAgentOverride per-test); Playwright handles this globally via playwright.config.ts `use.userAgent`. All cy.task() helpers (occ, uploadFile, mkdavCol, uploadAvatar, seedChatMessages, etc.) become plain async functions in playwright/helpers.ts — no IPC separation needed since Playwright tests run in Node.js rather than the browser. AI-Assisted-By: Claude Sonnet 4.6 <claude@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
50e10b6 to
955641b
Compare
4 tasks
…panel Was incorrectly capturing the participants tab. Navigate to conversation settings → Guests section to show the open-conversation and guest-access toggles, matching the intended screenshot content. AI-Assisted-By: Claude Sonnet 4.6 <claude@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
…tasks messages-expiration: screenshot the specific .settings-section containing the "Message expiration" heading instead of the whole settings container, matching the tight crop of the original screenshot. note-to-self: seed the conversation with a 5-item task list (2 checked) in beforeAll so the screenshot shows the task counter and checkboxes. AI-Assisted-By: Claude Sonnet 4.6 <claude@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
files.spec.ts: - Add Amara and Malik as peer users for sharing - Add Photos/Red desert.jpg to photos folder - Add Fundraising Pitch.md at root level (varied file type) - Add Documents/Q3 Meeting Agenda.md and Event Budget.csv - Add Projects/ folder - Share Documents with both admin and Amara; share Q2 Proposal with Malik - Add incoming share: Amara → Christine (Venue Scouting Notes.md) - Set Christine's user status to "Working on Q3 event planning" webinterface.spec.ts: - Seed 3 Notes entries so the dashboard Notes widget shows content conversations.spec.ts: - Seed note-to-self with a 5-item task list (2 checked) for task counter - Fix group-public-settings to show guests/moderation panel - Fix messages-expiration to crop to the specific settings section AI-Assisted-By: Claude Sonnet 4.6 <claude@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
files.spec.ts: - Generate Gala Proposal 2026.docx and Volunteer Agreement.docx via LibreOffice headless conversion (proper Word format, varied file icons) conversations.spec.ts: - Extend 1:1 DM to 10 messages; add emoji reactions (👍 ❤️ 🙏) via new reactToMessage helper - Seed 7 group messages in "Event planning"; add reactions (🎉 👏) to the venue confirmation message - Set emoji icon 🎪 on "Event planning" room - Add "Design Team" room (🎨) with Lila and Kieran; 4 seeded messages - Add "Project Updates" room (📢) with full team; 5 seeded messages helpers.ts: - Export reactToMessage() for adding emoji reactions to chat messages AI-Assisted-By: Claude Sonnet 4.6 <claude@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
Talk 23 has no "Guests" nav item. Try "General" first, then locate the .settings-section containing "Open conversation to registered" by text so the test is robust to nav label changes across Talk versions. AI-Assisted-By: Claude Sonnet 4.6 <claude@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
The unscoped .navigation-list__link click was matching a page-level General link and navigating away from Talk. Scope the locator to #conversation-settings-container and guard with isVisible(). AI-Assisted-By: Claude Sonnet 4.6 <claude@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
…ges-expiration group-public-settings: target #settings-section_conversation-settings directly (Talk 23 uses [role="region"] for sections, not .settings-section) and clip to the top 280px showing the open/guest-access toggles. messages-expiration: the setting only appears when backgroundjobs_mode=cron (Talk capability gate); add that OCC call to global-setup and locate the expiration label by text within #settings-section_conversation-settings, then clip a page screenshot around its bounding box. Signed-off-by: Anna Larch <anna@larch.dev> AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
…k UI New users: adrian_l, charlotte_m, orion_g, analise_l with avatars New 1:1 DMs: charlotte_m (venue deposit), orion_g (@mention unread badge), adrian_l (decorator query) New groups: Board Updates (📋), Volunteer Coordination (🤝) Screenshot improvements: - note-to-self: wait for task list to render before screenshot - one-to-one-right-sidebar: clip to top 380px (user info, not empty lower area) - new-room: seed 2 messages via API then reload for populated chat view - participant-menu, open-settings, ban-participant, conversation-notifications: clip to [role="menu"] bounding box + 16px padding instead of full page - group-public-settings, messages-expiration: add 20px padding to clips - ban-participant-list: pre-ban lila_h + malik_s; screenshot the nested "Banned users" dialog (3 entries); clean up all bans after - archived-conversations-button: seed @ALL mention before archiving; clip to bottom 160px of sidebar showing button with notification badge - archived-conversations-list: use .first() to handle duplicate DOM entries Signed-off-by: Anna Larch <anna@larch.dev> AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
All four 1:1 DM seeding guards were using limit=1 and checking msgs.length === 0, which failed silently because Talk always injects a "You created the conversation" system message on room creation. Changed to limit=20 with a filter that excludes system messages. Note-to-self API seeding requires a browser session to have visited /apps/spreed first — pure API calls are silently dropped by Talk 23. Moved the task-list seeding to after the browser context navigates to the Talk app, and added a UI-typing fallback in the test itself as a safety net. Added reminder seeding for the dashboard panel (Amara DM and Event planning group), and enabled fake media streams + camera/microphone permissions in playwright.config.ts so call-UI flows can be tested. AI-Assisted-By: Claude Sonnet 4.6 <claude@anthropic.com> Signed-off-by: Anna Larch <anna@larch.dev> Signed-off-by: Anna Larch <anna@nextcloud.com>
…-button ban-participant-list: "Manage bans" navigates within the settings container — the Moderation section animates away before the banned- users view fully renders. Wait for #settings-section_conversation- settings to disappear before screenshotting so the banned-users dialog is unobscured. archived-conversations-button: seeding an @ALL mention in the same test triggers an "Unread mentions" button that floats above the Archived conversations button inside the fixed 160px clip. Switch to anchoring the clip on the Archived conversations button's own bounding box so the clip is always tight to the button regardless of what appears above it. AI-Assisted-By: Claude Sonnet 4.6 <claude@anthropic.com> Signed-off-by: Anna Larch <anna@larch.dev> Signed-off-by: Anna Larch <anna@nextcloud.com>
Move Talk DM file upload + share calls inside the conditional seeding block, between the "Will do" message and "Perfect" reply, so share cards appear at the correct position in chat history (visible in viewport) and populate the right-sidebar Files section. AI-Assisted-By: claude-sonnet-4-6 Signed-off-by: Anna Larch <anna@nextcloud.com>
Document four patterns discovered during Talk conversation screenshot automation: bounding-box clipping, contextual padding, animation waits for nested panels, and inline seeding of rich content between messages. AI-Assisted-By: claude-sonnet-4-6 Signed-off-by: Anna Larch <anna@nextcloud.com>
…shots - archived-conversations-button: use plain message (no @ALL) so no unread-mention badge appears above the button in the footer - archived-conversations-list: archive Design Team + Volunteer Coordination temporarily for a populated list; crop to upper half - creating-open-conversation: set laptop emoji via pressSequentially (fill() bypasses Vue reactivity on the emoji mart search), fill description field; dismiss emoji mart by waiting for Frequently Used to be hidden before clicking the first result - new-room (Product team): add lila_h and malik_s as participants, seed six messages from four users AI-Assisted-By: claude-sonnet-4-6 Signed-off-by: Anna Larch <anna@nextcloud.com>
AI-Assisted-By: claude-sonnet-4-6 Signed-off-by: Anna Larch <anna@nextcloud.com>
…uard, archive clip - Fix Talk emoji avatar API path: /v1/conversation/ → /v1/room/ (all 6 calls were silently 404ing on NC33/Talk 23) - Filter systemMessage field in event-planning seeding guard so "You set the conversation picture" system messages don't block chat seeding on fresh containers - New room: set laptop emoji after creation so it matches creating-open-conversation - Archived conversations button: switch to @ALL mention for unread dot; dynamically clip screenshot to start below "Unread mentions" nav button when present, using isVisible() guard before boundingBox() to avoid 60s action-timeout hang - Archived conversations list: archive Design Team + Volunteer Coordination in addition to Event Planning; crop to upper half of list - AGENTS.md: add isVisible()-before-boundingBox() guideline AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
…ar integration test
- Seed a CalDAV calendar event linked to the Event planning Talk room in
beforeAll so the Talk dashboard "Upcoming meetings" panel always has content
- Add 'Schedule a meeting' test that navigates to Calendar, opens a new event,
fills in the title, clicks 'Add Talk conversation' to show the room picker,
screenshots the picker (showing available Talk rooms), then dismisses it
and saves the event
- Handle the three-dialog chain: new-event popover → room picker →
discard-confirmation (use Cancel to preserve the form, then Save)
- Fix: Calendar new-event button is labelled 'Create new event', not 'New event'
- Fix: event creation form uses a popover (not .app-sidebar--open); anchor on
getByPlaceholder('Title') which is always visible when the form is ready
AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Anna Larch <anna@nextcloud.com>
…eed/ Move all user provisioning, Talk room/message creation, calendar event seeding, and note-to-self / reminder seeding out of the conversations spec beforeAll and into a dedicated playwright/seed/ module. global-setup.ts now calls seed() (all API seeding) then launches a browser to capture storageState in playwright/.auth/state.json so each test starts pre-authenticated without per-test login calls. Removes the authCookies / beforeEach pattern from the spec. AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
Adds playwright/seed/files.ts which runs as part of global-setup: - Creates Documents/ and Projects/Q3 Gala/ folders for christine - Uploads both fixture PDFs into Projects/Q3 Gala/ - Shares the Q3 Gala folder with amara_w (editor) - Shares Team Meeting Notes.pdf with lila_h (read-only) - Creates a public link share on Q2 Project Proposal.pdf - Ensures amara_w has a copy of Q2 Project Proposal.pdf and shares it back to christine, so christine's "Shared with you" view has content Any spec covering Files, Sharing, or Activities can now assume this state exists without per-spec upload/share boilerplate. AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
…state
Adds text-based fixture files covering file types documented in the
user manual — markdown, CSV, VCF contacts, and ICS calendar import.
Wallpaper JPEGs (local, not committed) serve as image fixtures.
Seed now creates a realistic folder tree for christine:
Documents/ — Event Brief.md, Budget Overview.csv, Volunteer List.csv,
team-contacts.vcf, q3-gala.ics
Photos/ — 4 landscape JPEGs (forest-green, ocean-golden,
city-night-purple, milky-way)
Projects/Q3 Gala/ — Q2 Project Proposal.pdf, Team Meeting Notes.pdf
Sharing covers all four modes:
- Projects/Q3 Gala/ → amara_w (editor)
- Documents/ → malik_s (read-only)
- Team Meeting Notes.pdf → lila_h (read-only user share)
- Q2 Project Proposal.pdf → public link
- amara_w shares Q2 Project Proposal.pdf back to christine
- amara_w shares Budget Overview.csv with lila_h
AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Anna Larch <anna@nextcloud.com>
All fixture files now live under playwright/fixtures/ alongside the rest of the Playwright infrastructure. Updated FIXTURES_DIR in seed/files.ts, seed/talk.ts, and e2e/user/files.spec.ts to use __dirname-relative paths. Binary fixtures (pdfs/, images/) added to .gitignore — they are local files like the avatar images and are not committed to the repo. Text fixtures (documents/, contacts/, calendar/) are committed. The cypress/fixtures/pdfs/ directory is now orphaned; leaving it in place so any legacy Cypress runs are unaffected. AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
…to all seed users Christine is now "Christine Schott" (c.schott@example.org) with org and role set. All 10 users now have email addresses (set via admin OCS — users cannot update their own email through the API), which is required for Calendar invitation and scheduling features to function correctly. Profile data added for all users: organisation and role now set for every account, giving the 1:1 sidebar and People search realistic content. Christine also has a phone number set. Updated q3-gala.ics to use the full name and corrected email address. AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
Spreads Talk message creation_timestamp values across realistic date ranges (e.g. event group: 21→1 days ago, DMs: 14→2 days ago) via PHP PDO writing directly to the SQLite DB — the Talk API offers no timestamp parameter. File uploads now pass X-OC-MTime so modification dates in the Files app reflect plausible activity rather than the seed run time. AI-Assisted-By: claude-sonnet-4-6 <noreply@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
The spreadTimestamps function was writing raw Unix integers into
oc_talk_rooms.last_activity, which is a DATETIME column
("YYYY-MM-DD HH:MM:SS"). Talk's PHP ORM throws when trying to parse the
integer as a DateTime, causing GET /v4/room to return HTTP 500 and an
empty conversation list in every test.
Fix by using SQLite's datetime(ts, 'unixepoch') to write the correct
string format. Also set Christine's last_attendee_activity to 2 h in
the future so Talk's modifiedSince poll filter (which checks
lastAttendeeActivity as a fallback) continues to return backdated rooms.
AI-Assisted-By: claude-sonnet-4-6 <noreply@anthropic.com>
Signed-off-by: Anna Larch <anna@nextcloud.com>
…tes and better selections - Add backdateFolderMtime() helper that updates both oc_filecache and the filesystem mtime so NC's lazy scanner doesn't revert the change - Backdate Documents/Photos/Projects/Notes/Talk folder mtimes after login (Talk app initialises on first login and would overwrite an earlier backdate) - Intercept PROPFIND responses in beforeEach to patch Talk's getlastmodified: NC's in-process Sabre/DAV cache ignores DB writes from outside the web process - Fix multi-select test to select actual user files (Fundraising Pitch, Q2 Proposal, Volunteer Agreement) instead of the first 3 rows which are folders - Fix grid view test to dismiss any open Viewer via Escape before resetting to list view, preventing the grid button click from being intercepted AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
NC auto-generates welcome.txt at container startup; remove it via WebDAV in beforeAll so it doesn't appear in the file list screenshots. AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.com>
… Talk timestamps Document the oc_filecache path prefix, lazy-scanner filesystem sync requirement, Sabre/DAV in-process cache workaround via PROPFIND intercept, and Talk's DATETIME column format and modifiedSince poll filter behaviour. AI-Assisted-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Anna Larch <anna@nextcloud.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
@playwright/test+@nextcloud/e2e-test-serveras screenshot automationfor the Nextcloud documentation repo (no prior automation existed).
What's included:
playwright.config.ts— single-worker Chromium config, Chrome 142+ user agentoverride (NC 33 shows a browser-compat warning for lower version strings)
playwright/global-setup.ts/global-teardown.ts— Docker container lifecycle,brute-force protection disable, pngquant compression
playwright/helpers.ts—docScreenshot,docElementScreenshot,occ,tryOcc,uploadFile,uploadAvatar,ocsRequest,seedChatMessages, etc.playwright/e2e/user/files.spec.ts— 12 Files app screenshotsplaywright/e2e/user/webinterface.spec.ts— 6 web interface screenshots (login,dashboard, nav bar, unified search, profile menu, customize button)
playwright/e2e/user/talk/conversations.spec.ts— 22 Talk conversations screenshotsKey implementation notes:
beforeAll, cache cookies, restore inbeforeEach— avoids brute-force throttle on repeated loginsPOST /v4/room, roomType=1)?lookIntoFuture=0(Talk 23 returns HTTP 400 withempty body otherwise)
findOrCreateGroup()called inbeforeAllto avoid participant-sync race onthe participants tab
[title="…"]attribute to avoid strict-mode violationswhen a user appears in multiple conversations
✅ Checklist
codespellor similar and addressed any spelling issues