diff --git a/.gitignore b/.gitignore index 89e412234..0910e89c4 100644 --- a/.gitignore +++ b/.gitignore @@ -55,4 +55,7 @@ nohup.out .vscode/settings.json # tmp file -src/server/tmp/* \ No newline at end of file +src/server/tmp/* + +#ui-testing screenshots +src/cypress/screenshots/* diff --git a/cypress.config.ts b/cypress.config.ts new file mode 100644 index 000000000..e295790c2 --- /dev/null +++ b/cypress.config.ts @@ -0,0 +1,16 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +import { defineConfig } from 'cypress'; + +export default defineConfig({ + e2e: { + setupNodeEvents(on, config) { + // implement node event listeners here + }, + specPattern: 'src/cypress/e2e/*.cy.ts', + supportFile: 'src/cypress/support/e2e.ts', + screenshotsFolder: 'src/cypress/screenshots/e2e' + } +}); diff --git a/docker-compose.yml b/docker-compose.yml old mode 100644 new mode 100755 index d93db2b01..1b354cf39 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,6 +16,11 @@ services: - POSTGRES_PASSWORD=pleaseChange # default postgres password that should be changed for security. volumes: - ./postgres-data:/var/lib/postgresql/data/pgdata + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 10s + timeout: 10s + retries: 3 # ports: # - "5432:5432" # Uncomment the above lines to enable access to the PostgreSQL server @@ -68,10 +73,15 @@ services: # and comment out the debug port and 3000:3000 line above # Don't bring this up without the DB depends_on: - - database - # database: + # - database + database: # We need the database and it has to be ready for work (see healthcheck above). - # condition: service_healthy + condition: service_healthy + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3000"] + interval: 10s + timeout: 5s + retries: 5 # Lets docker compose up work right # If environment variable install_args is not set then it becomes blank without warning user. command: @@ -81,4 +91,24 @@ services: "${install_args:-}" ] # Use this if you are using a docker-compose that is earlier than version 2 and comment out the one above. - # command: ["bash", "./src/scripts/installOED.sh"] \ No newline at end of file + # command: ["bash", "./src/scripts/installOED.sh"] + + # Cypress testing service + cypress: + image: cypress/included + profiles: + - ui-testing + environment: + - CYPRESS_BASE_URL=http://web:3000 + - DISPLAY=:99 + working_dir: /usr/src/app + depends_on: + web: + condition: service_healthy + volumes: + - ./:/usr/src/app + entrypoint: > + /bin/sh -c " + rm -f /tmp/.X99-lock && + Xvfb :99 -screen 0 1024x768x16" + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 629ecbb91..68bc1cd28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10799,4 +10799,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/cypress/e2e/general_ui.cy.ts b/src/cypress/e2e/general_ui.cy.ts new file mode 100644 index 000000000..406b9ef1f --- /dev/null +++ b/src/cypress/e2e/general_ui.cy.ts @@ -0,0 +1,98 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// TODO: The commented out tests were attempts to test the UI that are +// not yet working. They need to be fixed. + +describe('UI Functionality Tests for Open Energy Dashboard', () => { + beforeEach(() => { + // Visit the page before each test + cy.visit('/'); + }); + + // it('Tests all buttons functionality', () => { + // // Ensure buttons are visible and clickable + // cy.get('button').should('have.length.greaterThan', 0); // Ensure buttons exist + // cy.get('button').each((button) => { + // cy.wrap(button).should('be.visible'); // Check visibility + // cy.wrap(button).click({ force: true }); // Test click + // }); + // }); + + // it('Tests all form inputs', () => { + // // Test text and email inputs + // cy.get('input[type="text"], input[type="email"]').each((input) => { + // cy.wrap(input).should('be.visible').type("Sample Text"); // Check visibility and type + // }); + + // // Test password inputs + // cy.get('input[type="password"]').each((input) => { + // cy.wrap(input).should('be.visible').type('password'); + // }); + + // // Test textareas + // cy.get('textarea').each((textarea) => { + // cy.wrap(textarea).should('be.visible').type('Sample description text'); + // }); + + // // Submit forms + // cy.get('form').each((form) => { + // cy.wrap(form).within(() => { + // cy.get('button[type="submit"], input[type="submit"]').click({ force: true }); + // }); + // }); + // }); + + // it('Tests dropdown menus', () => { + // // Ensure dropdowns are visible and options are selectable + // cy.get('select').should('have.length.greaterThan', 0); // Ensure dropdowns exist + // cy.get('select').each((dropdown) => { + // cy.wrap(dropdown) + // .should('be.visible') // Check visibility + // .find('option') + // .should('have.length.greaterThan', 1); // Ensure options exist + + // // Select the first option (change index as needed) + // cy.wrap(dropdown).select(0); + // }); + // }); + + it('Tests links for navigation', () => { + // Ensure links have valid href attributes + cy.get('a[href]').each((link) => { + cy.wrap(link).should('have.attr', 'href').and('not.be.empty'); // Check href exists + }); + }); + + // it('Tests modals for correct behavior', () => { + // // Ensure modals can be triggered and closed + // cy.get('[data-bs-toggle="modal"]').each((modalTrigger) => { + // cy.wrap(modalTrigger).should('be.visible').click(); // Trigger modal + // cy.get('.modal').should('be.visible'); // Check modal is visible + // cy.get('.modal .close').click(); // Close modal + // cy.get('.modal').should('not.be.visible'); // Check modal is closed + // }); + // }); + // it('Tests tables for data population', () => { + // // Ensure tables are populated with rows + // cy.get('table').should('have.length.greaterThan', 0); // Ensure tables exist + // cy.get('table').each((table) => { + // cy.wrap(table).find('tr').should('have.length.greaterThan', 1); // At least one row + // }); + // }); + // it('Tests interactive inputs (checkboxes and radio)', () => { + // // Check and uncheck checkboxes + // cy.get('input[type="checkbox"]').each((checkbox) => { + // cy.wrap(checkbox).check({ force: true }).should('be.checked'); // Check it + // cy.wrap(checkbox).uncheck({ force: true }).should('not.be.checked'); // Uncheck it + // }); + // cy.get('input[type="radio"]').each((radio) => { + // cy.wrap(radio).check({ force: true }).should('be.checked'); // Check radio + // }); + // }); + // it('Tests for dynamic elements', () => { + // // Ensure dynamically loaded elements exist and are visible + // cy.get('[data-dynamic]').should('exist').and('be.visible'); + // }); +}); diff --git a/src/cypress/e2e/hideOptions.cy.ts b/src/cypress/e2e/hideOptions.cy.ts new file mode 100644 index 000000000..c869f5341 --- /dev/null +++ b/src/cypress/e2e/hideOptions.cy.ts @@ -0,0 +1,38 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +describe("Options Menu Tests", () => { + beforeEach(() => { + // Visit the OED application + cy.visit("/"); + }); + + it("should toggle the visibility of graph configuration options when 'Hide options' is clicked", () => { + // Open the Options dropdown + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(3) > a").click(); + + // Click "Hide options" + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li.dropdown.show.nav-item > div > button:nth-child(2)").click(); + + // Verify that graph configuration options are hidden + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(2) > a").should("not.exist"); // pages + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(3) > a").should("not.exist"); // options + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > a:nth-child(4)").should("not.exist"); // help + + + + // Click "Menu" again to toggle visibility back + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > button").click(); + cy.get("body > div:nth-child(4) > div > div.modal.fade.show > div > div > div.modal-header > div > h6 > div > nav > div > ul > li:nth-child(3) > a").click(); + cy.get("body > div:nth-child(4) > div > div.modal.fade.show > div > div > div.modal-header > div > h6 > div > nav > div > ul > li.dropdown.show.nav-item > div > button:nth-child(2)").click(); + + + + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(2) > a").should("be.visible"); // pages + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(3) > a").should("be.visible"); // options + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > a:nth-child(4)").should("be.visible"); // help + + + }); +}); diff --git a/src/cypress/e2e/initLangTest.cy.ts b/src/cypress/e2e/initLangTest.cy.ts new file mode 100644 index 000000000..baf6a2b7a --- /dev/null +++ b/src/cypress/e2e/initLangTest.cy.ts @@ -0,0 +1,25 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +describe("Language Selector Tests", () => { + beforeEach(() => { + // Visit the OED application + cy.visit("/"); + }); + + it("should update the UI and React state when the language is changed", () => { + // Open the language selection dropdown + + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(3) > a").click(); + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li.dropdown.show.nav-item > div > div.dropdown.dropstart > a").click(); + + + // Select a specific language (e.g., Spanish) + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li.dropdown.show.nav-item > div > div.dropdown.dropstart.show > div").contains("Español").click(); + + // Verify that UI elements are updated to the selected language + cy.get("body").should("contain", "Tipo de gráfico"); // Example text in Spanish for "Graph Type" + + }); +}); diff --git a/src/cypress/e2e/line.cy.ts b/src/cypress/e2e/line.cy.ts new file mode 100644 index 000000000..805ef6842 --- /dev/null +++ b/src/cypress/e2e/line.cy.ts @@ -0,0 +1,92 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + // TODO These tests assume a clean setup/test data. In the future we should wipe the database + // and load the needed data (maybe without the actual meter data until needed) in a similar way + // to how the Chai/Mocha tests work. + +// This test is a great template to start with for understanding testing using cypress. +describe('testing line graph selecting groups and meters and test for plotly line graph ', () => { + beforeEach(() => { + // Visit the OED application + cy.visit('/'); + }); + + // Graph Type is Line. + // TODO This is the default line type when OED is created but can be changed by the admin. It might be good + // to first set it to this value at some point (but it does make another possible failure). + it('should display a line graph type automatically', () => { + // Find the line chart + cy.get('#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-2.d-none.d-lg-block > div > div.dropdown > button').should('have.text', 'Line'); + cy.screenshot('ShowLineTypeOption') + + }); + // Checking all group options + it('groups should be clickable and display 10 options and 1 incompatible option', () => { + // Find and click the group + cy.get('#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-2.d-none.d-lg-block > div > div:nth-child(4) > div:nth-child(2) > div > div.css-1fdsijx-ValueContainer').click().should('be.visible'); + // Check if the 10 options are there + cy.get('#react-select-2-listbox > div:nth-child(1) > div:nth-child(2)').children().should('have.length', 10); + cy.get('#react-select-2-group-0-heading > div > span.badge.bg-primary.rounded-pill').should('have.text', '10'); + // check if the incompatible option is visible and not clickable + cy.get('#react-select-2-option-1-0').should('exist') + .should('have.attr', 'aria-disabled', 'true') // Check the aria-disabled attribute + .should('have.attr', 'tabindex', '-1') // Validate tabindex to confirm it’s not focusable + }); + // Checking all meter options + it('selecting menu option should display 25 options and plotly graph', () => { + // open menu option + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-2.d-none.d-lg-block > div > div:nth-child(4) > div:nth-child(4) > div > div.css-1fdsijx-ValueContainer").click().should('be.visible'); + // Verify all options + cy.get("#react-select-3-listbox > div > div:nth-child(2)").children().should('have.length', 25); + // click on Cos 23 Min KWH + cy.get("#react-select-3-option-0-0").should('exist').click(); + + // plotly element show be dynamically created: check for plotly display + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div") + .should('exist'); + + //meter name should be displayed + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(3) > g.infolayer > g.legend > g > g > g > text").should('have.text', 'Cos 23 Min kWh'); + + // checking x-axis labels + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.xaxislayer-above > g:nth-child(1) > text").should('have.text', 'Mar 2020'); + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.xaxislayer-above > g:nth-child(2) > text").should('have.text', 'May 2020'); + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.xaxislayer-above > g:nth-child(3) > text").should('have.text', 'Jul 2020'); + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.xaxislayer-above > g:nth-child(4) > text").should('have.text', 'Sep 2020'); + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.xaxislayer-above > g:nth-child(5) > text").should('have.text', 'Nov 2020'); + + // checking y-axis labels + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.yaxislayer-above > g:nth-child(1) > text").should('have.text', '0'); + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.yaxislayer-above > g:nth-child(2) > text").should('have.text', '0.5'); + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.yaxislayer-above > g:nth-child(3) > text").should('have.text', '1'); + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.yaxislayer-above > g:nth-child(4) > text").should('have.text', '1.5'); + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.yaxislayer-above > g:nth-child(5) > text").should('have.text', '2'); + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.yaxislayer-above > g:nth-child(6) > text").should('have.text', '2.5'); + cy.get("#root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.yaxislayer-above > g:nth-child(7) > text").should('have.text', '3'); + + + /* + TODO: We want to check if the graph displays correct information. + After a meter or group is selected a get request is made to the server to get the data for the graph to the following endpoint: + http://localhost:3000/api/unitReadings/line/meters/21?timeInterval=all&graphicUnitId=1 + The response is a json object with the data that is used to plot the graph. + It might be possible to check the json object to see if the data is correct. + + Testing methods to + The line in the graph is rendered as path class ="js-line" + + Main Graph: + #root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(1) > g.cartesianlayer > g > g.plot > g > g > g.lines > path + + Drag Bar: + #root > div:nth-child(2) > div.container-fluid.flexGrowOne > div > div.col-12.col-lg-10.align-self-auto.text-center > div > div.js-plotly-plot > div > div > svg:nth-child(3) > g.infolayer > g.rangeslider-container > g.rangeslider-rangeplot.xy > g.plot > g > g > g.lines > path + + We could possibly simulate moving a mouse over the graph to check if the data is correct. + Clicking and dragging the bottom drag bar then refreshing the page + + And checking the time interval in which the data is displayed. (From seconds to day...) + */ + }); +}); diff --git a/src/cypress/e2e/pagesGroups.cy.ts b/src/cypress/e2e/pagesGroups.cy.ts new file mode 100644 index 000000000..fcec0073d --- /dev/null +++ b/src/cypress/e2e/pagesGroups.cy.ts @@ -0,0 +1,25 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +describe("Navigation to Groups Page", () => { + beforeEach(() => { + // Visit the application home page + cy.visit("/"); + }); + + it("should navigate to the Groups page when 'Groups' is clicked from the Pages dropdown", () => { + // Open the Pages dropdown + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(2) > a").click(); + + // Click the 'Groups' option in the dropdown + cy.contains("Groups").click(); + + // Verify that the Groups page has the correct title + cy.get("h2").should("have.text", "Groups"); + + // Verify the tooltip icon is present in the title + cy.get("h2 > div > i").should("have.attr", "data-for", "groups"); + cy.get("h2 > div > i").should("have.attr", "data-tip", "help.groups.groupview"); + }); +}); diff --git a/src/cypress/e2e/pagesMeters.cy.ts b/src/cypress/e2e/pagesMeters.cy.ts new file mode 100644 index 000000000..260214417 --- /dev/null +++ b/src/cypress/e2e/pagesMeters.cy.ts @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +describe("Navigation to Meters Page", () => { + beforeEach(() => { + // Visit the application home page + cy.visit("/"); + }); + + it("should navigate to the Meters page when 'Meters' is clicked from the Pages dropdown", () => { + // Open the Pages dropdown + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li:nth-child(2) > a").click(); + + // Click the 'Meters' option in the dropdown + cy.get("#header > div > div.col-4.justify-content-end.d-lg-flex.d-none > div > nav > div > ul > li.dropdown.show.nav-item > div > a:nth-child(6)").click(); + + + // Verify that the Meters page has the correct title + cy.get("h2").should("have.text", "Meters"); + + // Verify the tooltip icon is present in the title + cy.get("h2 > div > i").should("have.attr", "data-for", "meters"); + cy.get("h2 > div > i").should("have.attr", "data-tip", "help.meters.meterview"); + }); +}); diff --git a/src/cypress/e2e/tooltipIcon.cy.ts b/src/cypress/e2e/tooltipIcon.cy.ts new file mode 100644 index 000000000..366b16e72 --- /dev/null +++ b/src/cypress/e2e/tooltipIcon.cy.ts @@ -0,0 +1,22 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +describe('Tooltip Attribute Test', () => { + it('should add aria-describedby attribute after clicking the element', () => { + // Visit the page + cy.visit('/'); + + // Locate the element with the tooltip + cy.get('i[data-for="all"][data-tip="help.home.navigation"]') + .should('exist') // Ensure the element exists + .and('not.have.attr', 'aria-describedby'); // Verify aria-describedby is not present initially + + // Click the element + cy.get('i[data-for="all"][data-tip="help.home.navigation"]').click(); + + // Verify aria-describedby is added after clicking + cy.get('i[data-for="all"][data-tip="help.home.navigation"]') + .should('have.attr', 'aria-describedby', 'all'); // Confirm the correct attribute value + }); +}); diff --git a/src/cypress/support/commands.ts b/src/cypress/support/commands.ts new file mode 100644 index 000000000..4d97d8264 --- /dev/null +++ b/src/cypress/support/commands.ts @@ -0,0 +1,43 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + // TODO This might be removed once all basic tests are ready. + +/// +// *********************************************** +// 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 +// } +// } +// } diff --git a/src/cypress/support/e2e.ts b/src/cypress/support/e2e.ts new file mode 100644 index 000000000..acd0d08f9 --- /dev/null +++ b/src/cypress/support/e2e.ts @@ -0,0 +1,24 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// *********************************************************** +// 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