From 8f875c79ae17bad42450f5ad63c7b64a969c0306 Mon Sep 17 00:00:00 2001 From: gertie-sheshe Date: Mon, 14 Dec 2020 00:15:34 +0300 Subject: [PATCH 1/5] test modules --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index 615f85abe..444e5d60c 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,8 @@ "babel-eslint": "^10.1.0", "babel-plugin-module-resolver": "^4.0.0", "babel-plugin-transform-imports": "^2.0.0", + "cypress": "^6.1.0", + "cypress-graphql-mock": "^0.5.0-alpha.4", "eslint": "^7.14.0", "eslint-config-airbnb": "^18.2.0", "eslint-config-prettier": "^6.15.0", @@ -65,6 +67,7 @@ "build": "next build", "dev": "yarn dev:next", "dev:next": "next dev", + "test-dev": "cypress open", "export": "yarn run build && next export", "format": "yarn prettier --write --ignore-path './.gitignore' \"**/*.+(json|md|yml)\" './'", "format-staged": "prettier --write", From 47ce0c2f94206c4196684c187a03c099ecc73e76 Mon Sep 17 00:00:00 2001 From: gertie-sheshe Date: Mon, 14 Dec 2020 00:32:37 +0300 Subject: [PATCH 2/5] cypress tests + config --- .eslintrc.json | 3 +- cypress.json | 1 + cypress/fixtures/example.json | 5 + cypress/integration/actNowPage.spec.js | 26 +++++ cypress/integration/homePage.spec.js | 48 ++++++++ cypress/integration/promisesPage.spec.js | 110 ++++++++++++++++++ cypress/integration/singlePromisePage.spec.js | 22 ++++ cypress/plugins/index.js | 21 ++++ cypress/support/commands.js | 25 ++++ cypress/support/index.js | 20 ++++ package.json | 1 + 11 files changed, 281 insertions(+), 1 deletion(-) create mode 100644 cypress.json create mode 100644 cypress/fixtures/example.json create mode 100644 cypress/integration/actNowPage.spec.js create mode 100644 cypress/integration/homePage.spec.js create mode 100644 cypress/integration/promisesPage.spec.js create mode 100644 cypress/integration/singlePromisePage.spec.js create mode 100644 cypress/plugins/index.js create mode 100644 cypress/support/commands.js create mode 100644 cypress/support/index.js diff --git a/.eslintrc.json b/.eslintrc.json index 08c378e0f..306641ee9 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -7,7 +7,8 @@ "plugin:import/errors", "airbnb", "plugin:prettier/recommended", - "prettier/react" + "prettier/react", + "plugin:cypress/recommended" ], "env": { "browser": true diff --git a/cypress.json b/cypress.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/cypress.json @@ -0,0 +1 @@ +{} diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json new file mode 100644 index 000000000..02e425437 --- /dev/null +++ b/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/cypress/integration/actNowPage.spec.js b/cypress/integration/actNowPage.spec.js new file mode 100644 index 000000000..c124d65f8 --- /dev/null +++ b/cypress/integration/actNowPage.spec.js @@ -0,0 +1,26 @@ +describe("Act Now page", () => { + beforeEach(() => { + cy.viewport("macbook-16"); + }); + it("renders Act Now page", () => { + cy.visit("http://localhost:3000"); + cy.get("[data-cy=navigation-buttons]").contains("Act Now").click(); + cy.location("pathname", { timeout: 10000 }).should("include", "/act-now"); + cy.get("[data-cy=actnow-desc]").contains( + "Act now and create the change you want in your area." + ); + }); + it("select promise to petition", () => { + cy.get("[data-cy=promise-select]").click(); + cy.get("[data-cy=promise-item").first().click(); + }); + it("displays petiton form", () => { + cy.get("[data-cy=start-petition]").click(); + cy.get("[data-cy=petition-form]").contains("Petition Title"); + cy.get("[data-cy=petition-form]").contains("Category & Promise"); + cy.get("[data-cy=petition-form]").contains("Recipient"); + cy.get("[data-cy=petition-form]").contains("What is the Issue"); + cy.get("[data-cy=petition-form]").contains("Featured Image"); + cy.get("[data-cy=close-form]").click(); + }); +}); diff --git a/cypress/integration/homePage.spec.js b/cypress/integration/homePage.spec.js new file mode 100644 index 000000000..39ac2e94d --- /dev/null +++ b/cypress/integration/homePage.spec.js @@ -0,0 +1,48 @@ +describe("Promise Home page", () => { + it("renders Key Promises", () => { + cy.visit("http://localhost:3000"); + cy.get("[data-cy=key-promises]").contains("Key Promises"); + }); + + it("renders Latest Promises", () => { + cy.get("[data-cy=latest-promises]").contains("Latest Promises"); + cy.get("[data-cy=latest-promises]") + .find("img") + .its("length") + .then((length) => { + expect(length).to.equal(5); + }); + }); + + it("renders Latest Articles", () => { + cy.get("[data-cy=latest-articles]").contains("Latest Articles"); + cy.get("[data-cy=latest-articles]") + .find("img") + .its("length") + .then((length) => { + expect(length).to.equal(2); + }); + }); + + it("renders Partners", () => { + cy.get("[data-cy=partners]").contains("Partners"); + cy.get("[data-cy=partners]") + .find("a") + .its("length") + .then((length) => { + expect(length).to.equal(6); + }); + }); + + it("has Neswletter section", () => { + cy.get("[data-cy=subscribe]").contains("Subscribe"); + }); + + it("has Act Now section", () => { + cy.get("[data-cy=act-now]").contains("Act Now"); + }); + + it("renders Partners", () => { + cy.get("[data-cy=latest-promises]").contains("Latest Promises"); + }); +}); diff --git a/cypress/integration/promisesPage.spec.js b/cypress/integration/promisesPage.spec.js new file mode 100644 index 000000000..bebe32866 --- /dev/null +++ b/cypress/integration/promisesPage.spec.js @@ -0,0 +1,110 @@ +// Cypress.env(); + +describe("Promises page", () => { + beforeEach(() => { + cy.viewport("macbook-16"); + }); + it("renders Promises page", () => { + cy.visit("http://localhost:3000"); + cy.get("[data-cy=navigation-buttons]").contains("Promises").click(); + cy.location("pathname", { timeout: 10000 }).should("include", "/promises"); + cy.get("[data-cy=promises-section]").contains("Promises"); + }); + it("renders Promises categories", () => { + cy.get("[data-cy=promises-section]").contains("Promises by status"); + cy.get("[data-cy=promises-section]").contains("Promises by category"); + }); + it("filter in progress promises", () => { + cy.get("[data-cy=promises-section]") + .find("img") + .its("length") + .then((length) => { + expect(length).to.equal(5); + }); + cy.get("[data-cy=filter-buttons]").contains("In Progress").click(); + cy.get("[data-cy=promises-section]") + .find("img") + .its("length") + .then((length) => { + expect(length).to.equal(3); + }); + cy.get("[data-cy=filter-buttons]").contains("In Progress").click(); + }); + + it("filter unrated promises", () => { + cy.get("[data-cy=promises-section]") + .find("img") + .its("length") + .then((length) => { + expect(length).to.equal(5); + }); + cy.get("[data-cy=filter-buttons]").contains("Unrated").click(); + cy.get("[data-cy=promises-section]") + .find("img") + .its("length") + .then((length) => { + expect(length).to.equal(1); + }); + cy.get("[data-cy=filter-buttons]").contains("Unrated").click(); + }); + + it("filter stalled promises", () => { + cy.get("[data-cy=promises-section]") + .find("img") + .its("length") + .then((length) => { + expect(length).to.equal(5); + }); + cy.get("[data-cy=filter-buttons]").contains("Stalled").click(); + cy.get("[data-cy=promises-section]") + .find("img") + .its("length") + .then((length) => { + expect(length).to.equal(1); + }); + cy.get("[data-cy=filter-buttons]").contains("Stalled").click(); + }); + + it("filter governance category promises", () => { + cy.get("[data-cy=promises-section]") + .find("img") + .its("length") + .then((length) => { + expect(length).to.equal(5); + }); + + cy.get("[data-cy=filter-buttons]").contains("Governance").click(); + cy.get("[data-cy=promises-section]") + .find("img") + .its("length") + .then((length) => { + expect(length).to.equal(1); + }); + cy.get("[data-cy=filter-buttons]").contains("Governance").click(); + }); + + it("filter governance category promises", () => { + cy.get("[data-cy=promises-section]") + .find("img") + .its("length") + .then((length) => { + expect(length).to.equal(5); + }); + cy.get("[data-cy=filter-buttons]").contains("Health").click(); + cy.get("[data-cy=promises-section]") + .find("img") + .its("length") + .then((length) => { + expect(length).to.equal(2); + }); + cy.get("[data-cy=filter-buttons]").contains("Health").click(); + }); + + it("share promise to social platforms", () => { + cy.get("[data-cy=share-button").first().click(); + cy.get("[data-cy=twitter]").should("be.visible"); + cy.get("[data-cy=facebook]").should("be.visible"); + cy.get("[data-cy=linkedin]").should("be.visible"); + cy.get("[data-cy=share-button").first().click(); + }); +}); diff --git a/cypress/integration/singlePromisePage.spec.js b/cypress/integration/singlePromisePage.spec.js new file mode 100644 index 000000000..0c3cdb8a9 --- /dev/null +++ b/cypress/integration/singlePromisePage.spec.js @@ -0,0 +1,22 @@ +// Cypress.env(); + +describe("Promises page", () => { + beforeEach(() => { + cy.viewport("macbook-16"); + }); + it("renders promise radar", () => { + cy.visit("http://localhost:3000/promises"); + cy.get("[data-cy=promises-section]").contains("Promises"); + /* eslint-disable cypress/no-unnecessary-waiting */ + cy.get("[data-cy=promises-section").find("a").first().click().wait(20000); + cy.get("[data-cy=promise-radar]").should("be.visible"); + }); + it("renders promise chart, dataset and datasource", () => { + cy.get("[data-cy=datasource]").scrollIntoView(); + cy.get("[data-cy=datasource").should("be.visible"); + cy.get("[data-cy=dataset]").scrollIntoView(); + cy.get("[data-cy=dataset]").should("be.visible"); + cy.get("[data-cy=promise-chart]").scrollIntoView(); + cy.get("[data-cy=promise-chart]").should("be.visible"); + }); +}); diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js new file mode 100644 index 000000000..8affdd414 --- /dev/null +++ b/cypress/plugins/index.js @@ -0,0 +1,21 @@ +/// +// *********************************************************** +// This example plugins/index.js can be used to load plugins +// +// You can change the location of this file or turn off loading +// the plugins file with the 'pluginsFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/plugins-guide +// *********************************************************** + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) + +/** + * @type {Cypress.PluginConfig} + */ +module.exports = () => { + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config +}; diff --git a/cypress/support/commands.js b/cypress/support/commands.js new file mode 100644 index 000000000..ca4d256f3 --- /dev/null +++ b/cypress/support/commands.js @@ -0,0 +1,25 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add("login", (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/cypress/support/index.js b/cypress/support/index.js new file mode 100644 index 000000000..d076cec9f --- /dev/null +++ b/cypress/support/index.js @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import "./commands"; + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/package.json b/package.json index 444e5d60c..31d539251 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "eslint-config-airbnb": "^18.2.0", "eslint-config-prettier": "^6.15.0", "eslint-import-resolver-babel-module": "^5.1.2", + "eslint-plugin-cypress": "^2.11.2", "eslint-plugin-import": "^2.22.0", "eslint-plugin-json": "^2.1.2", "eslint-plugin-jsx-a11y": "^6.4.1", From 11dcb3445860f0a28f82ff5783b8484d67d4dde0 Mon Sep 17 00:00:00 2001 From: gertie-sheshe Date: Mon, 14 Dec 2020 00:33:19 +0300 Subject: [PATCH 3/5] add data attributes --- src/components/ActNow/index.js | 6 +++++- src/components/DataSource/index.js | 2 +- src/components/Dataset/index.js | 7 ++++++- src/components/FormDialog/Form.js | 2 +- src/components/FormDialog/index.js | 1 + src/components/KeyPromises/index.js | 1 + src/components/LatestArticles/index.js | 1 + src/components/LatestPromises/index.js | 1 + src/components/Navigation/DesktopNavigation/index.js | 5 ++++- src/components/Newsletter/index.js | 11 +++++++++-- src/components/Partners/index.js | 1 + src/components/PickPromise/index.js | 8 +++++++- src/components/PostCardGrid/index.js | 1 + src/components/Promise/Radar.js | 2 +- src/components/PromiseCard/index.js | 1 + src/components/PromiseChart/index.js | 2 +- src/components/Promises/Filter/index.js | 2 +- src/components/Share/index.js | 4 ++++ src/pages/act-now.js | 5 ++++- 19 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/components/ActNow/index.js b/src/components/ActNow/index.js index 8a3614b30..9823d3798 100644 --- a/src/components/ActNow/index.js +++ b/src/components/ActNow/index.js @@ -85,7 +85,11 @@ function ActNow({ actionLabel, description, title, ...props }) {
- + {title} +
{label} diff --git a/src/components/Dataset/index.js b/src/components/Dataset/index.js index 21a74fa74..a0cbe32e7 100644 --- a/src/components/Dataset/index.js +++ b/src/components/Dataset/index.js @@ -98,7 +98,12 @@ function Dataset({ dataset, ...props }) { const hasHxlTags = tags && tags.find((tag) => tag.name.toLowerCase() === "hxl"); return ( - + +
{petitionTitle}
diff --git a/src/components/LatestPromises/index.js b/src/components/LatestPromises/index.js index 6e4eb7138..812332b3e 100644 --- a/src/components/LatestPromises/index.js +++ b/src/components/LatestPromises/index.js @@ -25,6 +25,7 @@ function LatestPromises({ actionLabel, items, title, ...props }) { } return (
diff --git a/src/components/Navigation/DesktopNavigation/index.js b/src/components/Navigation/DesktopNavigation/index.js index b5cefe9db..4d2f30236 100644 --- a/src/components/Navigation/DesktopNavigation/index.js +++ b/src/components/Navigation/DesktopNavigation/index.js @@ -72,7 +72,10 @@ function DesktopNavigation(props) { return ( -
+
diff --git a/src/components/Newsletter/index.js b/src/components/Newsletter/index.js index 234c66ca7..b1a7c99a3 100644 --- a/src/components/Newsletter/index.js +++ b/src/components/Newsletter/index.js @@ -124,7 +124,11 @@ function Newsletter({
- + {title} {description && ( @@ -132,7 +136,10 @@ function Newsletter({ {description} )} - + {config.settings.subscribe.embedCode}
diff --git a/src/components/Partners/index.js b/src/components/Partners/index.js index ca3421558..61f297298 100644 --- a/src/components/Partners/index.js +++ b/src/components/Partners/index.js @@ -81,6 +81,7 @@ function Partners({ items, title, ...props }) { return (