From 273ee200e858d691014c7c37707b27f486ac2d04 Mon Sep 17 00:00:00 2001 From: CharlesSheelam Date: Tue, 16 Jul 2024 12:52:31 -0700 Subject: [PATCH] feat: add final smoke tests --- e2e/cypress/tests/beforeLoginTests.spec.ts | 34 ++- e2e/cypress/tests/codebase.spec.ts | 208 ++++++++---------- e2e/cypress/tests/event.spec.ts | 55 +++++ e2e/cypress/tests/job.spec.ts | 35 +++ e2e/cypress/tests/setup.spec.ts | 12 +- e2e/cypress/tests/user.spec.ts | 20 ++ frontend/cypress.config.ts | 7 + frontend/cypress/fixtures/example.json | 5 + frontend/cypress/support/commands.ts | 37 ++++ frontend/cypress/support/e2e.ts | 20 ++ frontend/src/components/CodebaseEditForm.vue | 9 +- frontend/src/components/EventEditForm.vue | 9 +- frontend/src/components/JobEditForm.vue | 9 +- frontend/src/components/ProfileEditForm.vue | 8 +- .../releaseEditor/CommonImagesModal.vue | 8 +- .../components/releaseEditor/FileUpload.vue | 2 +- .../releaseEditor/MetadataFormPage.vue | 4 +- 17 files changed, 325 insertions(+), 157 deletions(-) create mode 100644 e2e/cypress/tests/event.spec.ts create mode 100644 e2e/cypress/tests/job.spec.ts create mode 100644 e2e/cypress/tests/user.spec.ts create mode 100644 frontend/cypress.config.ts create mode 100644 frontend/cypress/fixtures/example.json create mode 100644 frontend/cypress/support/commands.ts create mode 100644 frontend/cypress/support/e2e.ts diff --git a/e2e/cypress/tests/beforeLoginTests.spec.ts b/e2e/cypress/tests/beforeLoginTests.spec.ts index 286a848ac..44ec659aa 100644 --- a/e2e/cypress/tests/beforeLoginTests.spec.ts +++ b/e2e/cypress/tests/beforeLoginTests.spec.ts @@ -1,23 +1,19 @@ - -/* //test ability to browse/download codebases describe("Browse Codebases", () => { - it("should browse the model library and be able to enter a search query", () =>{ - cy.visit('/'); // visit homepage - cy.visit('/codebases'); - assert(cy.get("h1").contains("Computational Model Library")); - - - }) -}) + it("should browse the model library and be able to enter a search query", () => { + cy.visit("/"); // visit homepage + cy.visit("/codebases"); + assert(cy.get("h1").contains("Computational Model Library")); + }); +}); //download codebase -describe("Download Codebases", () =>{ - it("should download a codebase", () => { - // Navigate to the first 'search-result', find the 'a' tag within the 'title' div, and click it - cy.get('.search-result', {timeout: 10000}).first().find('.title a').click(); - - - }) -}) -/* +describe("Download Codebases", () => { + it("should download a codebase", () => { + // Navigate to the first 'search-result', find the 'a' tag within the 'title' div, and click it + cy.get(".search-result", { timeout: 10000 }) + .first() + .find(".title a") + .click(); + }); +}); diff --git a/e2e/cypress/tests/codebase.spec.ts b/e2e/cypress/tests/codebase.spec.ts index 8a499b646..4cf706cac 100644 --- a/e2e/cypress/tests/codebase.spec.ts +++ b/e2e/cypress/tests/codebase.spec.ts @@ -1,157 +1,121 @@ import { loginBeforeEach } from "./setup.spec"; -import 'cypress-file-upload' +import "cypress-file-upload"; //login describe("Login", () => { it("should log into comses homepage with test user", () => { - loginBeforeEach('testuser', '123456'); - }) -}) - -describe("Visit events page", () =>{ //EVENTS PAGE + loginBeforeEach("test_user", "123456"); + }); +}); - it("should visit the events page", () =>{ - cy.visit("/events"); - assert(cy.get("h1").contains("Community Events")); - cy.get('.card-body').first().find('a').first().click(); - assert(cy.get("h1").contains("Title")); - - }) - - it("should be able to search for a specific event", () =>{ - cy.visit("/events"); - cy.get('input[class="form-control"]').type("Call for applications to organize a 2022 CECAM-Lorentz funded workshop on modeling"); - cy.get('button.btn.btn-primary').click(); - }) - it("should be able to submit an event", () =>{ - loginBeforeEach('test_user', '123456'); - cy.visit("/events"); - cy.get('#djHideToolBarButton').click(); - cy.get('.text-white').first().click({force:true}); - cy.get('[data-cy="event title"]').type("Title"); - cy.get('[data-cy="event location"]').type("Location"); - cy.get('[data-cy="event start date"]').first().click(); //event start date - cy.get('[data-cy="event start date"]').contains('22').click(); - cy.get('[data-cy="event end date"]').first().click(); //event end date - cy.get('[data-cy="event end date"]').contains('27').click(); - cy.get('[data-cy="early registration deadline"]').first().click(); //early registration deadline - cy.get('[data-cy="early registration deadline"]').contains('22').click(); - cy.get('[data-cy="registration deadline"]').first().click(); //registration deadline - cy.get('[data-cy="registration deadline"]').contains('25').click(); - cy.get('[data-cy="submission deadline"]').first().click(); //submission deadline - cy.get('[data-cy="submission deadline"]').contains('22').click(); - cy.get('[data-cy="description"]').type('Description'); - cy.get('[data-cy="summary"]').type('Summary'); - cy.get('[data-cy="external url"]').type('https://www.comses.net/'); - cy.get('[data-cy="create button"]').click(); - }) +describe("Visit codebases page", () => { + //codebases PAGE - it("should be able to verify event was submitted correctly", () =>{ - cy.visit("/events"); - cy.get('#djHideToolBarButton').click(); - assert(cy.get("h1").contains("Community Events")); - cy.get('.card-body').first().find('a').first().click(); - assert(cy.get("h1").contains("Title")); - assert(cy.get("p").contains("Description")); - assert(cy.get("p").contains("Location")); - }) -}) - -describe("Visit jobs page", () =>{ //JOBS PAGE - - it("should visit the jobs page", () =>{ - cy.visit("/jobs"); - assert(cy.get("h1").contains("Jobs & Appointments")); - }) - - it("should be able to submit a job posting", () =>{ - loginBeforeEach('test_user', '123456'); - cy.visit("/jobs"); - cy.get('#djHideToolBarButton').click(); - cy.get('.text-white').first().click({force:true}); - cy.get('[data-cy="job title"]').type("Job Title"); - cy.get('[data-cy="job description"]').type('Job Description'); - cy.get('[data-cy="job summary"]').type('Job Summary'); - cy.get('[data-cy="external url"]').type('https://www.comses.net/'); - cy.get('[data-cy="application deadline"]').first().click(); - cy.get('[data-cy="application deadline"]').contains('29').click(); - cy.get('[data-cy="create button"]').click(); - }) - - it("should be able to verify job was submitted correctly", () =>{ - cy.visit("/jobs"); - cy.get('#djHideToolBarButton').click(); - assert(cy.get("h1").contains("Jobs & Appointments")); - cy.get('.card-body').first().find('a').first().click(); - assert(cy.get("h1").contains("Job Title")); - assert(cy.get("p").contains("Job Description")); - }) - -}) - -describe("Visit codebases page", () =>{ //codebases PAGE - - it("should visit the codebases page", () =>{ + it("should visit the codebases page", () => { cy.visit("/codebases"); assert(cy.get("h1").contains("Computational Model Library")); - }) + }); it("should be able to download a codebase", () => { cy.visit("/codebases"); - cy.get('.search-result').first().find('a').first().click(); - cy.get('#djHideToolBarButton').click(); + cy.get(".search-result").first().find("a").first().click(); + cy.get("#djHideToolBarButton").click(); cy.get('button.btn.btn-primary.my-1.w-100[rel="nofollow"]').click(); - cy.get('#form-field-industry').select('College/University'); - cy.get('#form-field-affiliation').type("Arizona State University{enter}", {force: true}); - cy.get('#form-field-reason').select('Research'); - cy.get('button[type="submit"][form="download-request-form"].btn.btn-success').click(); - }) - - it("should be able to upload a codebase", () =>{ - loginBeforeEach('test_user', '123456'); + cy.get("#form-field-industry").select("College/University"); + cy.get("#form-field-affiliation").type("Arizona State University{enter}", { + force: true, + }); + cy.get("#form-field-reason").select("Research"); + cy.get( + 'button[type="submit"][form="download-request-form"].btn.btn-success' + ).click(); + }); + + it("should be able to upload a codebase", () => { + loginBeforeEach("test_user", "123456"); cy.visit("/codebases"); assert(cy.get("h1").contains("Computational Model Library")); - cy.get('#djHideToolBarButton').click(); - cy.contains('Publish a model').click(); + cy.get("#djHideToolBarButton").click(); + cy.contains("Publish a model").click(); cy.get('[data-cy="codebase title"]').type("Codebase Title"); cy.get('[data-cy="codebase description"]').type("Codebase Description"); - cy.get('[data-cy="codebase replication-text"]').type("Codebase Replication Text"); - cy.get('[data-cy="codebase associated publications"]').type("Codebase Associated Publications"); + cy.get('[data-cy="codebase replication-text"]').type( + "Codebase Replication Text" + ); + cy.get('[data-cy="codebase associated publications"]').type( + "Codebase Associated Publications" + ); cy.get('[data-cy="codebase references"]').type("Codebase References"); cy.get('[data-cy="next"]').click(); //add images cy.get('[data-cy="add image"]').click(); //add image - cy.get('[data-cy="upload-image"]').first().selectFile('cypress/fixtures/codebase/codebasetestimage.png', {force: true}); - cy.get('button.btn.btn-outline-gray[data-bs-dismiss="modal"]').get("button").first().click( {force: true} ); - cy.get('button.btn.btn-outline-gray[data-bs-dismiss="modal"]') - .should('be.visible') - .and('not.be.disabled') - .first(). - click( {force: true} ); - cy.get('body').click(0, 0); - cy.get('body').click(0, 0); //FIX: find a more precise way of closing the image upload modal + cy.get('[data-cy="upload-image"]') + .first() + .selectFile("cypress/fixtures/codebase/codebasetestimage.png", { + force: true, + }); + cy.get('button.btn.btn-outline-gray[data-bs-dismiss="modal"]') + .get("button") + .first() + .click({ force: true }); + cy.get('button.btn.btn-outline-gray[data-bs-dismiss="modal"]') + .should("be.visible") + .and("not.be.disabled") + .first() + .click({ force: true }); + cy.get("body").click(0, 0); + cy.get("body").click(0, 0); //FIX: find a more precise way of closing the image upload modal //add source code files - cy.get('[data-cy="upload-code"]').first().selectFile('cypress/fixtures/codebase/testSourceCode.txt', {force: true}); - cy.get('[data-cy="upload-docs"]').first().selectFile('cypress/fixtures/codebase/testNarrativeDocumentation.txt', {force: true}); - cy.get('[data-cy="upload-data"]').first().selectFile('cypress/fixtures/codebase/testUploadData.txt', {force: true}); - cy.get('[data-cy="upload-results"]').first().selectFile('cypress/fixtures/codebase/testSimulationOutput.txt', {force: true}); + cy.get('[data-cy="upload-code"]') + .first() + .selectFile("cypress/fixtures/codebase/testSourceCode.txt", { + force: true, + }); + cy.get('[data-cy="upload-docs"]') + .first() + .selectFile("cypress/fixtures/codebase/testNarrativeDocumentation.txt", { + force: true, + }); + cy.get('[data-cy="upload-data"]') + .first() + .selectFile("cypress/fixtures/codebase/testUploadData.txt", { + force: true, + }); + cy.get('[data-cy="upload-results"]') + .first() + .selectFile("cypress/fixtures/codebase/testSimulationOutput.txt", { + force: true, + }); cy.get('[data-cy="add metadata"]').click(); cy.get('[data-cy="release-notes"] textarea').type("Release notes"); cy.get('[data-cy="embargo-end-date"]').click(); - cy.get('[data-cy="embargo-end-date"]').contains('29').click(); - cy.get('[data-cy="operating-system"] select').select('Operating System Independent'); + cy.get('[data-cy="embargo-end-date"]').contains("29").click(); + cy.get('[data-cy="operating-system"] select').select( + "Operating System Independent" + ); cy.get('[data-cy="software-frameworks"]').type("NetLogo {enter} "); - cy.get('body').click(0, 0); + cy.get("body").click(0, 0); cy.get('[data-cy="programming-languages"').type("Net Logo {enter}"); - cy.get('body').click(0, 0); + cy.get("body").click(0, 0); cy.get('[data-cy="license"] .multiselect__select').click(); - cy.get('[data-cy="license"] .multiselect__element').contains('GPL-2.0').click(); + cy.get('[data-cy="license"] .multiselect__element') + .contains("GPL-2.0") + .click(); cy.get('[data-cy="save-and-continue"]').click(); cy.get('button.btn.btn-danger[rel="nofollow"]').click(); cy.get('button[type="submit"].btn.btn-danger[form="publish-form"]').click(); + }); - }) -}) + it("should verify that the codebase was uploaded correctly", () => { + cy.visit("/codebases"); + cy.get(".search-result").first().find("a").first().click(); + assert(cy.get("h1").contains("Codebase Title")); + assert(cy.get("p").contains("Codebase Description")); + assert(cy.get("p").contains("Codebase Replication Text")); + assert(cy.get("p").contains("Codebase Associated Publications")); + assert(cy.get("p").contains("Codebase References")); + }) +}); \ No newline at end of file diff --git a/e2e/cypress/tests/event.spec.ts b/e2e/cypress/tests/event.spec.ts new file mode 100644 index 000000000..a9798bd96 --- /dev/null +++ b/e2e/cypress/tests/event.spec.ts @@ -0,0 +1,55 @@ +import { loginBeforeEach } from "./setup.spec"; +import "cypress-file-upload"; + + +describe("Visit events page", () => { + //EVENTS PAGE + + it("should visit the events page", () => { + cy.visit("/events"); + assert(cy.get("h1").contains("Community Events")); + cy.get(".card-body").first().find("a").first().click(); + assert(cy.get("h1").contains("Title")); + }); + + it("should be able to search for a specific event", () => { + cy.visit("/events"); + cy.get('input[class="form-control"]').type( + "Call for applications to organize a 2022 CECAM-Lorentz funded workshop on modeling" + ); + cy.get("button.btn.btn-primary").click(); + }); + + it("should be able to submit an event", () => { + loginBeforeEach("test_user", "123456"); + cy.visit("/events"); + cy.get("#djHideToolBarButton").click(); + cy.get(".text-white").first().click({ force: true }); + cy.get('[data-cy="event title"]').type("Title"); + cy.get('[data-cy="event location"]').type("Location"); + cy.get('[data-cy="event start date"]').first().click(); //event start date + cy.get('[data-cy="event start date"]').contains("22").click(); + cy.get('[data-cy="event end date"]').first().click(); //event end date + cy.get('[data-cy="event end date"]').contains("27").click(); + cy.get('[data-cy="early registration deadline"]').first().click(); //early registration deadline + cy.get('[data-cy="early registration deadline"]').contains("22").click(); + cy.get('[data-cy="registration deadline"]').first().click(); //registration deadline + cy.get('[data-cy="registration deadline"]').contains("25").click(); + cy.get('[data-cy="submission deadline"]').first().click(); //submission deadline + cy.get('[data-cy="submission deadline"]').contains("22").click(); + cy.get('[data-cy="description"]').type("Description"); + cy.get('[data-cy="summary"]').type("Summary"); + cy.get('[data-cy="external url"]').type("https://www.comses.net/"); + cy.get('[data-cy="create button"]').click(); + }); + + it("should be able to verify event was submitted correctly", () => { + cy.visit("/events"); + cy.get("#djHideToolBarButton").click(); + assert(cy.get("h1").contains("Community Events")); + cy.get(".card-body").first().find("a").first().click(); + assert(cy.get("h1").contains("Title")); + assert(cy.get("p").contains("Description")); + assert(cy.get("p").contains("Location")); + }); + }); \ No newline at end of file diff --git a/e2e/cypress/tests/job.spec.ts b/e2e/cypress/tests/job.spec.ts new file mode 100644 index 000000000..6382a2851 --- /dev/null +++ b/e2e/cypress/tests/job.spec.ts @@ -0,0 +1,35 @@ +import { loginBeforeEach } from "./setup.spec"; +import "cypress-file-upload"; + +describe("Visit jobs page", () => { + //JOBS PAGE + + it("should visit the jobs page", () => { + cy.visit("/jobs"); + assert(cy.get("h1").contains("Jobs & Appointments")); + }); + + it("should be able to submit a job posting", () => { + loginBeforeEach("test_user", "123456"); + cy.visit("/jobs"); + cy.get("#djHideToolBarButton").click(); + cy.get(".text-white").first().click({ force: true }); + cy.get('[data-cy="job title"]').type("Job Title"); + cy.get('[data-cy="job description"]').type("Job Description"); + cy.get('[data-cy="job summary"]').type("Job Summary"); + cy.get('[data-cy="external url"]').type("https://www.comses.net/"); + cy.get('[data-cy="application deadline"]').first().click(); + cy.get('[data-cy="application deadline"]').contains("29").click(); + cy.get('[data-cy="create button"]').click(); + }); + + it("should be able to verify job was submitted correctly", () => { + cy.visit("/jobs"); + cy.get("#djHideToolBarButton").click(); + assert(cy.get("h1").contains("Jobs & Appointments")); + cy.get(".card-body").first().find("a").first().click(); + assert(cy.get("h1").contains("Job Title")); + assert(cy.get("p").contains("Job Description")); + }); + }); + \ No newline at end of file diff --git a/e2e/cypress/tests/setup.spec.ts b/e2e/cypress/tests/setup.spec.ts index 5de43e41a..4876a3eb3 100644 --- a/e2e/cypress/tests/setup.spec.ts +++ b/e2e/cypress/tests/setup.spec.ts @@ -1,8 +1,8 @@ //contains setup function for smoke tests export const loginBeforeEach = (username, password) => { - cy.visit('/accounts/login/?next=/') - assert(cy.get("h1").contains("Sign In")); //simply goes to sign in page - cy.get('input[name="login"]').type(username) - cy.get('input[name="password"]').type(password) - cy.contains('button', 'Sign In').click(); -} \ No newline at end of file + cy.visit("/accounts/login/?next=/"); + assert(cy.get("h1").contains("Sign In")); //simply goes to sign in page + cy.get('input[name="login"]').type(username); + cy.get('input[name="password"]').type(password); + cy.contains("button", "Sign In").click(); +}; diff --git a/e2e/cypress/tests/user.spec.ts b/e2e/cypress/tests/user.spec.ts new file mode 100644 index 000000000..6b3cdcf37 --- /dev/null +++ b/e2e/cypress/tests/user.spec.ts @@ -0,0 +1,20 @@ +import { loginBeforeEach } from "./setup.spec"; +import "cypress-file-upload"; + +//login +describe("User tests", () => { + it("should visit the users page", () => { + loginBeforeEach("admin_user", "123456"); + cy.visit("/users"); + cy.get("#djHideToolBarButton").click(); + cy.contains('div', 'My profile').click(); + cy.contains('a', 'Edit Profile').click(); + cy.get('#form-field-givenName').clear() + cy.get('[data-cy="first name"]').type("New first name"); + cy.get('#form-field-familyName').clear() + cy.get('[data-cy="last name"]').type("New last name"); + cy.get('[data-cy="submit"]').click(); + assert(cy.get("h4").contains("New first name New last name")); + + }); + }); \ No newline at end of file diff --git a/frontend/cypress.config.ts b/frontend/cypress.config.ts new file mode 100644 index 000000000..8959a4f25 --- /dev/null +++ b/frontend/cypress.config.ts @@ -0,0 +1,7 @@ +export default { + e2e: { + setupNodeEvents(on, config) { + // implement node event listeners here + }, + }, +}; diff --git a/frontend/cypress/fixtures/example.json b/frontend/cypress/fixtures/example.json new file mode 100644 index 000000000..02e425437 --- /dev/null +++ b/frontend/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/frontend/cypress/support/commands.ts b/frontend/cypress/support/commands.ts new file mode 100644 index 000000000..698b01a42 --- /dev/null +++ b/frontend/cypress/support/commands.ts @@ -0,0 +1,37 @@ +/// +// *********************************************** +// This example commands.ts 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) => { ... }) +// +// declare global { +// namespace Cypress { +// interface Chainable { +// login(email: string, password: string): Chainable +// drag(subject: string, options?: Partial): Chainable +// dismiss(subject: string, options?: Partial): Chainable +// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable +// } +// } +// } \ No newline at end of file diff --git a/frontend/cypress/support/e2e.ts b/frontend/cypress/support/e2e.ts new file mode 100644 index 000000000..f80f74f8e --- /dev/null +++ b/frontend/cypress/support/e2e.ts @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/e2e.ts 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') \ No newline at end of file diff --git a/frontend/src/components/CodebaseEditForm.vue b/frontend/src/components/CodebaseEditForm.vue index 02dac3d1a..b617a8918 100644 --- a/frontend/src/components/CodebaseEditForm.vue +++ b/frontend/src/components/CodebaseEditForm.vue @@ -23,7 +23,6 @@ label="Replication of an existing model?" help="Is this model a replication of a previously published computational model? Please enter a DOI or other permanent identifier to the model, or citation text. Separate multiple entries with newlines." data-cy="codebase replication-text" - :rows="3" /> - diff --git a/frontend/src/components/EventEditForm.vue b/frontend/src/components/EventEditForm.vue index 5ad77b3d6..6fbfdd5a7 100644 --- a/frontend/src/components/EventEditForm.vue +++ b/frontend/src/components/EventEditForm.vue @@ -1,6 +1,13 @@ diff --git a/frontend/src/components/releaseEditor/CommonImagesModal.vue b/frontend/src/components/releaseEditor/CommonImagesModal.vue index 8da68048e..2dabfcfbc 100644 --- a/frontend/src/components/releaseEditor/CommonImagesModal.vue +++ b/frontend/src/components/releaseEditor/CommonImagesModal.vue @@ -1,5 +1,11 @@