diff --git a/.github/workflows/test-build-docker-image.yml b/.github/workflows/test-build-docker-image.yml index a09d77618e..f9c5ac84d9 100644 --- a/.github/workflows/test-build-docker-image.yml +++ b/.github/workflows/test-build-docker-image.yml @@ -482,6 +482,12 @@ jobs: name: cypress-screenshots-${{ matrix.job }} path: app/client/cypress/screenshots/ + # Upload the snapshots as artifacts for layout validation + - uses: actions/upload-artifact@v1 + with: + name: cypress-snapshots-visualRegression + path: app/client/cypress/snapshots/ + # Upload the log artifact so that it can be used by the test & deploy job in the workflow - name: Upload server logs bundle on failure uses: actions/upload-artifact@v2 diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js new file mode 100644 index 0000000000..e2853507c9 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js @@ -0,0 +1,77 @@ +const homePage = require("../../../../locators/HomePage.json"); + +describe("Visual regression tests", () => { + // for any changes in UI, update the screenshot in snapshot folder, to do so: + // 1. Delete the required screenshot which you want to update. + // 2. Run test in headless mode with any browser except chrome.(to maintain same resolution in CI) + // 3. New screenshot will be generated in the snapshot folder. + + it("Layout validation for app page in edit mode", () => { + cy.visit("/applications"); + cy.wait(3000); + cy.get(".t--applications-container .createnew").should("be.visible"); + cy.get(".t--applications-container .createnew") + .first() + .click(); + cy.wait(3000); + // taking screenshot of app home page in edit mode + cy.get("#root").matchImageSnapshot("apppage"); + }); + + it("Layout validation for Quick page wizard", () => { + cy.get(".t--GenerateCRUDPage").click(); + cy.wait(2000); + // taking screenshot of generate crud page + cy.get("#root").matchImageSnapshot("quickPageWizard"); + }); + + it("Layout Validation for App builder Page", () => { + cy.get(".bp3-icon-chevron-left").click(); + cy.get(".t--BuildFromScratch").click(); + cy.wait(2000); + // taking screenshot of app builder page + cy.get("#root").matchImageSnapshot("emptyAppBuilder"); + }); + + it("Layout Validation for Empty deployed app", () => { + cy.PublishtheApp(); + cy.wait(3000); + // taking screenshot of empty deployed app + cy.get("#root").matchImageSnapshot("EmptyApp"); + }); + + it("Layout Validation for profile page", () => { + cy.get(".t--profile-menu-icon").click(); + cy.get(".t--edit-profile").click(); + cy.wait(2000); + // taking screenshot of profile page + cy.get("#root").matchImageSnapshot("Profile"); + }); + + it("Layout validation for login page", () => { + cy.get(homePage.profileMenu).click(); + cy.get(homePage.signOutIcon).click(); + cy.wait(500); + // validating all the fields on login page + cy.get(homePage.headerAppSmithLogo).should("be.visible"); + cy.xpath("//h1").should("have.text", "Sign in to your account"); + cy.get(".bp3-label") + .first() + .should("have.text", "Email "); + cy.get(".bp3-label") + .last() + .should("have.text", "Password "); + cy.xpath('//span[text()="sign in"]').should("be.visible"); + cy.get(".bp3-label") + .first() + .click(); + /* cy.xpath("//a") + .eq(3) + .should("have.text", "Privacy Policy"); + cy.xpath("//a") + .eq(4) + .should("have.text", "Terms and conditions"); */ + // taking screenshot of login page + cy.matchImageSnapshot("loginpage"); + }); +}); diff --git a/app/client/cypress/plugins/index.js b/app/client/cypress/plugins/index.js index c65001ea24..4353f59b02 100644 --- a/app/client/cypress/plugins/index.js +++ b/app/client/cypress/plugins/index.js @@ -6,6 +6,9 @@ const dotenv = require("dotenv"); const chalk = require("chalk"); const cypressLogToOutput = require("cypress-log-to-output"); const { isFileExist } = require("cy-verify-downloads"); +const { + addMatchImageSnapshotPlugin, +} = require("cypress-image-snapshot/plugin"); // *********************************************************** // This example plugins/index.js can be used to load plugins @@ -127,3 +130,6 @@ module.exports = (on, config) => { return config; }; +module.exports = (on, config) => { + addMatchImageSnapshotPlugin(on, config); +}; diff --git a/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/EmptyApp.snap.png b/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/EmptyApp.snap.png new file mode 100644 index 0000000000..77b3a60cd3 Binary files /dev/null and b/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/EmptyApp.snap.png differ diff --git a/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/apppage.snap.png b/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/apppage.snap.png new file mode 100644 index 0000000000..9b8cecd39b Binary files /dev/null and b/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/apppage.snap.png differ diff --git a/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/emptyAppBuilder.snap.png b/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/emptyAppBuilder.snap.png new file mode 100644 index 0000000000..89fa50c1c4 Binary files /dev/null and b/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/emptyAppBuilder.snap.png differ diff --git a/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/loginpage.snap.png b/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/loginpage.snap.png new file mode 100644 index 0000000000..64efdc16b6 Binary files /dev/null and b/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/loginpage.snap.png differ diff --git a/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/quickPageWizard.snap.png b/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/quickPageWizard.snap.png new file mode 100644 index 0000000000..efe71acec9 Binary files /dev/null and b/app/client/cypress/snapshots/Smoke_TestSuite/ClientSideTests/LayoutValidation/AppPageLayout.spec.js/quickPageWizard.snap.png differ diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index f91ce10ed6..efd38ce7cf 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -6,7 +6,9 @@ require("cy-verify-downloads").addCustomCommand(); require("cypress-file-upload"); const dayjs = require("dayjs"); - +const { + addMatchImageSnapshotCommand, +} = require("cypress-image-snapshot/command"); const loginPage = require("../locators/LoginPage.json"); const signupPage = require("../locators/SignupPage.json"); const homePage = require("../locators/HomePage.json"); @@ -3580,3 +3582,7 @@ Cypress.Commands.add("isInViewport", (element) => { // return originalFn(element, clearedText, options); // }); +addMatchImageSnapshotCommand({ + failureThreshold: 0.2, // threshold for entire image + failureThresholdType: "percent", +}); diff --git a/app/client/package.json b/app/client/package.json index a52663c66d..c0fb960009 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -246,12 +246,13 @@ "babel-plugin-styled-components": "^1.10.7", "cra-bundle-analyzer": "^0.1.0", "craco-babel-loader": "^0.1.4", + "cy-verify-downloads": "^0.0.5", "cypress": "7.6.0", "cypress-file-upload": "^4.1.1", + "cypress-image-snapshot": "^4.0.1", "cypress-multi-reporters": "^1.2.4", "cypress-real-events": "^1.5.1", "cypress-xpath": "^1.4.0", - "cy-verify-downloads": "^0.0.5", "dotenv": "^8.1.0", "eslint": "^7.11.0", "eslint-config-prettier": "^6.12.0",