From 2434f363f61615567bf17b978a59d626b8759e75 Mon Sep 17 00:00:00 2001 From: Adrien Boutigny Date: Tue, 9 Jan 2024 11:24:40 +0100 Subject: [PATCH] =?UTF-8?q?Ajoute=20des=20tests=20navigateur=20automatis?= =?UTF-8?q?=C3=A9=20(#593)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * install cypress and setup example tests * add placeholder account spec file * add tests to write * add test instructions in readme * test audit creation --------- Co-authored-by: Quentin Bellanger --- README.md | 19 +- .../audit/AuditGeneralInformationsForm.vue | 1 + cypress.config.ts | 10 + cypress/e2e/account.cy.ts | 11 + cypress/e2e/audit.cy.ts | 67 ++ cypress/e2e/report.cy.ts | 4 + cypress/examples/1-getting-started/todo.cy.js | 143 +++ .../2-advanced-examples/actions.cy.js | 299 ++++++ .../2-advanced-examples/aliasing.cy.js | 39 + .../2-advanced-examples/assertions.cy.js | 176 ++++ .../2-advanced-examples/connectors.cy.js | 98 ++ .../2-advanced-examples/cookies.cy.js | 118 +++ .../2-advanced-examples/cypress_api.cy.js | 185 ++++ .../examples/2-advanced-examples/files.cy.js | 85 ++ .../2-advanced-examples/location.cy.js | 32 + .../examples/2-advanced-examples/misc.cy.js | 104 ++ .../2-advanced-examples/navigation.cy.js | 56 ++ .../network_requests.cy.js | 163 ++++ .../2-advanced-examples/querying.cy.js | 114 +++ .../spies_stubs_clocks.cy.js | 201 ++++ .../2-advanced-examples/storage.cy.js | 110 +++ .../2-advanced-examples/traversal.cy.js | 121 +++ .../2-advanced-examples/utilities.cy.js | 108 +++ .../2-advanced-examples/viewport.cy.js | 58 ++ .../2-advanced-examples/waiting.cy.js | 30 + .../examples/2-advanced-examples/window.cy.js | 22 + cypress/fixtures/audit.json | 10 + cypress/fixtures/example.json | 5 + cypress/support/commands.ts | 37 + cypress/support/e2e.ts | 20 + cypress/tsconfig.json | 9 + package.json | 1 + yarn.lock | 918 ++++++++++++++---- 33 files changed, 3189 insertions(+), 185 deletions(-) create mode 100644 cypress.config.ts create mode 100644 cypress/e2e/account.cy.ts create mode 100644 cypress/e2e/audit.cy.ts create mode 100644 cypress/e2e/report.cy.ts create mode 100644 cypress/examples/1-getting-started/todo.cy.js create mode 100644 cypress/examples/2-advanced-examples/actions.cy.js create mode 100644 cypress/examples/2-advanced-examples/aliasing.cy.js create mode 100644 cypress/examples/2-advanced-examples/assertions.cy.js create mode 100644 cypress/examples/2-advanced-examples/connectors.cy.js create mode 100644 cypress/examples/2-advanced-examples/cookies.cy.js create mode 100644 cypress/examples/2-advanced-examples/cypress_api.cy.js create mode 100644 cypress/examples/2-advanced-examples/files.cy.js create mode 100644 cypress/examples/2-advanced-examples/location.cy.js create mode 100644 cypress/examples/2-advanced-examples/misc.cy.js create mode 100644 cypress/examples/2-advanced-examples/navigation.cy.js create mode 100644 cypress/examples/2-advanced-examples/network_requests.cy.js create mode 100644 cypress/examples/2-advanced-examples/querying.cy.js create mode 100644 cypress/examples/2-advanced-examples/spies_stubs_clocks.cy.js create mode 100644 cypress/examples/2-advanced-examples/storage.cy.js create mode 100644 cypress/examples/2-advanced-examples/traversal.cy.js create mode 100644 cypress/examples/2-advanced-examples/utilities.cy.js create mode 100644 cypress/examples/2-advanced-examples/viewport.cy.js create mode 100644 cypress/examples/2-advanced-examples/waiting.cy.js create mode 100644 cypress/examples/2-advanced-examples/window.cy.js create mode 100644 cypress/fixtures/audit.json create mode 100644 cypress/fixtures/example.json create mode 100644 cypress/support/commands.ts create mode 100644 cypress/support/e2e.ts create mode 100644 cypress/tsconfig.json diff --git a/README.md b/README.md index 385dc4f0..22e85377 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Ara -Réaliser des audits d'accessibilité numérique sur la base du référentiel général d'amélioration de l'accessibilité (RGAA). +Réaliser des audits d'accessibilité numérique sur la base du référentiel général d'amélioration de l'accessibilité (RGAA). Générer et consulter les rapports de ces audits et les déclarations d'accessibilité. ## Développement @@ -8,3 +8,20 @@ Générer et consulter les rapports de ces audits et les déclarations d'accessi - La partie front est une application Vue.js 3 avec Typescript. [Voir les instructions de développement](https://github.com/DISIC/Ara/blob/main/confiture-web-app/README.md). - La partie back est une API Nest.js et utilise une base de données PostgreSQL. [Voir les instructions de développement](https://github.com/DISIC/Ara/blob/main/confiture-rest-api/README.md). +## Tests + +[Cypress](https://www.cypress.io/) est utilisé pour lancer des tests end-to-end (e2e) dans un navigateur pour reproduire le comportement des utilisateurs. + +Les tests peuvent être lancés de 2 manières : + +- Via l’application Cypress avec : + + ```sh + yarn cypress open + ``` + +- Via le terminal avec : + + ```sh + yarn cypress run + ``` diff --git a/confiture-web-app/src/components/audit/AuditGeneralInformationsForm.vue b/confiture-web-app/src/components/audit/AuditGeneralInformationsForm.vue index 0f2a59d1..ee4c57bb 100644 --- a/confiture-web-app/src/components/audit/AuditGeneralInformationsForm.vue +++ b/confiture-web-app/src/components/audit/AuditGeneralInformationsForm.vue @@ -194,6 +194,7 @@ const previousRoute = usePreviousRoute(); class="fr-btn fr-btn--tertiary-no-outline page-delete-button" type="button" :disabled="pages.length === 1" + data-cy="delete" @click="deletePage(i)" > Supprimer diff --git a/cypress.config.ts b/cypress.config.ts new file mode 100644 index 00000000..af3f258c --- /dev/null +++ b/cypress.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from "cypress"; + +export default defineConfig({ + e2e: { + setupNodeEvents(on, config) { + // implement node event listeners here + }, + }, + experimentalStudio: true, +}); diff --git a/cypress/e2e/account.cy.ts b/cypress/e2e/account.cy.ts new file mode 100644 index 00000000..2065a4ca --- /dev/null +++ b/cypress/e2e/account.cy.ts @@ -0,0 +1,11 @@ +describe("Account", () => { + // it.skip("User can create a new account", () => {}); + // it.skip("User can sign in with their account", () => {}); + // it.skip("User can update their user profile", () => {}); + // it.skip("User can update their password", () => {}); + // it.skip("User can reset their password", () => {}); + // it.skip("User can update their email address", () => {}); + // it.skip("User can delete their account from Ara", () => {}); + // it.skip("User can access all their audits", () => {}); + // it.skip("User profile info are prefilled on new audits", () => {}); +}); diff --git a/cypress/e2e/audit.cy.ts b/cypress/e2e/audit.cy.ts new file mode 100644 index 00000000..12f2f722 --- /dev/null +++ b/cypress/e2e/audit.cy.ts @@ -0,0 +1,67 @@ +import * as auditJson from "../fixtures/audit.json"; + +describe("Audit", () => { + it("User can create an audit", () => { + function fillPageField(pageIndex: number, field: string, content: string) { + cy.contains("Page " + pageIndex) + .parent() + .parent() + .contains(field) + .parent() + .find("input") + .type(content); + } + + cy.visit("http://localhost:3000"); + + // Navigate to new audit page + cy.contains("Je démarre un audit").click(); + + // Fill fields + cy.contains("Complet, de conformité").click(); + + cy.contains("Nom du site à auditer") + .parent() + .find("input") + .type(auditJson.procedureName); + + fillPageField(1, "Nom de la page", auditJson.pages[0].name); + fillPageField(1, "URL de la page", auditJson.pages[0].url); + + fillPageField(2, "Nom de la page", auditJson.pages[1].name); + fillPageField(2, "URL de la page", auditJson.pages[1].url); + + // Delete empty pages "Supprimer" buttons + cy.get('[data-cy="delete"]').eq(2).click(); + cy.get('[data-cy="delete"]').eq(2).click(); + cy.get('[data-cy="delete"]').eq(2).click(); + cy.get('[data-cy="delete"]').eq(2).click(); + cy.get('[data-cy="delete"]').eq(2).click(); + + // Fill auditor informations + cy.contains("Prénom et nom (optionnel)") + .parent() + .find("input") + .type(auditJson.procedureAuditorName); + + cy.contains("Adresse e-mail") + .parent() + .find("input") + .type(auditJson.procedureAuditorEmail); + + // Submit new audit form + cy.contains("Valider les paramètres").click(); + + // Check user is redirect to audit overview page + cy.get("h1").contains(auditJson.procedureName); + }); + // it.skip("User can fill an audit (status, description, recommendation, image, impact, easy to fix)", () => {}); + // it.skip("User can check Markdown syntax", () => {}); + // it.skip("User can complete a11y statement", () => {}); + // it.skip("User can update notes", () => {}); + // it.skip("User can filter criteria", () => {}); + // it.skip("User can search criteria", () => {}); + // it.skip("User can copy an audit", () => {}); + // it.skip("User can delete an audit", () => {}); + // it.skip("User can downlaod an audit", () => {}); +}); diff --git a/cypress/e2e/report.cy.ts b/cypress/e2e/report.cy.ts new file mode 100644 index 00000000..a009eb95 --- /dev/null +++ b/cypress/e2e/report.cy.ts @@ -0,0 +1,4 @@ +describe("Report", () => { + // it.skip("User can filter errors", () => {}); + // it.skip("User can download results", () => {}); +}); diff --git a/cypress/examples/1-getting-started/todo.cy.js b/cypress/examples/1-getting-started/todo.cy.js new file mode 100644 index 00000000..4768ff92 --- /dev/null +++ b/cypress/examples/1-getting-started/todo.cy.js @@ -0,0 +1,143 @@ +/// + +// Welcome to Cypress! +// +// This spec file contains a variety of sample tests +// for a todo list app that are designed to demonstrate +// the power of writing tests in Cypress. +// +// To learn more about how Cypress works and +// what makes it such an awesome testing tool, +// please read our getting started guide: +// https://on.cypress.io/introduction-to-cypress + +describe('example to-do app', () => { + beforeEach(() => { + // Cypress starts out with a blank slate for each test + // so we must tell it to visit our website with the `cy.visit()` command. + // Since we want to visit the same URL at the start of all our tests, + // we include it in our beforeEach function so that it runs before each test + cy.visit('https://example.cypress.io/todo') + }) + + it('displays two todo items by default', () => { + // We use the `cy.get()` command to get all elements that match the selector. + // Then, we use `should` to assert that there are two matched items, + // which are the two default items. + cy.get('.todo-list li').should('have.length', 2) + + // We can go even further and check that the default todos each contain + // the correct text. We use the `first` and `last` functions + // to get just the first and last matched elements individually, + // and then perform an assertion with `should`. + cy.get('.todo-list li').first().should('have.text', 'Pay electric bill') + cy.get('.todo-list li').last().should('have.text', 'Walk the dog') + }) + + it('can add new todo items', () => { + // We'll store our item text in a variable so we can reuse it + const newItem = 'Feed the cat' + + // Let's get the input element and use the `type` command to + // input our new list item. After typing the content of our item, + // we need to type the enter key as well in order to submit the input. + // This input has a data-test attribute so we'll use that to select the + // element in accordance with best practices: + // https://on.cypress.io/selecting-elements + cy.get('[data-test=new-todo]').type(`${newItem}{enter}`) + + // Now that we've typed our new item, let's check that it actually was added to the list. + // Since it's the newest item, it should exist as the last element in the list. + // In addition, with the two default items, we should have a total of 3 elements in the list. + // Since assertions yield the element that was asserted on, + // we can chain both of these assertions together into a single statement. + cy.get('.todo-list li') + .should('have.length', 3) + .last() + .should('have.text', newItem) + }) + + it('can check off an item as completed', () => { + // In addition to using the `get` command to get an element by selector, + // we can also use the `contains` command to get an element by its contents. + // However, this will yield the