diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..b677df5 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "extends": [ + "plugin:cypress/recommended" + ] +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index a1066ba..efad958 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +/cypress/integration/examples/* +/cypress/videos/* +/cypress/fixtures +/cypress/screenshots # Created by https://www.toptal.com/developers/gitignore/api/vscode,node,intellij # Edit at https://www.toptal.com/developers/gitignore?templates=vscode,node,intellij diff --git a/cypress.json b/cypress.json new file mode 100644 index 0000000..f040c23 --- /dev/null +++ b/cypress.json @@ -0,0 +1,3 @@ +{ + "baseUrl": "http://localhost:5500" +} diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json new file mode 100644 index 0000000..02e4254 --- /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/calculator.ts b/cypress/integration/calculator.ts new file mode 100644 index 0000000..77d4686 --- /dev/null +++ b/cypress/integration/calculator.ts @@ -0,0 +1,473 @@ +// +//@ts-check +describe("addition test", () => { + it("add one digit numbers: 9 + 2", () => { + cy.visit("/"); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("+") + .click(); + cy.get(".digit") + .contains("2") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", 9 + 2); + }); + it("add one digit numbers: -9 + 2", () => { + cy.reload(); + cy.get(".operation") + .contains("-") + .click(); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("+") + .click(); + cy.get(".digit") + .contains("2") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", -9 + 2); + }); + it("add two digit numbers: 36 + 87", () => { + cy.reload(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".digit") + .contains("6") + .click(); + cy.get(".operation") + .contains("+") + .click(); + cy.get(".digit") + .contains("8") + .click(); + cy.get(".digit") + .contains("7") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", 36 + 87); + }); + it("add three digit numbers: 369 + 876", () => { + cy.reload(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".digit") + .contains("6") + .click(); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("+") + .click(); + cy.get(".digit") + .contains("8") + .click(); + cy.get(".digit") + .contains("7") + .click(); + cy.get(".digit") + .contains("6") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", 369 + 876); + }); +}); + +describe("subtraction test", () => { + it("subtract one digit numbers: 9 - 2", () => { + cy.visit("/"); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("-") + .click(); + cy.get(".digit") + .contains("2") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", 9 - 2); + }); + it("subtract one digit numbers: -9 - 2", () => { + cy.reload(); + cy.get(".operation") + .contains("-") + .click(); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("-") + .click(); + cy.get(".digit") + .contains("2") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", -9 - 2); + }); + it("subtract two digit numbers: 36 - 87", () => { + cy.reload(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".digit") + .contains("6") + .click(); + cy.get(".operation") + .contains("-") + .click(); + cy.get(".digit") + .contains("8") + .click(); + cy.get(".digit") + .contains("7") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", 36 - 87); + }); + it("subtract three digit numbers: 369 - 876", () => { + cy.reload(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".digit") + .contains("6") + .click(); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("-") + .click(); + cy.get(".digit") + .contains("8") + .click(); + cy.get(".digit") + .contains("7") + .click(); + cy.get(".digit") + .contains("6") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", 369 - 876); + }); +}); + +describe("multiplication test", () => { + it("multiply one digit numbers: 9 * 2", () => { + cy.visit("/"); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("X") + .click(); + cy.get(".digit") + .contains("2") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", 9 * 2); + }); + it("multiply one digit numbers: -9 * 2", () => { + cy.reload(); + cy.get(".operation") + .contains("-") + .click(); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("X") + .click(); + cy.get(".digit") + .contains("2") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", -9 * 2); + }); + it("multiply two digit numbers: 36 * 87", () => { + cy.reload(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".digit") + .contains("6") + .click(); + cy.get(".operation") + .contains("X") + .click(); + cy.get(".digit") + .contains("8") + .click(); + cy.get(".digit") + .contains("7") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", 36 * 87); + }); + it("multiply three digit numbers: 369 * 876", () => { + cy.reload(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".digit") + .contains("6") + .click(); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("X") + .click(); + cy.get(".digit") + .contains("8") + .click(); + cy.get(".digit") + .contains("7") + .click(); + cy.get(".digit") + .contains("6") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", 369 * 876); + }); +}); + +describe("division test", () => { + it("divide one digit numbers: 9 / 3", () => { + cy.visit("/"); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("/") + .click(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", 9 / 3); + }); + it("divide one digit numbers: -9 / 3", () => { + cy.reload(); + cy.get(".operation") + .contains("-") + .click(); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("/") + .click(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", -9 / 3); + }); + it("divide two digit numbers: 99 / 33", () => { + cy.visit("/"); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("/") + .click(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", 99 / 33); + }); + it("divide two digit numbers: -99 / 33", () => { + cy.reload(); + cy.get(".operation") + .contains("-") + .click(); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("/") + .click(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", -99 / 33); + }); + it("divide three digit numbers: 999 / 333", () => { + cy.visit("/"); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("/") + .click(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", 999 / 333); + }); +}); + +describe("AC test", () => { + it("click AC button", () => { + cy.get(".modifier").click(); + cy.get("#total").should("have.text", "0"); + }); +}); + +describe("decimal point test", () => { + it("divide one digit numbers: 9 / 2", () => { + cy.visit("/"); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("/") + .click(); + cy.get(".digit") + .contains("2") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", Math.floor(9 / 2)); + }); + it("divide one digit numbers: -9 / 2", () => { + cy.reload(); + cy.get(".operation") + .contains("-") + .click(); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("/") + .click(); + cy.get(".digit") + .contains("2") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", Math.floor(-9 / 2)); + }); + it("divide two digit numbers: 36 / 87", () => { + cy.reload(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".digit") + .contains("6") + .click(); + cy.get(".operation") + .contains("/") + .click(); + cy.get(".digit") + .contains("8") + .click(); + cy.get(".digit") + .contains("7") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", Math.floor(36 / 87)); + }); + it("divide three digit numbers: 369 / 876", () => { + cy.reload(); + cy.get(".digit") + .contains("3") + .click(); + cy.get(".digit") + .contains("6") + .click(); + cy.get(".digit") + .contains("9") + .click(); + cy.get(".operation") + .contains("/") + .click(); + cy.get(".digit") + .contains("8") + .click(); + cy.get(".digit") + .contains("7") + .click(); + cy.get(".digit") + .contains("6") + .click(); + cy.get(".operation") + .contains("=") + .click(); + cy.get("#total").should("have.text", Math.floor(369 / 876)); + }); +}); diff --git a/cypress/integration/examples/actions.spec.js b/cypress/integration/examples/actions.spec.js new file mode 100644 index 0000000..0926379 --- /dev/null +++ b/cypress/integration/examples/actions.spec.js @@ -0,0 +1,299 @@ +/// + +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