diff --git a/tests/Frontend/e2e/AdminIndex.cy.js b/tests/Frontend/e2e/AdminIndex.cy.js index 6b92cdbcb..902e33875 100644 --- a/tests/Frontend/e2e/AdminIndex.cy.js +++ b/tests/Frontend/e2e/AdminIndex.cy.js @@ -26,6 +26,7 @@ describe("Admin index", function () { // Check if the welcome page is shown cy.url().should("not.include", "/admin"); cy.get("h1").should("be.visible").and("include.text", "home.title"); + cy.checkToastMessage("app.flash.unauthorized"); }); it("check admin index with all permissions", function () { diff --git a/tests/Frontend/e2e/AdminRolesNew.cy.js b/tests/Frontend/e2e/AdminRolesNew.cy.js index e66f2b71d..2aa4141aa 100644 --- a/tests/Frontend/e2e/AdminRolesNew.cy.js +++ b/tests/Frontend/e2e/AdminRolesNew.cy.js @@ -43,6 +43,7 @@ describe("Admin roles new", function () { // Check if the welcome page is shown cy.url().should("not.include", "/admin/room_types"); cy.get("h1").should("be.visible").and("include.text", "home.title"); + cy.checkToastMessage("app.flash.unauthorized"); }); it("add new role", function () { diff --git a/tests/Frontend/e2e/AdminRoomTypesNew.cy.js b/tests/Frontend/e2e/AdminRoomTypesNew.cy.js index c68f5b30c..bdf352425 100644 --- a/tests/Frontend/e2e/AdminRoomTypesNew.cy.js +++ b/tests/Frontend/e2e/AdminRoomTypesNew.cy.js @@ -46,6 +46,7 @@ describe("Admin room types new", function () { // Check if the welcome page is shown cy.url().should("not.include", "/admin/room_types"); cy.get("h1").should("be.visible").and("include.text", "home.title"); + cy.checkToastMessage("app.flash.unauthorized"); }); it("add new room type", function () { diff --git a/tests/Frontend/e2e/Login.cy.js b/tests/Frontend/e2e/Login.cy.js index cddd933cf..a77b699d7 100644 --- a/tests/Frontend/e2e/Login.cy.js +++ b/tests/Frontend/e2e/Login.cy.js @@ -643,6 +643,7 @@ describe("Login", function () { cy.visit("/external_login"); cy.url().should("include", "/rooms").and("not.include", "/login"); + cy.checkToastMessage("auth.flash.login"); }); it("hide shibboleth login if disabled", function () { @@ -823,6 +824,7 @@ describe("Login", function () { cy.visit("/external_login"); cy.url().should("include", "/rooms").and("not.include", "/login"); + cy.checkToastMessage("auth.flash.login"); }); it("hide oidc login if disabled", function () { diff --git a/tests/Frontend/support/commands/commandOverrides.js b/tests/Frontend/support/commands/commandOverrides.js new file mode 100644 index 000000000..a60276824 --- /dev/null +++ b/tests/Frontend/support/commands/commandOverrides.js @@ -0,0 +1,53 @@ +// Override for window.it used for all tests, to check the final state after each test, to make sure that unexpected errors +// or states that may have happened during the test are caught. + +const originalIt = window.it; + +window.it = function (title, optionsOrFunction, fn) { + // Determine test function and options based on the arguments passed to it + const testFn = + typeof optionsOrFunction === "function" ? optionsOrFunction : fn; + const testOptions = + typeof optionsOrFunction === "object" ? { ...optionsOrFunction } : {}; + + if (typeof testFn !== "function") { + // Call the original it function with the provided arguments + // This is necessary to make it.skip work correctly + return originalIt(title, optionsOrFunction, fn); + } + + // Call the original it function with the modified test function and options + return originalIt(title, testOptions, function () { + testFn(); + cy.checkFinalState(); + }); +}; + +// Add the original it.only and it.skip methods to the window object +// originalIt.only and originalIt.skip will use the overridden window.it function +window.it.only = originalIt.only; +window.it.skip = originalIt.skip; + +/** + * 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)); +}); diff --git a/tests/Frontend/support/commands/generalCommands.js b/tests/Frontend/support/commands/generalCommands.js index cb0725c04..8c98add4a 100644 --- a/tests/Frontend/support/commands/generalCommands.js +++ b/tests/Frontend/support/commands/generalCommands.js @@ -1,3 +1,25 @@ +/** + * Check that the final state of the test is correct, e.g. that there are no unexpected error toasts. + * This should be called at the end of every test to make sure that unexpected errors aren't missed in the tests. + * @memberof cy + * @method checkFinalState + * @returns void + */ +Cypress.Commands.add("checkFinalState", () => { + cy.url({ log: false }).then((currentUrl) => { + const currentOrigin = new URL(currentUrl).origin; + const baseOrigin = new URL(Cypress.config().baseUrl).origin; + + if (currentOrigin === baseOrigin) { + cy.log("Check final state"); + // Check that all toasts that maybe have been created during the test have been removed + // This makes sure that unexpected error toasts that are not handled in the test will cause the test to fail, + // which makes sure that we don't miss any unexpected errors in the tests + cy.get(".p-toast-message").should("not.exist"); + } + }); +}); + /** * Check that a user who visits this page without being logged in is redirected to the login page * @memberof cy diff --git a/tests/Frontend/support/e2e.js b/tests/Frontend/support/e2e.js index 3c6adc628..f35f87a91 100644 --- a/tests/Frontend/support/e2e.js +++ b/tests/Frontend/support/e2e.js @@ -13,6 +13,7 @@ // https://on.cypress.io/configuration // *********************************************************** +import "./commands/commandOverrides.js"; import "./commands/generalCommands.js"; import "./commands/roomCommands.js"; import "./commands/interceptCommands.js";