Skip to content

Add unexpected toast message detection to Cypress tests#3147

Open
Sabr1n4W wants to merge 15 commits into
developfrom
cypress-check-for-unexpected-toasts
Open

Add unexpected toast message detection to Cypress tests#3147
Sabr1n4W wants to merge 15 commits into
developfrom
cypress-check-for-unexpected-toasts

Conversation

@Sabr1n4W
Copy link
Copy Markdown
Contributor

@Sabr1n4W Sabr1n4W commented May 18, 2026

Fixes #

Type

  • Bugfix
  • Feature
  • Documentation
  • Refactoring (e.g. Style updates, Test implementation, etc.)
  • Other (please describe):

Checklist

  • Code updated to current develop branch head
  • Passes CI checks
  • Is a part of an issue
  • Tests added for the bugfix or newly implemented feature, describe below why if not
  • Changelog is updated
  • Documentation of code and features exists

Changes

  • Add check for unexpected toast messages as last check for all tests by overriding it
  • Add same check for unexpected toast messages before visiting / reloading a page by overriding cy.visit() and cy.reload()
  • Skip the unexpected toast check when the test switched origins (e.g. through simulating opening a link)
  • Add missing explicit toast checks where needed

Summary by CodeRabbit

  • Tests
    • Enhanced end-to-end test coverage with improved assertion verification for authorization checks, authentication flows, and toast message validation. Added test infrastructure improvements to automatically verify final state after each test execution.

Review Change Stack

Sabr1n4W added 12 commits May 3, 2026 15:00
…unexpected-toasts

# Conflicts:
#	tests/Frontend/e2e/AdminServersViewServerActions.cy.js
#	tests/Frontend/e2e/RoomsIndex.cy.js
#	tests/Frontend/e2e/RoomsViewDescription.cy.js
#	tests/Frontend/e2e/RoomsViewFiles.cy.js
#	tests/Frontend/e2e/RoomsViewFilesFileActions.cy.js
#	tests/Frontend/e2e/RoomsViewGeneral.cy.js
#	tests/Frontend/e2e/RoomsViewHistory.cy.js
#	tests/Frontend/e2e/RoomsViewMeetings.cy.js
#	tests/Frontend/e2e/RoomsViewMembers.cy.js
#	tests/Frontend/e2e/RoomsViewMembersBulkActions.cy.js
#	tests/Frontend/e2e/RoomsViewMembersMemberActions.cy.js
#	tests/Frontend/e2e/RoomsViewPersonalizedLinks.cy.js
#	tests/Frontend/e2e/RoomsViewPersonalizedLinksTokenActions.cy.js
#	tests/Frontend/e2e/RoomsViewRecordings.cy.js
#	tests/Frontend/e2e/RoomsViewRecordingsRecordingActions.cy.js
#	tests/Frontend/e2e/RoomsViewSettings.cy.js
#	tests/Frontend/e2e/RoomsViewStreaming.cy.js
#	tests/Frontend/e2e/RoomsViewStreamingConfigActions.cy.js
@Sabr1n4W Sabr1n4W self-assigned this May 18, 2026
@Sabr1n4W Sabr1n4W added the tests Softwaretests without any feature improvement label May 18, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 18, 2026

Warning

Rate limit exceeded

@Sabr1n4W has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 34 minutes and 18 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: faae8bd9-f42b-42df-b77a-298ca2ae37e4

📥 Commits

Reviewing files that changed from the base of the PR and between 069bf47 and e922417.

📒 Files selected for processing (1)
  • tests/Frontend/support/commands/commandOverrides.js

Walkthrough

This PR adds test infrastructure to validate that Cypress e2e tests end without stray toast messages, and applies that validation to authorization and login test flows. A new checkFinalState command checks for residual toasts at test completion, while test-lifecycle overrides ensure the check runs after every test and before navigation commands. Five e2e tests are then updated with explicit toast message assertions.

Changes

E2E test toast message validation

Layer / File(s) Summary
Toast validation command and test lifecycle integration
tests/Frontend/support/commands/generalCommands.js, tests/Frontend/support/commands/commandOverrides.js, tests/Frontend/support/e2e.js
Introduces checkFinalState Cypress command that asserts no .p-toast-message elements exist at the end of same-origin tests, overrides window.it to run final state checks after each test and before cleanup, overwrites visit and reload commands to check state before navigation, and registers these overrides in the e2e support configuration.
Toast message assertions in authorization and login tests
tests/Frontend/e2e/AdminIndex.cy.js, tests/Frontend/e2e/AdminRolesNew.cy.js, tests/Frontend/e2e/AdminRoomTypesNew.cy.js, tests/Frontend/e2e/Login.cy.js
Five e2e tests add explicit toast message assertions: AdminIndex, AdminRolesNew, and AdminRoomTypesNew tests assert the unauthorized toast is shown when accessing restricted admin pages; Shibboleth and OIDC login tests assert the login success toast is shown after external authentication redirects.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • samuelwei
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is incomplete. While the PR type is marked and changes are listed, critical sections are missing: no issue number is specified in 'Fixes #', checklist items are unchecked, and changelog/documentation are not addressed. Complete the checklist items, add an issue number if applicable, update the changelog, and provide documentation as required by the template.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add unexpected toast message detection to Cypress tests' accurately summarizes the main change—implementing automatic detection of unexpected toast messages in the test suite.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cypress-check-for-unexpected-toasts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@codecov
Copy link
Copy Markdown

codecov Bot commented May 18, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.81%. Comparing base (3ee83a8) to head (e922417).
⚠️ Report is 2 commits behind head on develop.

Additional details and impacted files
@@              Coverage Diff              @@
##             develop    #3147      +/-   ##
=============================================
+ Coverage      96.80%   96.81%   +0.01%     
  Complexity      1944     1944              
=============================================
  Files            466      466              
  Lines          13291    13291              
  Branches        2190     2190              
=============================================
+ Hits           12866    12868       +2     
+ Misses           425      423       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cypress
Copy link
Copy Markdown

cypress Bot commented May 18, 2026

PILOS    Run #3040

Run Properties:  status check passed Passed #3040  •  git commit e92241712c: Add unexpected toast message detection to Cypress tests
Project PILOS
Branch Review cypress-check-for-unexpected-toasts
Run status status check passed Passed #3040
Run duration 07m 26s
Commit git commit e92241712c: Add unexpected toast message detection to Cypress tests
Committer Sabrina Wüst
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 632
View all changes introduced in this branch ↗︎

@Sabr1n4W Sabr1n4W marked this pull request as ready for review May 18, 2026 16:09
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@tests/Frontend/support/commands/commandOverrides.js`:
- Around line 47-53: The Cypress.Commands.overwrite for "reload" currently only
forwards the second parameter named options to originalFn, breaking other call
signatures; update the overwrite in the Cypress.Commands.overwrite("reload",
(originalFn, options) => { ... }) implementation to forward all received
arguments to originalFn (e.g., capture rest args from the overwrite handler and
call originalFn(...args)) so any call patterns like cy.reload(forceReload,
options) are preserved; ensure the wrapper still performs the
wrap/checkFinalState/log steps before invoking originalFn with the full
arguments list.
- Around line 20-23: The wrapper around originalIt currently invokes testFn()
and cy.checkFinalState() without returning their results, losing any return
value from testFn and preventing Mocha from waiting for the Cypress chain;
update the it-wrapper (the function passed to originalIt) to preserve the test
context and return a combined chain/value by returning the result of calling
testFn() (or wrapping it in Promise.resolve if it may be non-promise) and then
chaining cy.checkFinalState() (or returning cy.checkFinalState() after testFn()
completes) so that originalIt receives the returned chain/value; locate the call
sites using originalIt, testFn, and cy.checkFinalState to implement this change.
🪄 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: 7695dd3f-a092-4288-8251-94729c0ad659

📥 Commits

Reviewing files that changed from the base of the PR and between 42d1a17 and 069bf47.

📒 Files selected for processing (7)
  • tests/Frontend/e2e/AdminIndex.cy.js
  • tests/Frontend/e2e/AdminRolesNew.cy.js
  • tests/Frontend/e2e/AdminRoomTypesNew.cy.js
  • tests/Frontend/e2e/Login.cy.js
  • tests/Frontend/support/commands/commandOverrides.js
  • tests/Frontend/support/commands/generalCommands.js
  • tests/Frontend/support/e2e.js

Comment on lines +20 to +23
return originalIt(title, testOptions, function () {
testFn();
cy.checkFinalState();
});
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether current tests rely on Mocha context (`this`) or done-callbacks in `it(...)`.
rg -nP --type=js -C2 '\bit\s*\([^,]+,\s*function\s*\([^)]*\)\s*\{' tests/Frontend/e2e
rg -nP --type=js -C2 '\bit\s*\([^,]+,\s*function\s*\(\s*done\s*\)' tests/Frontend/e2e
rg -nP --type=js -C2 '\bthis\.' tests/Frontend/e2e

Repository: THM-Health/PILOS

Length of output: 50373


🏁 Script executed:

# First, examine the file in question
head -30 tests/Frontend/support/commands/commandOverrides.js

Repository: THM-Health/PILOS

Length of output: 1216


🏁 Script executed:

# Search for Mocha context usage (this.timeout, this.skip, this.retries) in test functions
rg -n 'this\.(timeout|skip|retries|slow)' tests/Frontend/e2e --max-count=20

# Search for done callbacks in test function parameters
rg -n 'it\([^,]+,\s*function\s*\(\s*done\s*\)' tests/Frontend/e2e --max-count=20

# Search for return statements in test functions (not cy.* chains)
rg -n 'return\s+(?!cy\.|this\.|.*\.)' tests/Frontend/e2e/*.js --max-count=20

Repository: THM-Health/PILOS

Length of output: 302


🏁 Script executed:

# Simpler search for this. usage in test files
rg -n '\bthis\.' tests/Frontend/e2e --max-count=15

# Search for return statements in test functions (simple pattern)
rg -n '^\s+return\s+(?!cy)' tests/Frontend/e2e --max-count=15

# Search for promise-based patterns (.then, .catch)
rg -n 'testFn.*\.then|testFn.*\.catch' tests/Frontend/e2e --max-count=10

Repository: THM-Health/PILOS

Length of output: 296


🏁 Script executed:

# Simple search for "this." in test files
rg 'this\.' tests/Frontend/e2e -c

# Count "return" statements in test files
rg '^\s+return' tests/Frontend/e2e -c

# Search for function(done) pattern specifically
rg 'function\s*\(\s*done\s*\)' tests/Frontend/e2e -c

# Look at a sample test to see the structure
head -100 tests/Frontend/e2e/UserProfile.cy.js | tail -50

Repository: THM-Health/PILOS

Length of output: 1562


🏁 Script executed:

# Find which test files use "this."
rg 'this\.' tests/Frontend/e2e --files-with-matches

# Search for done callbacks more thoroughly
rg 'function\s*\(\s*done' tests/Frontend/e2e

Repository: THM-Health/PILOS

Length of output: 42


🏁 Script executed:

# Search for cy.checkFinalState definition
rg 'checkFinalState' tests/Frontend/support -A 5

# Check if any test file returns a value from test function
rg 'it\([^,]+,.*function.*\{' tests/Frontend/e2e -A 10 | grep -E '(return|done)' | head -20

# Look for async/await in test functions
rg 'async\s+function' tests/Frontend/e2e

Repository: THM-Health/PILOS

Length of output: 2095


🏁 Script executed:

# Check for any explicit return statements in the test function bodies
rg -n '^\s+return\s' tests/Frontend/e2e/*.js | head -20

# Check if any test files might return promises
rg -n 'return\s+(new\s+)?Promise' tests/Frontend/e2e | head -10

# Verify the full checkFinalState implementation
cat tests/Frontend/support/commands/generalCommands.js | grep -A 20 'checkFinalState'

Repository: THM-Health/PILOS

Length of output: 1436


🏁 Script executed:

# Verify the exact code at lines 15-25 of commandOverrides.js
sed -n '15,25p' tests/Frontend/support/commands/commandOverrides.js

# Check if cy.visit override properly returns the chain
sed -n '32,50p' tests/Frontend/support/commands/commandOverrides.js

Repository: THM-Health/PILOS

Length of output: 1065


Preserve test context and return Cypress command chains in the it wrapper.

Line 21 calls testFn() directly without forwarding its return value, and line 22 calls cy.checkFinalState() but doesn't return its Cypress command chain. This causes two issues:

  1. If testFn() returns a value (promise or otherwise), it's discarded, breaking tests that rely on return semantics.
  2. cy.checkFinalState() is async (uses cy.url().then() internally), but since the wrapper doesn't return the chain, Mocha may not wait for it to complete, creating a race condition where the test finishes before final state validation runs.
Proposed fix
-  return originalIt(title, testOptions, function () {
-    testFn();
-    cy.checkFinalState();
+  return originalIt(title, testOptions, function (...args) {
+    const result = testFn.apply(this, args);
+    return cy.checkFinalState().then(() => result);
});
🤖 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 `@tests/Frontend/support/commands/commandOverrides.js` around lines 20 - 23,
The wrapper around originalIt currently invokes testFn() and
cy.checkFinalState() without returning their results, losing any return value
from testFn and preventing Mocha from waiting for the Cypress chain; update the
it-wrapper (the function passed to originalIt) to preserve the test context and
return a combined chain/value by returning the result of calling testFn() (or
wrapping it in Promise.resolve if it may be non-promise) and then chaining
cy.checkFinalState() (or returning cy.checkFinalState() after testFn()
completes) so that originalIt receives the returned chain/value; locate the call
sites using originalIt, testFn, and cy.checkFinalState to implement this change.

Comment thread tests/Frontend/support/commands/commandOverrides.js Outdated
Comment on lines +31 to +53
/**
* Override for visit
* Checks final state before performing the visit, to make sure that unexpected errors that may have happened previously are caught.
*/
Cypress.Commands.overwrite("visit", (originalFn, url, options) => {
return cy
.wrap(null, { log: false })
.then(() => cy.checkFinalState())
.then(() => cy.log(`Visit ${url}`))
.then(() => originalFn(url, options));
});

/**
* Override for reload
* Checks final state before performing the reload, to make sure that unexpected errors that may have happened previously are caught.
*/
Cypress.Commands.overwrite("reload", (originalFn, ...args) => {
return cy
.wrap(null, { log: false })
.then(() => cy.checkFinalState())
.then(() => cy.log("Reload"))
.then(() => originalFn(...args));
});
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The cypress logs are changed quite a bit because of the overrides.

e.g.
Before the overrides:

visit $url

After the overrides:

log Visit $url
- then $url

This is the case because the originalFn is called inside a then and therefore not logged as e.g. visit anymore but as then (I am not sure why this is the case but didn't find any way to "fix" this).
The wrapping and calling originalFn is necessary because of the mix between calling a cypress custom command and calling originalFn which is not possible without the wrapping.

It would be possible to suppress the logs triggered by originalFn (the -then log) using log: false and also to partially "rebuild" a similar looking log entry using Cypress.log and through this get log entries that mostly look like the ones before.

Even though this would be possible I would suggests to not suppress the logs triggered by the originalFn because they can contain some additional information which could be potentially helpful for debugging. Because of that I would also not try to "rebuild" a similar looking log entry because it could be misleading and confusing why this log entry does not contain all the additional information contained in the original log entry.

Therefore I would suggest using the current log strategy.

@Sabr1n4W
Copy link
Copy Markdown
Contributor Author

There are still some explicit checks for missing toast messages at the end of tests, for example in Login.cy.js and RoomsViewGeneral.cy.js.

These checks would also be covered by the added checks for unexpected toast messages and could therefore be removed.

I currently kept them for now because in these tests the absence of a toast is part of the tested behavior, not just a generic cleanup/final-state condition.

However, keeping only some explicit missing toast message checks at the end of tests may also be a bit confusing because other tests may rely only on cy.checkFinalState() for similar expectations.

@Sabr1n4W Sabr1n4W requested a review from samuelwei May 18, 2026 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tests Softwaretests without any feature improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant