From 4db3c8293d5611e45431a7e0001666bd9395c6f9 Mon Sep 17 00:00:00 2001 From: Johannes Konings Date: Sun, 5 Apr 2020 16:15:55 +0200 Subject: [PATCH] initiales cypress setup (#46) --- .eslintrc.js | 3 +- .gitignore | 5 +- README.md | 7 + cypress.json | 1 + cypress/fixtures/example.json | 5 + cypress/integration/authenticator_spec.js | 35 + cypress/integration/examples/actions.spec.js | 298 ++++++ cypress/integration/examples/aliasing.spec.js | 42 + .../integration/examples/assertions.spec.js | 168 ++++ .../integration/examples/connectors.spec.js | 97 ++ cypress/integration/examples/cookies.spec.js | 78 ++ .../integration/examples/cypress_api.spec.js | 222 ++++ cypress/integration/examples/files.spec.js | 114 +++ .../examples/local_storage.spec.js | 52 + cypress/integration/examples/location.spec.js | 32 + cypress/integration/examples/misc.spec.js | 92 ++ .../integration/examples/navigation.spec.js | 56 ++ .../examples/network_requests.spec.js | 195 ++++ cypress/integration/examples/querying.spec.js | 114 +++ .../examples/spies_stubs_clocks.spec.js | 95 ++ .../integration/examples/traversal.spec.js | 121 +++ .../integration/examples/utilities.spec.js | 133 +++ cypress/integration/examples/viewport.spec.js | 59 ++ cypress/integration/examples/waiting.spec.js | 34 + cypress/integration/examples/window.spec.js | 22 + cypress/plugins/index.js | 21 + cypress/support/commands.js | 25 + cypress/support/index.js | 20 + package-lock.json | 948 +++++++++++++++++- package.json | 5 +- src/components/Navbars/AdminNavbarLinks.js | 2 + 31 files changed, 3096 insertions(+), 5 deletions(-) create mode 100644 cypress.json create mode 100644 cypress/fixtures/example.json create mode 100644 cypress/integration/authenticator_spec.js create mode 100644 cypress/integration/examples/actions.spec.js create mode 100644 cypress/integration/examples/aliasing.spec.js create mode 100644 cypress/integration/examples/assertions.spec.js create mode 100644 cypress/integration/examples/connectors.spec.js create mode 100644 cypress/integration/examples/cookies.spec.js create mode 100644 cypress/integration/examples/cypress_api.spec.js create mode 100644 cypress/integration/examples/files.spec.js create mode 100644 cypress/integration/examples/local_storage.spec.js create mode 100644 cypress/integration/examples/location.spec.js create mode 100644 cypress/integration/examples/misc.spec.js create mode 100644 cypress/integration/examples/navigation.spec.js create mode 100644 cypress/integration/examples/network_requests.spec.js create mode 100644 cypress/integration/examples/querying.spec.js create mode 100644 cypress/integration/examples/spies_stubs_clocks.spec.js create mode 100644 cypress/integration/examples/traversal.spec.js create mode 100644 cypress/integration/examples/utilities.spec.js create mode 100644 cypress/integration/examples/viewport.spec.js create mode 100644 cypress/integration/examples/waiting.spec.js create mode 100644 cypress/integration/examples/window.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.js b/.eslintrc.js index 3b1e841..994d46c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -16,6 +16,7 @@ module.exports = { extends: [ "eslint:recommended", "plugin:react/recommended", - "plugin:prettier/recommended" + "plugin:prettier/recommended", + "plugin:cypress/recommended" ] }; diff --git a/.gitignore b/.gitignore index 10435fa..06f4872 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,7 @@ awsconfiguration.json amplifyconfiguration.json amplify-gradle-config.json amplifyxc.config -amplify/team-provider-info.json \ No newline at end of file +amplify/team-provider-info.json + +#cypress +cypress.env.json \ No newline at end of file diff --git a/README.md b/README.md index 129c66f..4301a6f 100644 --- a/README.md +++ b/README.md @@ -35,3 +35,10 @@ https://aws.amazon.com/de/amplify/ ```sh amplify mock ``` + +## test + +```sh +npx cypress open +npm run cypress:open +``` diff --git a/cypress.json b/cypress.json new file mode 100644 index 0000000..f16085b --- /dev/null +++ b/cypress.json @@ -0,0 +1 @@ +{"baseUrl": "http://localhost:3000"} diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json new file mode 100644 index 0000000..da18d93 --- /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" +} \ No newline at end of file diff --git a/cypress/integration/authenticator_spec.js b/cypress/integration/authenticator_spec.js new file mode 100644 index 0000000..1caa917 --- /dev/null +++ b/cypress/integration/authenticator_spec.js @@ -0,0 +1,35 @@ +//https://glebbahmutov.com/blog/keep-passwords-secret-in-e2e-tests/ +//https://docs.cypress.io/guides/guides/environment-variables.html#Setting +describe("Authenticator:", function() { + // Step 1: setup the application state + beforeEach(function() { + cy.visit("/"); + }); + + describe("Sign In and out:", () => { + const username = Cypress.env("username"); + const password = Cypress.env("password"); + + it("allows a user to signin", () => { + // Step 2: Take an action (Sign in) + cy.get(selectors.usernameInput).type(username, { log: false }); + cy.get(selectors.signInPasswordInput).type(password, { log: false }); + cy.get(selectors.signInSignInButton) + .contains("Sign In") + .click(); + + // Step 3: Make an assertion (Check for sign-out text) + cy.get(selectors.profileDropdown).click({ multiple: true, force: true }); + //cy.get(selectors.profileLogout).click({ multiple: true }); + }); + }); +}); +export const selectors = { + // Auth component classes + usernameInput: '[data-test="username-input"]', + signInPasswordInput: '[data-test="sign-in-password-input"]', + signInSignInButton: '[data-test="sign-in-sign-in-button"]', + signOutButton: '[data-test="sign-out-button"]', + profileDropdown: '[data-test="profile-dropdown"]', + profileLogout: '[data-test="profile-logout"]' +}; diff --git a/cypress/integration/examples/actions.spec.js b/cypress/integration/examples/actions.spec.js new file mode 100644 index 0000000..f26ba63 --- /dev/null +++ b/cypress/integration/examples/actions.spec.js @@ -0,0 +1,298 @@ +/// + +context('Actions', () => { + beforeEach(() => { + cy.visit('https://example.cypress.io/commands/actions') + }) + + // https://on.cypress.io/interacting-with-elements + + it('.type() - type into a DOM element', () => { + // https://on.cypress.io/type + cy.get('.action-email') + .type('fake@email.com').should('have.value', 'fake@email.com') + + // .type() with special character sequences + .type('{leftarrow}{rightarrow}{uparrow}{downarrow}') + .type('{del}{selectall}{backspace}') + + // .type() with key modifiers + .type('{alt}{option}') //these are equivalent + .type('{ctrl}{control}') //these are equivalent + .type('{meta}{command}{cmd}') //these are equivalent + .type('{shift}') + + // Delay each keypress by 0.1 sec + .type('slow.typing@email.com', { delay: 100 }) + .should('have.value', 'slow.typing@email.com') + + cy.get('.action-disabled') + // Ignore error checking prior to type + // like whether the input is visible or disabled + .type('disabled error checking', { force: true }) + .should('have.value', 'disabled error checking') + }) + + it('.focus() - focus on a DOM element', () => { + // https://on.cypress.io/focus + cy.get('.action-focus').focus() + .should('have.class', 'focus') + .prev().should('have.attr', 'style', 'color: orange;') + }) + + it('.blur() - blur off a DOM element', () => { + // https://on.cypress.io/blur + cy.get('.action-blur').type('About to blur').blur() + .should('have.class', 'error') + .prev().should('have.attr', 'style', 'color: red;') + }) + + it('.clear() - clears an input or textarea element', () => { + // https://on.cypress.io/clear + cy.get('.action-clear').type('Clear this text') + .should('have.value', 'Clear this text') + .clear() + .should('have.value', '') + }) + + it('.submit() - submit a form', () => { + // https://on.cypress.io/submit + cy.get('.action-form') + .find('[type="text"]').type('HALFOFF') + cy.get('.action-form').submit() + .next().should('contain', 'Your form has been submitted!') + }) + + it('.click() - click on a DOM element', () => { + // https://on.cypress.io/click + cy.get('.action-btn').click() + + // You can click on 9 specific positions of an element: + // ----------------------------------- + // | topLeft top topRight | + // | | + // | | + // | | + // | left center right | + // | | + // | | + // | | + // | bottomLeft bottom bottomRight | + // ----------------------------------- + + // clicking in the center of the element is the default + cy.get('#action-canvas').click() + + cy.get('#action-canvas').click('topLeft') + cy.get('#action-canvas').click('top') + cy.get('#action-canvas').click('topRight') + cy.get('#action-canvas').click('left') + cy.get('#action-canvas').click('right') + cy.get('#action-canvas').click('bottomLeft') + cy.get('#action-canvas').click('bottom') + cy.get('#action-canvas').click('bottomRight') + + // .click() accepts an x and y coordinate + // that controls where the click occurs :) + + cy.get('#action-canvas') + .click(80, 75) // click 80px on x coord and 75px on y coord + .click(170, 75) + .click(80, 165) + .click(100, 185) + .click(125, 190) + .click(150, 185) + .click(170, 165) + + // click multiple elements by passing multiple: true + cy.get('.action-labels>.label').click({ multiple: true }) + + // Ignore error checking prior to clicking + cy.get('.action-opacity>.btn').click({ force: true }) + }) + + it('.dblclick() - double click on a DOM element', () => { + // https://on.cypress.io/dblclick + + // Our app has a listener on 'dblclick' event in our 'scripts.js' + // that hides the div and shows an input on double click + cy.get('.action-div').dblclick().should('not.be.visible') + cy.get('.action-input-hidden').should('be.visible') + }) + + it('.rightclick() - right click on a DOM element', () => { + // https://on.cypress.io/rightclick + + // Our app has a listener on 'contextmenu' event in our 'scripts.js' + // that hides the div and shows an input on right click + cy.get('.rightclick-action-div').rightclick().should('not.be.visible') + cy.get('.rightclick-action-input-hidden').should('be.visible') + }) + + it('.check() - check a checkbox or radio element', () => { + // https://on.cypress.io/check + + // By default, .check() will check all + // matching checkbox or radio elements in succession, one after another + cy.get('.action-checkboxes [type="checkbox"]').not('[disabled]') + .check().should('be.checked') + + cy.get('.action-radios [type="radio"]').not('[disabled]') + .check().should('be.checked') + + // .check() accepts a value argument + cy.get('.action-radios [type="radio"]') + .check('radio1').should('be.checked') + + // .check() accepts an array of values + cy.get('.action-multiple-checkboxes [type="checkbox"]') + .check(['checkbox1', 'checkbox2']).should('be.checked') + + // Ignore error checking prior to checking + cy.get('.action-checkboxes [disabled]') + .check({ force: true }).should('be.checked') + + cy.get('.action-radios [type="radio"]') + .check('radio3', { force: true }).should('be.checked') + }) + + it('.uncheck() - uncheck a checkbox element', () => { + // https://on.cypress.io/uncheck + + // By default, .uncheck() will uncheck all matching + // checkbox elements in succession, one after another + cy.get('.action-check [type="checkbox"]') + .not('[disabled]') + .uncheck().should('not.be.checked') + + // .uncheck() accepts a value argument + cy.get('.action-check [type="checkbox"]') + .check('checkbox1') + .uncheck('checkbox1').should('not.be.checked') + + // .uncheck() accepts an array of values + cy.get('.action-check [type="checkbox"]') + .check(['checkbox1', 'checkbox3']) + .uncheck(['checkbox1', 'checkbox3']).should('not.be.checked') + + // Ignore error checking prior to unchecking + cy.get('.action-check [disabled]') + .uncheck({ force: true }).should('not.be.checked') + }) + + it('.select() - select an option in a