Skip to content

E2E: Downloads coverage - #3859

Merged
yasserfaraazkhan merged 3 commits into
e2e/03-mattermost-shellfrom
e2e/05-downloads
Jul 1, 2026
Merged

E2E: Downloads coverage #3859
yasserfaraazkhan merged 3 commits into
e2e/03-mattermost-shellfrom
e2e/05-downloads

Conversation

@yasserfaraazkhan

@yasserfaraazkhan yasserfaraazkhan commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Stacked PR 5/10 — downloads helpers + all download specs.

Test plan

  • e2e/specs/downloads/

Change Impact: 🟡 Medium

Regression Risk: The changes are mostly isolated to E2E test helpers and download-related specs, but they touch shared test utilities, Electron teardown flows, and persisted download-state handling. Risk is moderate because failures could surface in cleanup, file-lock handling, or download UI behavior across multiple download scenarios.

QA Recommendation: Automated coverage is strong for the added download flows, but a small amount of manual verification is still recommended for the main download, cancel, open, and clear-all paths in the downloads UI.
Generated by CodeRabbitAI

@mm-cloud-bot

Copy link
Copy Markdown

@yasserfaraazkhan: Adding the "do-not-merge/release-note-label-needed" label because no release-note block was detected, please follow our release note process to remove it.

Details

I understand the commands that are listed here

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 40 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 23db9c84-152a-45f7-927a-e8840a97c557

📥 Commits

Reviewing files that changed from the base of the PR and between 8fc6c40 and 711060b.

📒 Files selected for processing (4)
  • e2e/helpers/downloads.ts
  • e2e/helpers/downloadsDropdown.ts
  • e2e/specs/downloads/download_cancel.test.ts
  • e2e/specs/downloads/download_open.test.ts
📝 Walkthrough

Walkthrough

This PR adds e2e helper modules (downloads.ts, downloadsDropdown.ts) for Playwright/Electron download testing, including a local HTTP server, app launching, dropdown interaction, and state polling utilities. New test specs cover download cancellation, clear-all, opening, and video downloads. Existing specs are refactored to use a shared closeElectronAppFast teardown helper.

Changes

Download E2E Helpers and Tests

Layer / File(s) Summary
Download server and lifecycle helpers
e2e/helpers/downloads.ts
Adds DownloadServer type and functions for serving downloads via HTTP, launching the app with a downloads directory, opening the dropdown, triggering downloads from popups, reading/polling downloads.json state, waiting for downloaded files, and tearing down the app/directory with retry logic.
Downloads dropdown close helper
e2e/helpers/downloadsDropdown.ts
Adds closeDownloadsDropdownIfOpen, polling and closing Electron windows matching the downloads dropdown URL, with retry on destroyed contexts and a timeout error.
Download cancel test
e2e/specs/downloads/download_cancel.test.ts
New DL-06 test cancelling an in-progress slow download via the dropdown and verifying the persisted cancelled/interrupted state.
Clear-all downloads test
e2e/specs/downloads/download_clear_all.test.ts
New DL-07 test seeding two completed downloads, clicking clear-all, and verifying both persisted state and UI rows become empty.
Download open test
e2e/specs/downloads/download_open.test.ts
New DL-05 test stubbing shell.openPath and verifying clicking a downloaded item opens the correct file path.
Video download test
e2e/specs/downloads/video_download.test.ts
New MM-T1538 test serving a fake video file, downloading it via popup, verifying byte-for-byte content match and completed download state.
Teardown refactor across existing specs
e2e/specs/downloads/download_completion.test.ts, e2e/specs/downloads/downloads_dropdown_items.test.ts, e2e/specs/downloads/downloads_manager.test.ts, e2e/specs/downloads/downloads_menubar.test.ts
Replaces app.close() plus waitForLockFileRelease with closeElectronAppFast(app, userDataDir) in cleanup finally blocks.

Sequence Diagram(s)

sequenceDiagram
  participant Test
  participant DownloadServer
  participant ElectronApp
  participant Popup
  participant DownloadsJson as downloads.json

  Test->>DownloadServer: startDownloadServer/startVideoServer
  Test->>ElectronApp: launchAppWithDownloadsDir
  Test->>Popup: triggerDownloadFromPopup (click download-link)
  Popup->>DownloadsJson: write download state (progressing/completed)
  Test->>DownloadsJson: waitForDownloadState / poll
  Test->>ElectronApp: openDownloadsDropdown / cancel / clear all
  ElectronApp->>DownloadsJson: update state on cancel/clear
  Test->>ElectronApp: closeDownloadTestApp / closeElectronAppFast
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the change set: it clearly signals added end-to-end downloads coverage.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch e2e/05-downloads

Comment @coderabbitai help to get the list of available commands.

@yasserfaraazkhan yasserfaraazkhan changed the title E2E: Downloads coverage (5/10) E2E: Downloads coverage Jun 19, 2026
Base automatically changed from e2e/02-main-hooks to e2e/01-harness-ci June 19, 2026 11:21
Base automatically changed from e2e/01-harness-ci to master June 30, 2026 23:13
Resolve harness/hook conflicts by keeping merged #3855 changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions github-actions Bot added the E2E/Run Run Desktop E2E Tests label Jun 30, 2026
@mm-cloud-bot

Copy link
Copy Markdown

❌ E2E Test Setup Failed

Failed to create E2E test instances: installation wait cancelled: context canceled

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (4)
e2e/specs/downloads/download_cancel.test.ts (1)

38-44: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider extracting menu-window discovery into a shared helper.

This window-discovery pattern (find existing window, else waitForEvent with predicate/timeout) is the kind of logic the helpers module exists for, and is likely needed by other download specs (e.g. the open/cancel flows) that also interact with the dropdown menu window. Extracting it into e2e/helpers/downloads.ts (e.g. getDownloadsDropdownMenuWindow(app)) avoids duplicating this logic across multiple spec files.

As per coding guidelines, "Reuse helpers from e2e/helpers before creating new launch, login, or server-discovery logic."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/specs/downloads/download_cancel.test.ts` around lines 38 - 44, Extract
the downloads dropdown menu window lookup into a shared helper in the downloads
helpers module, since the current find-or-wait pattern is duplicated and likely
needed across multiple download specs. Add a reusable helper such as
getDownloadsDropdownMenuWindow(app) in e2e/helpers/downloads.ts that
encapsulates the existing app.windows() search plus app.waitForEvent('window', {
predicate, timeout }) fallback, and update the download cancel flow to call that
helper instead of inlining the discovery logic. Also reuse the same helper from
the related open/cancel spec paths where the downloads dropdown menu window is
needed.

Source: Coding guidelines

e2e/specs/downloads/video_download.test.ts (3)

127-136: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Popup reference stored on an ad-hoc global instead of the sanctioned __e2eTestRefs.

(global as any).__videoDownloadPopup = popup introduces a one-off global that's never read elsewhere, instead of using the established global.__e2eTestRefs channel for main-process state exchange.

As per path instructions, "Use app.evaluate() only to read/write main-process state via global.__e2eTestRefs or global.__e2eAppReady."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/specs/downloads/video_download.test.ts` around lines 127 - 136, The popup
reference is being written to an ad-hoc global in the `app.evaluate()` block
instead of the approved main-process test refs channel. Update the
`videoDownload` popup setup to store the `BrowserWindow` on
`global.__e2eTestRefs` (matching the existing e2e state-sharing pattern) rather
than using `(global as any).__videoDownloadPopup`, and keep the `app.evaluate()`
usage limited to the sanctioned globals. Make sure the unique popup creation
flow in the `video_download.test.ts` scenario still assigns and later accesses
the reference through `__e2eTestRefs`.

Source: Path instructions


34-69: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extend the shared download-server helper for the MP4 case

e2e/helpers/downloads.ts hardcodes /download.txt and text/plain, so this test can’t reuse it as-is. If this flow should share the helper, make it accept a custom path, content type, and body; otherwise the local server here is the right approach.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/specs/downloads/video_download.test.ts` around lines 34 - 69, The MP4
download test is currently using a bespoke local server because the shared
download helper is hardcoded for a text file path and MIME type. Update the
shared helper in downloads.ts so its server setup can accept a custom request
path, content type, and body, then reuse that from startVideoServer if this flow
should share the common setup; otherwise keep the local server and avoid trying
to force the existing helper to handle only /download.txt and text/plain.

Source: Path instructions


101-118: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Reuse the download helper and centralize launch flags. This spec already has per-test downloadLocation setup, so keep that in launchAppWithDownloadsDir and closeDownloadTestApp instead of hand-rolling electron.launch here; then add the CI-hardening flags once in e2e/helpers/downloads.ts.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/specs/downloads/video_download.test.ts` around lines 101 - 118, The video
download spec is bypassing the shared download app helper and duplicating
Electron launch setup. Move this setup to use the existing download helper
functions, keeping per-test downloadLocation handling inside
launchAppWithDownloadsDir and closeDownloadTestApp, and centralize the
CI-hardening launch flags in e2e/helpers/downloads.ts so the spec no longer
calls electron.launch directly.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@e2e/helpers/downloads.ts`:
- Around line 217-250: The teardown in closeDownloadTestApp still uses the
slower app.close() plus waitForLockFileRelease flow, which should be replaced by
the shared closeElectronAppFast helper used across the updated e2e specs. Update
closeDownloadTestApp to delegate the ElectronApplication shutdown to
closeElectronAppFast (keeping the popup cleanup and download directory removal
logic intact) so this helper matches the new standardized fast teardown path.
- Around line 94-101: The local download server startup in the download helper
can crash on an unhandled http.Server error instead of rejecting cleanly. In the
setup around server.listen() and the address check, add an error listener on the
server before calling listen, and ensure any startup failure rejects the promise
so callers can handle it. Use the existing download server initialization flow
in downloads.ts to keep the fix scoped to the server startup path.

In `@e2e/helpers/downloadsDropdown.ts`:
- Around line 10-39: The helper closeDownloadsDropdownIfOpen is using
BrowserWindow.getAllWindows() to find downloadsDropdown.html, but that view is
hosted in MainWindow.contentView via a WebContentsView, so it will never be
discovered and the dropdown may remain open. Replace the window-scanning logic
with the existing close IPC/path used by the downloads dropdown, using the
relevant main-process close handler or message that already closes the downloads
UI. Keep the retry/timeout behavior if needed, but make the helper trigger the
real close flow instead of inspecting BrowserWindow webContents URLs.

In `@e2e/specs/downloads/download_cancel.test.ts`:
- Around line 52-55: The cleanup in the test teardown currently lets a failure
in closeDownloadTestApp prevent the local download server from being closed, so
update the finally block in downloads/download_cancel.test.ts to make close()
run even if closeDownloadTestApp(app, userDataDir, downloadLocation) throws. Use
separate teardown handling around closeDownloadTestApp and close so the server
shutdown is guaranteed, and keep the logic localized to the existing finally
cleanup path.

In `@e2e/specs/downloads/download_open.test.ts`:
- Around line 32-38: The test hook in the download-open spec is using a new
ad-hoc global for captured paths instead of the repo’s standard main-process
test state container. Update the `app.evaluate` setup to store and read the
`shell.openPath` call history through `global.__e2eTestRefs` (consistent with
`__e2eAppReady` patterns) and keep the hook wiring in the same place so other
specs can discover and reuse it.

---

Nitpick comments:
In `@e2e/specs/downloads/download_cancel.test.ts`:
- Around line 38-44: Extract the downloads dropdown menu window lookup into a
shared helper in the downloads helpers module, since the current find-or-wait
pattern is duplicated and likely needed across multiple download specs. Add a
reusable helper such as getDownloadsDropdownMenuWindow(app) in
e2e/helpers/downloads.ts that encapsulates the existing app.windows() search
plus app.waitForEvent('window', { predicate, timeout }) fallback, and update the
download cancel flow to call that helper instead of inlining the discovery
logic. Also reuse the same helper from the related open/cancel spec paths where
the downloads dropdown menu window is needed.

In `@e2e/specs/downloads/video_download.test.ts`:
- Around line 127-136: The popup reference is being written to an ad-hoc global
in the `app.evaluate()` block instead of the approved main-process test refs
channel. Update the `videoDownload` popup setup to store the `BrowserWindow` on
`global.__e2eTestRefs` (matching the existing e2e state-sharing pattern) rather
than using `(global as any).__videoDownloadPopup`, and keep the `app.evaluate()`
usage limited to the sanctioned globals. Make sure the unique popup creation
flow in the `video_download.test.ts` scenario still assigns and later accesses
the reference through `__e2eTestRefs`.
- Around line 34-69: The MP4 download test is currently using a bespoke local
server because the shared download helper is hardcoded for a text file path and
MIME type. Update the shared helper in downloads.ts so its server setup can
accept a custom request path, content type, and body, then reuse that from
startVideoServer if this flow should share the common setup; otherwise keep the
local server and avoid trying to force the existing helper to handle only
/download.txt and text/plain.
- Around line 101-118: The video download spec is bypassing the shared download
app helper and duplicating Electron launch setup. Move this setup to use the
existing download helper functions, keeping per-test downloadLocation handling
inside launchAppWithDownloadsDir and closeDownloadTestApp, and centralize the
CI-hardening launch flags in e2e/helpers/downloads.ts so the spec no longer
calls electron.launch directly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ce31ab03-49af-496a-b78e-17184a8a0e96

📥 Commits

Reviewing files that changed from the base of the PR and between 08129c4 and 8fc6c40.

📒 Files selected for processing (10)
  • e2e/helpers/downloads.ts
  • e2e/helpers/downloadsDropdown.ts
  • e2e/specs/downloads/download_cancel.test.ts
  • e2e/specs/downloads/download_clear_all.test.ts
  • e2e/specs/downloads/download_completion.test.ts
  • e2e/specs/downloads/download_open.test.ts
  • e2e/specs/downloads/downloads_dropdown_items.test.ts
  • e2e/specs/downloads/downloads_manager.test.ts
  • e2e/specs/downloads/downloads_menubar.test.ts
  • e2e/specs/downloads/video_download.test.ts

Comment thread e2e/helpers/downloads.ts
Comment thread e2e/helpers/downloads.ts
Comment thread e2e/helpers/downloadsDropdown.ts
Comment thread e2e/specs/downloads/download_cancel.test.ts
Comment thread e2e/specs/downloads/download_open.test.ts
Handle download server bind errors, use closeElectronAppFast, close the
dropdown via IPC, guard teardown with allSettled, and store openPath
captures on __e2eTestRefs.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions github-actions Bot added E2E/Run Run Desktop E2E Tests and removed E2E/Run Run Desktop E2E Tests labels Jun 30, 2026
@mm-cloud-bot

Copy link
Copy Markdown

❌ E2E Test Setup Failed

Failed to create E2E test instances: installation wait cancelled: context canceled

@yasserfaraazkhan

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@yasserfaraazkhan yasserfaraazkhan added E2E/Reset-Servers Destroy E2E server for a fresh Run. Add E2E/Run label to kick off an e2e run. and removed E2E/Run Run Desktop E2E Tests E2E/Reset-Servers Destroy E2E server for a fresh Run. Add E2E/Run label to kick off an e2e run. labels Jul 1, 2026
@yasserfaraazkhan
yasserfaraazkhan changed the base branch from master to e2e/03-mattermost-shell July 1, 2026 00:22
@yasserfaraazkhan
yasserfaraazkhan merged commit 0922144 into e2e/03-mattermost-shell Jul 1, 2026
28 of 29 checks passed
@yasserfaraazkhan
yasserfaraazkhan deleted the e2e/05-downloads branch July 1, 2026 00:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants