From 09fae79c593ad7b3ff7a65711697da0e704d95de Mon Sep 17 00:00:00 2001 From: edchai Date: Mon, 6 Feb 2023 11:52:12 +0200 Subject: [PATCH] feat: Added e2e tests for vite-react-simple sample --- cypress/README.md | 1 + cypress/common/base.ts | 35 ++++- cypress/common/selectors.ts | 5 +- cypress/fixtures/constants.ts | 30 +++- cypress/types/cssAttr.ts | 3 +- .../e2e/tests/hostComponentChecks.cy.ts | 2 +- .../e2e/CheckAppExposes.cy.ts | 2 +- .../e2e/tests/commonChecks.cy.ts | 2 +- .../e2e/tests/commonChecks.cy.ts | 66 +++++++++ vite-react-simple/e2e/tests/runAll.cy.ts | 2 + .../e2e/tests/viteAppChecks.cy.ts | 128 ++++++++++++++++++ vite-react-simple/package.json | 2 +- 12 files changed, 261 insertions(+), 17 deletions(-) create mode 100644 vite-react-simple/e2e/tests/commonChecks.cy.ts create mode 100644 vite-react-simple/e2e/tests/runAll.cy.ts create mode 100644 vite-react-simple/e2e/tests/viteAppChecks.cy.ts diff --git a/cypress/README.md b/cypress/README.md index ec9c5d46a01..711e1fa76e5 100644 --- a/cypress/README.md +++ b/cypress/README.md @@ -461,6 +461,7 @@ It will generate two `describes` and two `its` for each test, and our test run w ### Separate common checks and uncommon As a suggestion, if you have two or more applications with similar functionality, you can create a separate file for shared checks, named `commonChecks.ts`, and add your created object with common checks there. +NOTE: You can use `commonChecks.ts`, not only fot different apps but for similar checks in one app (for example similar checks of different buttons in one app) So, your `e2e` directory will look like the following: diff --git a/cypress/common/base.ts b/cypress/common/base.ts index b2515341f5d..0f18b228d81 100644 --- a/cypress/common/base.ts +++ b/cypress/common/base.ts @@ -59,7 +59,8 @@ export class BaseMethods { wait = 0, isShadowRoot = false, index = 0, - parentSelector + parentSelector, + isTargetChanged = false }: { selector: string, text: string, @@ -67,8 +68,18 @@ export class BaseMethods { wait?: number, isShadowRoot?: boolean, index?: number, - parentSelector?: string + parentSelector?: string, + isTargetChanged?: boolean }): void { + if(isTargetChanged) { + cy.get(selector).contains(text) + .should(($button: JQuery) => { + $button.attr('target', '_self'); + }).click() + + return; + } + if(parentSelector) { cy.get(parentSelector) .find(selector) @@ -124,7 +135,15 @@ export class BaseMethods { }) } - public checkUrlText(url: string, isInclude: boolean = false): void { + public checkUrlText(url: string, isInclude: boolean = false, isDifferentOrigin: boolean = false): void { + if(isDifferentOrigin) { + cy.origin(url, { args: { isInclude, url } }, ({ isInclude, url }) => { + cy.url().should(isInclude ? 'include' : 'not.include', url); + }); + + return; + } + cy.url().should(isInclude ? 'include' : 'not.include', url); } @@ -340,7 +359,8 @@ export class BaseMethods { isShadowElement = false, text, isParent = false, - checkType = 'contains' + checkType = 'contains', + isWithInvoke = true }: { selector: string, attr?: string, @@ -352,7 +372,8 @@ export class BaseMethods { isShadowElement?: boolean, text?: string, isParent?: boolean, - checkType?: string + checkType?: string, + isWithInvoke?: boolean } ): Cypress.Chainable> { if(text) { @@ -426,6 +447,10 @@ export class BaseMethods { }); } + if(!isWithInvoke) { + return cy.get(selector).should(prop, value) + } + return cy.get(selector) .invoke(attr, prop) .should('include', value) diff --git a/cypress/common/selectors.ts b/cypress/common/selectors.ts index 4c9688f88a4..c3915dcff99 100644 --- a/cypress/common/selectors.ts +++ b/cypress/common/selectors.ts @@ -189,7 +189,7 @@ export const updatedSelectors = { vue3DemoFederationWithViteApp: { buttons: { vite: selectors.vue3DemoFederationWithViteApp.vueAppButton.replace('{appType}', Constants.selectorParts.vue3DemoFederationWithViteApp.vite), - webpack: selectors.vue3DemoFederationWithViteApp.vueAppButton.replace('{appType}', Constants.selectorParts.vue3DemoFederationWithViteApp.webpack), + webpack: selectors.vue3DemoFederationWithViteApp.vueAppButton.replace('{appType}', Constants.commonConstantsData.webpack), common: `${baseSelectors.tags.coreElements.div}[class*= "content"]`, } }, @@ -210,5 +210,8 @@ export const updatedSelectors = { componentBorder: `${selectors.craReactRewiredApp.componentInfo}${baseSelectors.css.style .replace('{style}', Constants.color.nonRgbValues.borderRed)}` }, + viteReactSimpleApp: { + headerBlock: `${baseSelectors.tags.headers.header} ${baseSelectors.tags.coreElements.div}`, + } } diff --git a/cypress/fixtures/constants.ts b/cypress/fixtures/constants.ts index 94ba719ab6c..a83e632a439 100644 --- a/cypress/fixtures/constants.ts +++ b/cypress/fixtures/constants.ts @@ -11,7 +11,6 @@ export class Constants { public static readonly selectorParts = { vue3DemoFederationWithViteApp : { vite: 'vite', - webpack: 'webpack' }, sharedRoutingAppReplaceSelectorPart: 'RECENT_', formFieldNames: { @@ -35,7 +34,10 @@ export class Constants { app3: 'App 3' }, button: 'Button', + header: 'Header', widget: 'Widget', + webpack: 'webpack', + counter: 'Counter', home: 'Home', commonIndexes: { minusOne: -1, @@ -137,6 +139,7 @@ export class Constants { }, helloWorldMessage: 'Hello World', commonVueAppComponentState: 'Remote Component in Action..', + commonReactLink: 'https://reactjs.org' } public static readonly updatedConstantsData = { @@ -607,7 +610,6 @@ export class Constants { routeButton: 'Route', subheader1: 'Exposed from Child', subheader2: 'Listening in Parent', - counter: 'Counter', }, appButtonDiv: 'App Button', appButtonClickMeButton: 'Click me', @@ -691,8 +693,15 @@ export class Constants { 'Stop 🛑' ], }, - rollupFederationDemoApp: { - headerText: 'Header' + viteReactSimpleApp: { + buttons: { + webpack: 'Webpack Remote Button', + counter: 'count is: 0' + }, + links: [ + 'Learn React', + 'Vite Docs' + ] } } @@ -830,6 +839,12 @@ export class Constants { rollupHost: 'Rollup Host' }, buttonText: 'Webpack Remote Button' + }, + viteReactSimpleApp: { + messages: { + intro: 'Hello Vite + federation! +1+2+3+4', + edit: 'Edit App.tsx and save to test HMR updates.' + } } } @@ -869,7 +884,8 @@ export class Constants { white: 'rgb(255, 255, 255)', lightGrey: 'rgb(239, 239, 239)', darkGrey: 'rgb(40, 44, 52)', - darkSaturatedBlue: 'rgb(0, 0, 255)' + darkSaturatedBlue: 'rgb(0, 0, 255)', + mint: 'rgb(97, 218, 251)' } public static readonly hrefs = { @@ -947,7 +963,6 @@ export class Constants { learnAboutNext: 'https://nextjs.org/learn/foundations/about-nextjs', deprecatedMainExamples: 'https://github.com/vercel/next.js/tree/deprecated-main/examples', }, - nativeFederationReactAppUrl: 'https://reactjs.org', comprehensiveDemoApp: { gitHub: 'https://github.com/module-federation/mfe-webpack-demo', app3: 'http://localhost:3003/', @@ -968,5 +983,8 @@ export class Constants { federationLink: '/federation' }, thirdPartyScriptsPostRequestPath: 'https://www.google-analytics.com/j/collect?**', + viteReactSimpleApp: { + viteLink: 'https://vitejs.dev/guide/features.html' + } } } diff --git a/cypress/types/cssAttr.ts b/cypress/types/cssAttr.ts index 39cb760173f..3eac9cb1972 100644 --- a/cypress/types/cssAttr.ts +++ b/cypress/types/cssAttr.ts @@ -2,5 +2,6 @@ export const enum CssAttr { backgroundColor = 'background-color', background = 'background', color = 'color', - css = 'css' + css = 'css', + transform = 'transform', } diff --git a/native-federation-react/e2e/tests/hostComponentChecks.cy.ts b/native-federation-react/e2e/tests/hostComponentChecks.cy.ts index 0c474a8a130..db9a750b528 100644 --- a/native-federation-react/e2e/tests/hostComponentChecks.cy.ts +++ b/native-federation-react/e2e/tests/hostComponentChecks.cy.ts @@ -93,7 +93,7 @@ describe("It checks host apps' component", () => { selector: baseSelectors.tags.coreElements.link, attr: Constants.commonConstantsData.commonAttributes.attr, prop: Constants.commonConstantsData.commonAttributes.href, - value: Constants.hrefs.nativeFederationReactAppUrl, + value: Constants.commonConstantsData.commonReactLink, isMultiple: true }) }) diff --git a/quasar-cli-vue3-webpack-javascript/e2e/CheckAppExposes.cy.ts b/quasar-cli-vue3-webpack-javascript/e2e/CheckAppExposes.cy.ts index c3935b05bde..92fa0783508 100644 --- a/quasar-cli-vue3-webpack-javascript/e2e/CheckAppExposes.cy.ts +++ b/quasar-cli-vue3-webpack-javascript/e2e/CheckAppExposes.cy.ts @@ -84,7 +84,7 @@ appsData.forEach(( }) basePage.checkElementWithTextPresence({ selector: baseSelectors.tags.coreElements.div, - text: Constants.elementsText.quasarCliApp.appGeneral.counter, + text: Constants.commonConstantsData.counter, }) } if (property.host === 3001) { diff --git a/rollup-federation-demo/e2e/tests/commonChecks.cy.ts b/rollup-federation-demo/e2e/tests/commonChecks.cy.ts index 89bc23549a2..215637cedd1 100644 --- a/rollup-federation-demo/e2e/tests/commonChecks.cy.ts +++ b/rollup-federation-demo/e2e/tests/commonChecks.cy.ts @@ -23,7 +23,7 @@ describe('It checks rollup-federation-demo apps functionality', () => { basePage.openLocalhost(property.host) basePage.checkElementWithTextPresence({ selector: selectors.rollupFederationDemoApp.header, - text: Constants.elementsText.rollupFederationDemoApp.headerText, + text: Constants.commonConstantsData.header, visibilityState: 'be.visible' }) }); diff --git a/vite-react-simple/e2e/tests/commonChecks.cy.ts b/vite-react-simple/e2e/tests/commonChecks.cy.ts new file mode 100644 index 00000000000..be7e0a9c785 --- /dev/null +++ b/vite-react-simple/e2e/tests/commonChecks.cy.ts @@ -0,0 +1,66 @@ +import { BaseMethods } from "../../../cypress/common/base"; +import {baseSelectors} from "../../../cypress/common/selectors"; +import {Constants} from "../../../cypress/fixtures/constants"; +import {CssAttr} from "../../../cypress/types/cssAttr"; + +const basePage: BaseMethods = new BaseMethods() + +describe('It checks buttons & links on page', () => { + const appsData = [ + { + buttonName: Constants.commonConstantsData.webpack, + buttonText: Constants.elementsText.viteReactSimpleApp.buttons.webpack, + buttonColor: Constants.color.red, + link: Constants.commonConstantsData.commonReactLink, + linkName: Constants.elementsText.viteReactSimpleApp.links[0], + }, + { + buttonName: Constants.commonConstantsData.counter.toLowerCase(), + buttonText: Constants.elementsText.viteReactSimpleApp.buttons.counter, + buttonColor: Constants.color.lightGrey, + link: Constants.hrefs.viteReactSimpleApp.viteLink, + linkName: Constants.elementsText.viteReactSimpleApp.links[1], + } + ] + + appsData.forEach((property: { buttonName: string, buttonText: string, buttonColor: string, link: string, linkName: string }) => { + it(`Checks ${property.buttonName} texted button visibility`, () => { + basePage.openLocalhost(3000) + basePage.checkElementWithTextPresence({ + selector: baseSelectors.tags.coreElements.button, + text: property.buttonText, + visibilityState: 'be.visible' + }) + }); + + it(`Checks ${property.buttonName} texted button color`, () => { + basePage.openLocalhost(3000) + basePage.checkElementHaveProperty({ + selector: baseSelectors.tags.coreElements.button, + prop: CssAttr.backgroundColor, + value: property.buttonColor, + text: property.buttonText, + }) + }) + + + it(`Checks ${property.buttonName} texted button is not disabled`, () => { + basePage.openLocalhost(3000) + basePage.checkElementState({ + selector: baseSelectors.tags.coreElements.button, + text: property.buttonText, + state: 'not.be.disabled' + }) + }) + + it(`Checks ${property.linkName} link functionality`, () => { + basePage.openLocalhost(3000) + basePage.clickElementWithText({ + selector: baseSelectors.tags.coreElements.link, + text: property.linkName, + isTargetChanged: true + }) + basePage.checkUrlText(property.link, true, true) + }) + }) +}) \ No newline at end of file diff --git a/vite-react-simple/e2e/tests/runAll.cy.ts b/vite-react-simple/e2e/tests/runAll.cy.ts new file mode 100644 index 00000000000..a8c3272733a --- /dev/null +++ b/vite-react-simple/e2e/tests/runAll.cy.ts @@ -0,0 +1,2 @@ +import './viteAppChecks.cy' +import './commonChecks.cy' diff --git a/vite-react-simple/e2e/tests/viteAppChecks.cy.ts b/vite-react-simple/e2e/tests/viteAppChecks.cy.ts new file mode 100644 index 00000000000..869c4167b62 --- /dev/null +++ b/vite-react-simple/e2e/tests/viteAppChecks.cy.ts @@ -0,0 +1,128 @@ +import {BaseMethods} from "../../../cypress/common/base"; +import {Constants} from "../../../cypress/fixtures/constants"; +import {CssAttr} from "../../../cypress/types/cssAttr"; +import {baseSelectors, updatedSelectors} from "../../../cypress/common/selectors"; + +const basePage: BaseMethods = new BaseMethods() + +describe("It checks elements visibility/functionality", () => { + beforeEach(() => { + basePage.openLocalhost(3000) + }) + + it('Checks react logo visibility', () => { + basePage.checkElementVisibility({ + selector: baseSelectors.tags.coreElements.image + }) + }) + + it('Checks intro message visibility', () => { + basePage.checkElementWithTextPresence({ + selector: baseSelectors.tags.paragraph, + text: Constants.commonPhrases.viteReactSimpleApp.messages.intro, + visibilityState: 'be.visible' + }) + }) + + it('Checks header block with text visibility', () => { + basePage.checkElementWithTextPresence({ + selector: updatedSelectors.viteReactSimpleApp.headerBlock, + text: Constants.commonConstantsData.header, + visibilityState: 'be.visible' + }) + }) + + it('Checks edit message visibility', () => { + basePage.checkElementWithTextPresence({ + selector: baseSelectors.tags.paragraph, + text: Constants.commonPhrases.viteReactSimpleApp.messages.edit, + visibilityState: 'be.visible' + }) + }) + + it('Checks texted links visibility & checks links is not disabled', () => { + Constants.elementsText.viteReactSimpleApp.links.forEach((link: string) => { + basePage.checkElementWithTextPresence({ + selector: baseSelectors.tags.coreElements.link, + text: link, + visibilityState: 'be.visible' + }) + basePage.checkElementState({ + selector: baseSelectors.tags.coreElements.link, + text: link, + state: 'not.be.disabled' + }) + }) + }) +}) + +describe("It checks elements colors/functionality", () => { + beforeEach(() => { + basePage.openLocalhost(3000) + }) + + it('Checks page background color', () => { + basePage.checkElementHaveProperty({ + selector: baseSelectors.tags.headers.header, + prop: CssAttr.backgroundColor, + value: Constants.color.darkGrey + }) + }) + + it('Checks react logo is rotating', () => { + basePage.checkElementHaveProperty({ + selector: baseSelectors.tags.coreElements.image, + prop: 'have.css', + value: CssAttr.transform, + isWithInvoke: false + }) + }) + + it('Checks header block color', () => { + basePage.checkElementHaveProperty({ + selector: updatedSelectors.viteReactSimpleApp.headerBlock, + prop: CssAttr.backgroundColor, + value: Constants.color.darkSaturatedBlue + }) + }) + + it('Checks counter in counter-texted button changed after click and reverts after reload', () => { + basePage.checkCounterFunctionality({ + button: baseSelectors.tags.coreElements.button, + counterText: Constants.elementsText.viteReactSimpleApp.buttons.counter, + isReloaded: true + }) + }) + + it('Checks counter in counter-texted button is not updated by click on webpack button', () => { + basePage.checkElementWithTextPresence({ + selector: baseSelectors.tags.coreElements.button, + text: Constants.elementsText.viteReactSimpleApp.buttons.counter + }) + basePage.clickElementWithText({ + selector: baseSelectors.tags.coreElements.button, + text: Constants.elementsText.viteReactSimpleApp.buttons.webpack + }) + basePage.checkElementWithTextPresence({ + selector: baseSelectors.tags.coreElements.button, + text: Constants.elementsText.viteReactSimpleApp.buttons.counter + .replace(Constants.commonConstantsData.commonIndexes.zero.toString(), Constants.commonConstantsData.commonIndexes.one.toString()), + isVisible: false + }) + basePage.checkElementWithTextPresence({ + selector: baseSelectors.tags.coreElements.button, + text: Constants.elementsText.viteReactSimpleApp.buttons.counter + }) + }) + + it('Checks color of links text', () => { + Constants.elementsText.viteReactSimpleApp.links.forEach((link: string) => { + basePage.checkElementHaveProperty({ + selector: baseSelectors.tags.coreElements.link, + text: link, + prop: CssAttr.color, + value: Constants.color.mint + }) + }) + }) +}) diff --git a/vite-react-simple/package.json b/vite-react-simple/package.json index 6183953530e..ed5b8447e48 100644 --- a/vite-react-simple/package.json +++ b/vite-react-simple/package.json @@ -8,7 +8,7 @@ ], "version": "0.0.0", "scripts": { - "start": "concurrently \"yarn --cwd vite-react start\" \"yarn --cwd webpack-spa start\" \"cd rs-sidecar; yarn start\"" + "start": "concurrently \"yarn --cwd vite-react start\" \"yarn --cwd webpack-spa start\" \"cd rs-sidecart; yarn start\"" }, "devDependencies": { "concurrently": "7.3.0"