├── cypress ├── fixtures │ ├── post.json │ └── example.json ├── e2e │ ├── 2-advanced-examples │ │ ├── window.cy.js │ │ ├── waiting.cy.js │ │ ├── location.cy.js │ │ ├── aliasing.cy.js │ │ ├── navigation.cy.js │ │ ├── viewport.cy.js │ │ ├── local_storage.cy.js │ │ ├── cookies.cy.js │ │ ├── files.cy.js │ │ ├── connectors.cy.js │ │ ├── misc.cy.js │ │ ├── utilities.cy.js │ │ ├── querying.cy.js │ │ ├── traversal.cy.js │ │ ├── assertions.cy.js │ │ ├── cypress_api.cy.js │ │ ├── spies_stubs_clocks.cy.js │ │ ├── network_requests.cy.js │ │ └── actions.cy.js │ ├── 3-advanced-api-examples │ │ ├── Intercept.cy.js │ │ ├── Get-GetIteration.cy.js │ │ ├── Get-Get.cy.js │ │ ├── oAuth2.cy.js │ │ ├── Post-Get.cy.js │ │ ├── Post-Post-Delete-Get.cy.js │ │ ├── Post-Post-Put-Get.cy.js │ │ ├── Post.cy.js │ │ ├── Get.cy.js │ │ └── GetWithChain.cy.js │ └── 1-getting-started │ │ └── todo.cy.js └── support │ ├── e2e.js │ └── commands.js ├── jsconfig.json ├── cypress.config.js ├── .github └── workflows │ ├── chrome.yml │ ├── firefox.yml │ └── main.yml ├── .gitignore ├── package.json └── README.md /cypress/fixtures/post.json: -------------------------------------------------------------------------------- 1 | { 2 | "title":"Luckyily", 3 | "body":"testers body", 4 | "userID": "168" 5 | } -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["./node_modules/cypress", "cypress/e2e/**/*.js"], 3 | "exclude": ["node_modules"] 4 | } -------------------------------------------------------------------------------- /cypress/fixtures/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Using fixtures to represent data", 3 | "email": "hello@cypress.io", 4 | "body": "Fixtures are a great way to mock data for responses to routes" 5 | } 6 | -------------------------------------------------------------------------------- /cypress.config.js: -------------------------------------------------------------------------------- 1 | const { defineConfig } = require("cypress"); 2 | 3 | module.exports = defineConfig({ 4 | e2e: { 5 | setupNodeEvents(on, config) { 6 | // implement node event listeners here 7 | }, 8 | watchForFileChanges: false, 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /.github/workflows/chrome.yml: -------------------------------------------------------------------------------- 1 | name: Chrome 2 | on: push 3 | jobs: 4 | chrome: 5 | runs-on: ubuntu-22.04 6 | name: E2E on Chrome 7 | steps: 8 | - uses: actions/checkout@v4 9 | - uses: cypress-io/github-action@v6 10 | with: 11 | browser: chrome 12 | -------------------------------------------------------------------------------- /.github/workflows/firefox.yml: -------------------------------------------------------------------------------- 1 | name: Firefox 2 | on: push 3 | jobs: 4 | firefox: 5 | runs-on: ubuntu-22.04 6 | name: E2E on Firefox 7 | steps: 8 | - uses: actions/checkout@v4 9 | - uses: cypress-io/github-action@v6 10 | with: 11 | browser: firefox 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # never include node_modules/ 2 | node_modules/ 3 | 4 | # not including unnecessary files 5 | customCommands.d.ts 6 | 7 | # not including videos and individual reports into the repo 8 | cypress/videos/ 9 | cypress/reports/ 10 | cypress/screenshots/ 11 | mochawesome-report/ 12 | cypress/integration/examples/ -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cypressapitestingframework", 3 | "version": "1.0.0", 4 | "description": "Cypress API Automation Framework", 5 | "main": "index.js", 6 | "scripts": { 7 | "Cyopen": "npx Cypress open", 8 | "Cyrun": "npx Cypress run" 9 | }, 10 | "author": "Atul Kumar Sharma", 11 | "license": "ISC", 12 | "dependencies": { 13 | "cypress-plugin-api": "^1.3.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/window.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Window', () => { 4 | beforeEach(() => { 5 | cy.visit('https://example.cypress.io/commands/window') 6 | }) 7 | 8 | it('cy.window() - get the global window object', () => { 9 | // https://on.cypress.io/window 10 | cy.window().should('have.property', 'top') 11 | }) 12 | 13 | it('cy.document() - get the document object', () => { 14 | // https://on.cypress.io/document 15 | cy.document().should('have.property', 'charset').and('eq', 'UTF-8') 16 | }) 17 | 18 | it('cy.title() - get the title', () => { 19 | // https://on.cypress.io/title 20 | cy.title().should('include', 'Kitchen Sink') 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /cypress/support/e2e.js: -------------------------------------------------------------------------------- 1 | // *********************************************************** 2 | // This example support/e2e.js is processed and 3 | // loaded automatically before your test files. 4 | // 5 | // This is a great place to put global configuration and 6 | // behavior that modifies Cypress. 7 | // 8 | // You can change the location of this file or turn off 9 | // automatically serving support files with the 10 | // 'supportFile' configuration option. 11 | // 12 | // You can read more here: 13 | // https://on.cypress.io/configuration 14 | // *********************************************************** 15 | 16 | // Import commands.js using ES2015 syntax: 17 | import "./commands"; 18 | import "cypress-plugin-api"; 19 | 20 | // Alternatively you can use CommonJS syntax: 21 | // require('./commands') 22 | -------------------------------------------------------------------------------- /cypress/e2e/3-advanced-api-examples/Intercept.cy.js: -------------------------------------------------------------------------------- 1 | describe("cypressAssignment", ()=>{ 2 | it('Login a user and validate his name via intercept', ()=>{ 3 | 4 | cy.intercept('POST', '/auth/login', (req) => { 5 | expect(req.body).to.include('Admin') 6 | }).as('username') 7 | 8 | cy.visit('https://opensource-demo.orangehrmlive.com') 9 | 10 | 11 | cy.get('form').within(($form)=>{ 12 | cy.get('#divUsername').type('Admin') 13 | cy.get('#divPassword').type('admin123') 14 | 15 | cy.get('#btnLogin').click() 16 | 17 | }) 18 | cy.wait('@username').its('response.body').should('to.have.property', 'name').and('include', 'Admin') 19 | 20 | 21 | 22 | cy.url().should('include','dashboard') 23 | 24 | 25 | }) -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Artifacts 2 | on: push 3 | jobs: 4 | cypress-run: 5 | runs-on: ubuntu-22.04 6 | name: Artifacts 7 | steps: 8 | - uses: actions/checkout@v4 9 | - uses: cypress-io/github-action@v6 10 | # after the test run completes store videos and any screenshots 11 | #- uses: actions/upload-artifact@v3 12 | # add the line below to store screenshots only on failures 13 | if: failure() 14 | with: 15 | name: cypress-screenshots 16 | path: cypress/screenshots 17 | if-no-files-found: ignore # 'warn' or 'error' are also available, defaults to `warn` 18 | - uses: actions/upload-artifact@v3 19 | with: 20 | name: cypress-videos 21 | path: cypress/videos 22 | if-no-files-found: ignore # 'warn' or 'error' are also available, defaults to `warn` 23 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/waiting.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Waiting', () => { 4 | beforeEach(() => { 5 | cy.visit('https://example.cypress.io/commands/waiting') 6 | }) 7 | // BE CAREFUL of adding unnecessary wait times. 8 | // https://on.cypress.io/best-practices#Unnecessary-Waiting 9 | 10 | // https://on.cypress.io/wait 11 | it('cy.wait() - wait for a specific amount of time', () => { 12 | cy.get('.wait-input1').type('Wait 1000ms after typing') 13 | cy.wait(1000) 14 | cy.get('.wait-input2').type('Wait 1000ms after typing') 15 | cy.wait(1000) 16 | cy.get('.wait-input3').type('Wait 1000ms after typing') 17 | cy.wait(1000) 18 | }) 19 | 20 | it('cy.wait() - wait for a specific route', () => { 21 | // Listen to GET to comments/1 22 | cy.intercept('GET', '**/comments/*').as('getComment') 23 | 24 | // we have code that gets a comment when 25 | // the button is clicked in scripts.js 26 | cy.get('.network-btn').click() 27 | 28 | // wait for GET comments/1 29 | cy.wait('@getComment').its('response.statusCode').should('be.oneOf', [200, 304]) 30 | }) 31 | }) 32 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/location.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Location', () => { 4 | beforeEach(() => { 5 | cy.visit('https://example.cypress.io/commands/location') 6 | }) 7 | 8 | it('cy.hash() - get the current URL hash', () => { 9 | // https://on.cypress.io/hash 10 | cy.hash().should('be.empty') 11 | }) 12 | 13 | it('cy.location() - get window.location', () => { 14 | // https://on.cypress.io/location 15 | cy.location().should((location) => { 16 | expect(location.hash).to.be.empty 17 | expect(location.href).to.eq('https://example.cypress.io/commands/location') 18 | expect(location.host).to.eq('example.cypress.io') 19 | expect(location.hostname).to.eq('example.cypress.io') 20 | expect(location.origin).to.eq('https://example.cypress.io') 21 | expect(location.pathname).to.eq('/commands/location') 22 | expect(location.port).to.eq('') 23 | expect(location.protocol).to.eq('https:') 24 | expect(location.search).to.be.empty 25 | }) 26 | }) 27 | 28 | it('cy.url() - get the current URL', () => { 29 | // https://on.cypress.io/url 30 | cy.url().should('eq', 'https://example.cypress.io/commands/location') 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/aliasing.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Aliasing', () => { 4 | beforeEach(() => { 5 | cy.visit('https://example.cypress.io/commands/aliasing') 6 | }) 7 | 8 | it('.as() - alias a DOM element for later use', () => { 9 | // https://on.cypress.io/as 10 | 11 | // Alias a DOM element for use later 12 | // We don't have to traverse to the element 13 | // later in our code, we reference it with @ 14 | 15 | cy.get('.as-table').find('tbody>tr') 16 | .first().find('td').first() 17 | .find('button').as('firstBtn') 18 | 19 | // when we reference the alias, we place an 20 | // @ in front of its name 21 | cy.get('@firstBtn').click() 22 | 23 | cy.get('@firstBtn') 24 | .should('have.class', 'btn-success') 25 | .and('contain', 'Changed') 26 | }) 27 | 28 | it('.as() - alias a route for later use', () => { 29 | // Alias the route to wait for its response 30 | cy.intercept('GET', '**/comments/*').as('getComment') 31 | 32 | // we have code that gets a comment when 33 | // the button is clicked in scripts.js 34 | cy.get('.network-btn').click() 35 | 36 | // https://on.cypress.io/wait 37 | cy.wait('@getComment').its('response.statusCode').should('eq', 200) 38 | }) 39 | }) 40 | -------------------------------------------------------------------------------- /cypress/e2e/3-advanced-api-examples/Get-GetIteration.cy.js: -------------------------------------------------------------------------------- 1 | describe("Get-Get Iteration Call", () => { 2 | const baseURL = "https://dummyapi.io/"; 3 | const appid = "6348313ab96b557182415224"; 4 | 5 | it("CreateGetThenGet", () => { 6 | cy.api({ 7 | method: "GET", 8 | url: baseURL + "data/v1/tag/water/post?limit=10", 9 | headers: { 10 | "content-type": "application/json; charset=utf-8", 11 | "app-id": appid, 12 | }, 13 | }) 14 | .then((response) => { 15 | expect(response.status).to.eq(200); 16 | expect(response.body).to.have.property("data"); 17 | expect(response.body).to.be.a("object"); 18 | assert.typeOf(response.body.data, "array"); 19 | let respData = response.body.data; 20 | return respData; 21 | }) 22 | .then((respData) => { 23 | cy.log("Value of resp Body:->" + JSON.stringify(respData)); 24 | expect(respData).to.be.a("array"); 25 | expect(respData).to.be.a("array").that.is.not.empty; 26 | expect(respData).to.have.lengthOf.above(1); 27 | 28 | for (let itru of respData) { 29 | //cy.log(itru); 30 | expect(itru).to.have.property("tags"); 31 | expect("water").to.contain.oneOf(itru.tags); 32 | } 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /cypress/support/commands.js: -------------------------------------------------------------------------------- 1 | // *********************************************** 2 | // This example commands.js shows you how to 3 | // create various custom commands and overwrite 4 | // existing commands. 5 | // 6 | // For more comprehensive examples of custom 7 | // commands please read more here: 8 | // https://on.cypress.io/custom-commands 9 | // *********************************************** 10 | // 11 | // 12 | // -- This is a parent command -- 13 | // Cypress.Commands.add('login', (email, password) => { ... }) 14 | // 15 | // 16 | // -- This is a child command -- 17 | // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) 18 | // 19 | // 20 | // -- This is a dual command -- 21 | // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) 22 | // 23 | // 24 | // -- This will overwrite an existing command -- 25 | // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) 26 | 27 | // Cypress.Commands.add(randomString(length)) { 28 | // var result = ''; 29 | // var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; 30 | // var charactersLength = characters.length; 31 | // for ( var i = 0; i < length; i++ ) { 32 | // result += characters.charAt(Math.floor(Math.random() * 33 | // charactersLength)); 34 | // } 35 | // return result; 36 | // } 37 | -------------------------------------------------------------------------------- /cypress/e2e/3-advanced-api-examples/Get-Get.cy.js: -------------------------------------------------------------------------------- 1 | describe("Get-Get Call", () => { 2 | const baseURL = "https://dummyapi.io/"; 3 | const appid = "6348313ab96b557182415224"; 4 | 5 | it("CreateGetThenGet", () => { 6 | cy.request({ 7 | method: "GET", 8 | url: baseURL + "/data/v1/tag?limit=10", 9 | headers: { 10 | "content-type": "application/json; charset=utf-8", 11 | "app-id": appid, 12 | }, 13 | }) 14 | .then((response) => { 15 | expect(response.status).to.eq(200); 16 | expect(response.body).to.have.property("data"); 17 | expect(response.body.data).to.be.a("array"); 18 | assert.typeOf(response.body.data, "array"); 19 | let selectedTag = response.body.data[8].trim(); 20 | return selectedTag; 21 | }) 22 | .then((selectedTag) => { 23 | cy.log("Value of selectedTag:->" + selectedTag); 24 | cy.request({ 25 | method: "GET", 26 | url: baseURL + "/data/v1/tag/" + selectedTag + "/post?limit=10", 27 | headers: { 28 | "content-type": "application/json; charset=utf-8", 29 | "app-id": appid, 30 | }, 31 | }).then((response) => { 32 | //cy.log(JSON.stringify(response)); 33 | expect(response.status).to.eq(200); 34 | expect(response.body).to.have.property("data"); 35 | expect(response.body.data).to.be.a("array"); 36 | assert.typeOf(response.body.data, "array"); 37 | }); 38 | }); 39 | }); 40 | }); 41 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/navigation.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Navigation', () => { 4 | beforeEach(() => { 5 | cy.visit('https://example.cypress.io') 6 | cy.get('.navbar-nav').contains('Commands').click() 7 | cy.get('.dropdown-menu').contains('Navigation').click() 8 | }) 9 | 10 | it('cy.go() - go back or forward in the browser\'s history', () => { 11 | // https://on.cypress.io/go 12 | 13 | cy.location('pathname').should('include', 'navigation') 14 | 15 | cy.go('back') 16 | cy.location('pathname').should('not.include', 'navigation') 17 | 18 | cy.go('forward') 19 | cy.location('pathname').should('include', 'navigation') 20 | 21 | // clicking back 22 | cy.go(-1) 23 | cy.location('pathname').should('not.include', 'navigation') 24 | 25 | // clicking forward 26 | cy.go(1) 27 | cy.location('pathname').should('include', 'navigation') 28 | }) 29 | 30 | it('cy.reload() - reload the page', () => { 31 | // https://on.cypress.io/reload 32 | cy.reload() 33 | 34 | // reload the page without using the cache 35 | cy.reload(true) 36 | }) 37 | 38 | it('cy.visit() - visit a remote url', () => { 39 | // https://on.cypress.io/visit 40 | 41 | // Visit any sub-domain of your current domain 42 | 43 | // Pass options to the visit 44 | cy.visit('https://example.cypress.io/commands/navigation', { 45 | timeout: 50000, // increase total time for the visit to resolve 46 | onBeforeLoad (contentWindow) { 47 | // contentWindow is the remote page's window object 48 | expect(typeof contentWindow === 'object').to.be.true 49 | }, 50 | onLoad (contentWindow) { 51 | // contentWindow is the remote page's window object 52 | expect(typeof contentWindow === 'object').to.be.true 53 | }, 54 | }) 55 | }) 56 | }) 57 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/viewport.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Viewport', () => { 4 | beforeEach(() => { 5 | cy.visit('https://example.cypress.io/commands/viewport') 6 | }) 7 | 8 | it('cy.viewport() - set the viewport size and dimension', () => { 9 | // https://on.cypress.io/viewport 10 | 11 | cy.get('#navbar').should('be.visible') 12 | cy.viewport(320, 480) 13 | 14 | // the navbar should have collapse since our screen is smaller 15 | cy.get('#navbar').should('not.be.visible') 16 | cy.get('.navbar-toggle').should('be.visible').click() 17 | cy.get('.nav').find('a').should('be.visible') 18 | 19 | // lets see what our app looks like on a super large screen 20 | cy.viewport(2999, 2999) 21 | 22 | // cy.viewport() accepts a set of preset sizes 23 | // to easily set the screen to a device's width and height 24 | 25 | // We added a cy.wait() between each viewport change so you can see 26 | // the change otherwise it is a little too fast to see :) 27 | 28 | cy.viewport('macbook-15') 29 | cy.wait(200) 30 | cy.viewport('macbook-13') 31 | cy.wait(200) 32 | cy.viewport('macbook-11') 33 | cy.wait(200) 34 | cy.viewport('ipad-2') 35 | cy.wait(200) 36 | cy.viewport('ipad-mini') 37 | cy.wait(200) 38 | cy.viewport('iphone-6+') 39 | cy.wait(200) 40 | cy.viewport('iphone-6') 41 | cy.wait(200) 42 | cy.viewport('iphone-5') 43 | cy.wait(200) 44 | cy.viewport('iphone-4') 45 | cy.wait(200) 46 | cy.viewport('iphone-3') 47 | cy.wait(200) 48 | 49 | // cy.viewport() accepts an orientation for all presets 50 | // the default orientation is 'portrait' 51 | cy.viewport('ipad-2', 'portrait') 52 | cy.wait(200) 53 | cy.viewport('iphone-4', 'landscape') 54 | cy.wait(200) 55 | 56 | // The viewport will be reset back to the default dimensions 57 | // in between tests (the default can be set in cypress.config.{js|ts}) 58 | }) 59 | }) 60 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/local_storage.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Local Storage', () => { 4 | beforeEach(() => { 5 | cy.visit('https://example.cypress.io/commands/local-storage') 6 | }) 7 | // Although local storage is automatically cleared 8 | // in between tests to maintain a clean state 9 | // sometimes we need to clear the local storage manually 10 | 11 | it('cy.clearLocalStorage() - clear all data in local storage', () => { 12 | // https://on.cypress.io/clearlocalstorage 13 | cy.get('.ls-btn').click().should(() => { 14 | expect(localStorage.getItem('prop1')).to.eq('red') 15 | expect(localStorage.getItem('prop2')).to.eq('blue') 16 | expect(localStorage.getItem('prop3')).to.eq('magenta') 17 | }) 18 | 19 | // clearLocalStorage() yields the localStorage object 20 | cy.clearLocalStorage().should((ls) => { 21 | expect(ls.getItem('prop1')).to.be.null 22 | expect(ls.getItem('prop2')).to.be.null 23 | expect(ls.getItem('prop3')).to.be.null 24 | }) 25 | 26 | cy.get('.ls-btn').click().should(() => { 27 | expect(localStorage.getItem('prop1')).to.eq('red') 28 | expect(localStorage.getItem('prop2')).to.eq('blue') 29 | expect(localStorage.getItem('prop3')).to.eq('magenta') 30 | }) 31 | 32 | // Clear key matching string in Local Storage 33 | cy.clearLocalStorage('prop1').should((ls) => { 34 | expect(ls.getItem('prop1')).to.be.null 35 | expect(ls.getItem('prop2')).to.eq('blue') 36 | expect(ls.getItem('prop3')).to.eq('magenta') 37 | }) 38 | 39 | cy.get('.ls-btn').click().should(() => { 40 | expect(localStorage.getItem('prop1')).to.eq('red') 41 | expect(localStorage.getItem('prop2')).to.eq('blue') 42 | expect(localStorage.getItem('prop3')).to.eq('magenta') 43 | }) 44 | 45 | // Clear keys matching regex in Local Storage 46 | cy.clearLocalStorage(/prop1|2/).should((ls) => { 47 | expect(ls.getItem('prop1')).to.be.null 48 | expect(ls.getItem('prop2')).to.be.null 49 | expect(ls.getItem('prop3')).to.eq('magenta') 50 | }) 51 | }) 52 | }) 53 | -------------------------------------------------------------------------------- /cypress/e2e/3-advanced-api-examples/oAuth2.cy.js: -------------------------------------------------------------------------------- 1 | //https://restful-booker.herokuapp.com/apidoc/index.html 2 | 3 | describe("oAuth2.0", () => { 4 | const baseURLoAuth = "http://coop.apps.symfonycasts.com"; 5 | it("Post-Post-Put-Get", () => { 6 | //Auth Token-Post 7 | cy.api({ 8 | url: baseURLoAuth + "/token", 9 | method: "POST", 10 | form: true, 11 | body: { 12 | client_id: "AtulOAuthApp", 13 | client_secret: "a9a988974ce7920ff678f1f32ddb745d", 14 | grant_type: "client_credentials", 15 | //redirect_uri: "https://youtube.com", 16 | }, 17 | }).as("GetoAuthToken"); 18 | 19 | cy.get("@GetoAuthToken") 20 | .then(function (respo) { 21 | expect(respo.status).to.equal(200); 22 | //Got the Auth token 23 | let tokenValue = respo.body.access_token; 24 | //cy.log(tokenValue); 25 | return tokenValue; 26 | }) 27 | .then((tokenValue) => { 28 | //Booking created 29 | cy.api({ 30 | url: baseURLoAuth + "/api/me", 31 | method: "GET", 32 | headers: { 33 | "content-type": "application/x-www-form-urlencoded", 34 | "Cache-Control": "no-cache", 35 | followRedirect: false, 36 | Authorization: "Bearer " + tokenValue, 37 | }, 38 | }).as("GetUserIdbyGetCall"); 39 | 40 | cy.get("@GetUserIdbyGetCall") 41 | .then((respo) => { 42 | expect(respo.status).to.equal(200); 43 | let userIdValue = respo.body.id; 44 | //cy.log(userIdValue); 45 | return userIdValue; 46 | }) 47 | .then((userIdValue) => { 48 | cy.log("value of userIdValue is-->" + userIdValue); 49 | cy.api({ 50 | url: baseURLoAuth + "/api/" + userIdValue + "/barn-unlock", 51 | method: "POST", 52 | headers: { 53 | Authorization: "Bearer " + tokenValue, 54 | }, 55 | }).then((response) => { 56 | expect(response.status).to.equal(200); 57 | expect(response.body).to.have.property("data"); 58 | expect(response.body.action).to.eq("barn-unlock"); 59 | expect(response.body.success).to.eq(true); 60 | expect(response.body).to.have.property("success", true); 61 | expect(response.body).to.be.a("object"); 62 | }); 63 | }); 64 | }); 65 | }); 66 | }); 67 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/cookies.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Cookies', () => { 4 | beforeEach(() => { 5 | Cypress.Cookies.debug(true) 6 | 7 | cy.visit('https://example.cypress.io/commands/cookies') 8 | 9 | // clear cookies again after visiting to remove 10 | // any 3rd party cookies picked up such as cloudflare 11 | cy.clearCookies() 12 | }) 13 | 14 | it('cy.getCookie() - get a browser cookie', () => { 15 | // https://on.cypress.io/getcookie 16 | cy.get('#getCookie .set-a-cookie').click() 17 | 18 | // cy.getCookie() yields a cookie object 19 | cy.getCookie('token').should('have.property', 'value', '123ABC') 20 | }) 21 | 22 | it('cy.getCookies() - get browser cookies', () => { 23 | // https://on.cypress.io/getcookies 24 | cy.getCookies().should('be.empty') 25 | 26 | cy.get('#getCookies .set-a-cookie').click() 27 | 28 | // cy.getCookies() yields an array of cookies 29 | cy.getCookies().should('have.length', 1).should((cookies) => { 30 | // each cookie has these properties 31 | expect(cookies[0]).to.have.property('name', 'token') 32 | expect(cookies[0]).to.have.property('value', '123ABC') 33 | expect(cookies[0]).to.have.property('httpOnly', false) 34 | expect(cookies[0]).to.have.property('secure', false) 35 | expect(cookies[0]).to.have.property('domain') 36 | expect(cookies[0]).to.have.property('path') 37 | }) 38 | }) 39 | 40 | it('cy.setCookie() - set a browser cookie', () => { 41 | // https://on.cypress.io/setcookie 42 | cy.getCookies().should('be.empty') 43 | 44 | cy.setCookie('foo', 'bar') 45 | 46 | // cy.getCookie() yields a cookie object 47 | cy.getCookie('foo').should('have.property', 'value', 'bar') 48 | }) 49 | 50 | it('cy.clearCookie() - clear a browser cookie', () => { 51 | // https://on.cypress.io/clearcookie 52 | cy.getCookie('token').should('be.null') 53 | 54 | cy.get('#clearCookie .set-a-cookie').click() 55 | 56 | cy.getCookie('token').should('have.property', 'value', '123ABC') 57 | 58 | // cy.clearCookies() yields null 59 | cy.clearCookie('token').should('be.null') 60 | 61 | cy.getCookie('token').should('be.null') 62 | }) 63 | 64 | it('cy.clearCookies() - clear browser cookies', () => { 65 | // https://on.cypress.io/clearcookies 66 | cy.getCookies().should('be.empty') 67 | 68 | cy.get('#clearCookies .set-a-cookie').click() 69 | 70 | cy.getCookies().should('have.length', 1) 71 | 72 | // cy.clearCookies() yields null 73 | cy.clearCookies() 74 | 75 | cy.getCookies().should('be.empty') 76 | }) 77 | }) 78 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/files.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | /// JSON fixture file can be loaded directly using 4 | // the built-in JavaScript bundler 5 | const requiredExample = require('../../fixtures/example') 6 | 7 | context('Files', () => { 8 | beforeEach(() => { 9 | cy.visit('https://example.cypress.io/commands/files') 10 | }) 11 | 12 | beforeEach(() => { 13 | // load example.json fixture file and store 14 | // in the test context object 15 | cy.fixture('example.json').as('example') 16 | }) 17 | 18 | it('cy.fixture() - load a fixture', () => { 19 | // https://on.cypress.io/fixture 20 | 21 | // Instead of writing a response inline you can 22 | // use a fixture file's content. 23 | 24 | // when application makes an Ajax request matching "GET **/comments/*" 25 | // Cypress will intercept it and reply with the object in `example.json` fixture 26 | cy.intercept('GET', '**/comments/*', { fixture: 'example.json' }).as('getComment') 27 | 28 | // we have code that gets a comment when 29 | // the button is clicked in scripts.js 30 | cy.get('.fixture-btn').click() 31 | 32 | cy.wait('@getComment').its('response.body') 33 | .should('have.property', 'name') 34 | .and('include', 'Using fixtures to represent data') 35 | }) 36 | 37 | it('cy.fixture() or require - load a fixture', function () { 38 | // we are inside the "function () { ... }" 39 | // callback and can use test context object "this" 40 | // "this.example" was loaded in "beforeEach" function callback 41 | expect(this.example, 'fixture in the test context') 42 | .to.deep.equal(requiredExample) 43 | 44 | // or use "cy.wrap" and "should('deep.equal', ...)" assertion 45 | cy.wrap(this.example) 46 | .should('deep.equal', requiredExample) 47 | }) 48 | 49 | it('cy.readFile() - read file contents', () => { 50 | // https://on.cypress.io/readfile 51 | 52 | // You can read a file and yield its contents 53 | // The filePath is relative to your project's root. 54 | cy.readFile(Cypress.config('configFile')).then((config) => { 55 | expect(config).to.be.an('string') 56 | }) 57 | }) 58 | 59 | it('cy.writeFile() - write to a file', () => { 60 | // https://on.cypress.io/writefile 61 | 62 | // You can write to a file 63 | 64 | // Use a response from a request to automatically 65 | // generate a fixture file for use later 66 | cy.request('https://jsonplaceholder.cypress.io/users') 67 | .then((response) => { 68 | cy.writeFile('cypress/fixtures/users.json', response.body) 69 | }) 70 | 71 | cy.fixture('users').should((users) => { 72 | expect(users[0].name).to.exist 73 | }) 74 | 75 | // JavaScript arrays and objects are stringified 76 | // and formatted into text. 77 | cy.writeFile('cypress/fixtures/profile.json', { 78 | id: 8739, 79 | name: 'Jane', 80 | email: 'jane@example.com', 81 | }) 82 | 83 | cy.fixture('profile').should((profile) => { 84 | expect(profile.name).to.eq('Jane') 85 | }) 86 | }) 87 | }) 88 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/connectors.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Connectors', () => { 4 | beforeEach(() => { 5 | cy.visit('https://example.cypress.io/commands/connectors') 6 | }) 7 | 8 | it('.each() - iterate over an array of elements', () => { 9 | // https://on.cypress.io/each 10 | cy.get('.connectors-each-ul>li') 11 | .each(($el, index, $list) => { 12 | console.log($el, index, $list) 13 | }) 14 | }) 15 | 16 | it('.its() - get properties on the current subject', () => { 17 | // https://on.cypress.io/its 18 | cy.get('.connectors-its-ul>li') 19 | // calls the 'length' property yielding that value 20 | .its('length') 21 | .should('be.gt', 2) 22 | }) 23 | 24 | it('.invoke() - invoke a function on the current subject', () => { 25 | // our div is hidden in our script.js 26 | // $('.connectors-div').hide() 27 | 28 | // https://on.cypress.io/invoke 29 | cy.get('.connectors-div').should('be.hidden') 30 | // call the jquery method 'show' on the 'div.container' 31 | .invoke('show') 32 | .should('be.visible') 33 | }) 34 | 35 | it('.spread() - spread an array as individual args to callback function', () => { 36 | // https://on.cypress.io/spread 37 | const arr = ['foo', 'bar', 'baz'] 38 | 39 | cy.wrap(arr).spread((foo, bar, baz) => { 40 | expect(foo).to.eq('foo') 41 | expect(bar).to.eq('bar') 42 | expect(baz).to.eq('baz') 43 | }) 44 | }) 45 | 46 | describe('.then()', () => { 47 | it('invokes a callback function with the current subject', () => { 48 | // https://on.cypress.io/then 49 | cy.get('.connectors-list > li') 50 | .then(($lis) => { 51 | expect($lis, '3 items').to.have.length(3) 52 | expect($lis.eq(0), 'first item').to.contain('Walk the dog') 53 | expect($lis.eq(1), 'second item').to.contain('Feed the cat') 54 | expect($lis.eq(2), 'third item').to.contain('Write JavaScript') 55 | }) 56 | }) 57 | 58 | it('yields the returned value to the next command', () => { 59 | cy.wrap(1) 60 | .then((num) => { 61 | expect(num).to.equal(1) 62 | 63 | return 2 64 | }) 65 | .then((num) => { 66 | expect(num).to.equal(2) 67 | }) 68 | }) 69 | 70 | it('yields the original subject without return', () => { 71 | cy.wrap(1) 72 | .then((num) => { 73 | expect(num).to.equal(1) 74 | // note that nothing is returned from this callback 75 | }) 76 | .then((num) => { 77 | // this callback receives the original unchanged value 1 78 | expect(num).to.equal(1) 79 | }) 80 | }) 81 | 82 | it('yields the value yielded by the last Cypress command inside', () => { 83 | cy.wrap(1) 84 | .then((num) => { 85 | expect(num).to.equal(1) 86 | // note how we run a Cypress command 87 | // the result yielded by this Cypress command 88 | // will be passed to the second ".then" 89 | cy.wrap(2) 90 | }) 91 | .then((num) => { 92 | // this callback receives the value yielded by "cy.wrap(2)" 93 | expect(num).to.equal(2) 94 | }) 95 | }) 96 | }) 97 | }) 98 | -------------------------------------------------------------------------------- /cypress/e2e/3-advanced-api-examples/Post-Get.cy.js: -------------------------------------------------------------------------------- 1 | const dataJson = require("../../fixtures/post.json"); 2 | 3 | describe("Post Call", () => { 4 | const baseURL = "https://jsonplaceholder.typicode.com"; 5 | 6 | it("CreatePostThenGet", () => { 7 | cy.fixture("post.json").then(function (payload) { 8 | cy.request({ 9 | method: "POST", 10 | url: baseURL + "/posts", 11 | body: { 12 | title: payload.title, 13 | body: payload.body, 14 | userID: payload.userID, 15 | }, 16 | headers: { 17 | "content-type": "application/json; charset=utf-8", 18 | "Cache-Control": "no-cache", 19 | followRedirect: false, // turn off following redirects 20 | }, 21 | }).as("CreatePostJSON"); 22 | 23 | cy.get("@CreatePostJSON") 24 | .then((response) => { 25 | cy.log(JSON.stringify(response)); 26 | //response: status 27 | expect(response.status).to.equal(201); 28 | expect(response.status).to.eq(201); 29 | 30 | //response body: key only 31 | expect(response.body).to.have.property("userID"); 32 | expect(response.body).to.have.property("id"); 33 | expect(response.body).to.have.property("title"); 34 | expect(response.body).to.have.property("body"); 35 | expect(response).to.have.property("headers"); 36 | expect(response).to.have.property("duration"); 37 | 38 | //response body: key & value 39 | expect(response.body).to.have.property("userID", payload.userID); 40 | expect(response.body).to.have.property("title", payload.title); 41 | expect(response.body).has.property("body", payload.body); 42 | 43 | //response headers 44 | expect(response).to.include.keys("headers", "duration"); 45 | expect(response.headers).to.have.property( 46 | "content-type", 47 | "application/json; charset=utf-8" 48 | ); 49 | expect(response.headers).property("content-type").to.be.a("string"); 50 | expect(response.headers) 51 | .property("X-Ratelimit-Remaining".toLowerCase()) 52 | .to.be.a("string"); 53 | 54 | //response body- Data Types 55 | // expect(response.body).property("userID").to.be.a("string"); 56 | //expect(response.body).property("title").to.be.a("string"); 57 | // expect(response.body).property("body").to.be.a("string"); 58 | //expect(response.body).property("id").to.be.a("number"); 59 | }) 60 | .then(function (resp) { 61 | let userIDUsed = payload.userID; 62 | cy.log("Value of payload's userID:" + payload.userID); 63 | cy.log("Value of userID:" + userIDUsed); 64 | 65 | cy.request({ 66 | method: "GET", 67 | url: baseURL + "/posts/" + userIDUsed, 68 | headers: { 69 | "content-type": "application/json; charset=utf-8", 70 | "Cache-Control": "no-cache", 71 | }, 72 | }).then((response) => { 73 | cy.log(JSON.stringify(response)); 74 | //response: status 75 | expect(response.status).to.equal(200); 76 | expect(response.status).to.eq(200); 77 | // expect(response.body).to.have.property("userId", payload.userID); 78 | }); 79 | }); 80 | }); 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /cypress/e2e/3-advanced-api-examples/Post-Post-Delete-Get.cy.js: -------------------------------------------------------------------------------- 1 | //https://restful-booker.herokuapp.com/apidoc/index.html 2 | 3 | describe("Delete", () => { 4 | const baseURL = "https://restful-booker.herokuapp.com"; 5 | it("Post-Post-Put-Get", () => { 6 | //Auth Token-Post 7 | cy.api({ 8 | url: baseURL + "/auth", 9 | method: "POST", 10 | body: { 11 | username: "admin", 12 | password: "password123", 13 | }, 14 | headers: { 15 | "content-type": "application/json; charset=utf-8", 16 | "Cache-Control": "no-cache", 17 | followRedirect: false, // turn off following redirects 18 | }, 19 | }).as("GetAuthTokenByPostCall"); 20 | 21 | cy.get("@GetAuthTokenByPostCall") 22 | .then(function (respo) { 23 | expect(respo.status).to.equal(200); 24 | //Got the Auth token 25 | let tokenValue = respo.body.token; 26 | return tokenValue; 27 | }) 28 | .then((tokenValue) => { 29 | //Booking created 30 | cy.api({ 31 | url: baseURL + "/booking", 32 | method: "POST", 33 | body: { 34 | firstname: "Atulx", 35 | lastname: "Kumarx", 36 | totalprice: 168, 37 | depositpaid: true, 38 | bookingdates: { 39 | checkin: "2018-11-01", 40 | checkout: "2019-12-01", 41 | }, 42 | additionalneeds: "Breakfasto", 43 | }, 44 | headers: { 45 | "content-type": "application/json; charset=utf-8", 46 | "Cache-Control": "no-cache", 47 | followRedirect: false, 48 | Cookie: "token=" + tokenValue, 49 | }, 50 | }).as("BookingCreatedByPostCall"); 51 | 52 | cy.get("@BookingCreatedByPostCall") 53 | .then((respo) => { 54 | expect(respo.status).to.equal(200); 55 | let bookingIdValue = respo.body.bookingid; 56 | return bookingIdValue; 57 | }) 58 | .then(function (bookingIdValue) { 59 | cy.log("value of token is-->" + tokenValue); 60 | //Booking updated 61 | cy.api({ 62 | url: baseURL + "/booking/" + bookingIdValue, 63 | method: "DELETE", 64 | headers: { 65 | "content-type": "application/json; charset=utf-8", 66 | "Cache-Control": "no-cache", 67 | followRedirect: false, 68 | Cookie: "token=" + tokenValue, 69 | }, 70 | }).as("BookingDeletedByDeleteCall"); 71 | 72 | cy.get("@BookingDeletedByDeleteCall") 73 | .then((respo) => { 74 | expect(respo.status).to.equal(201); 75 | }) 76 | .then(() => { 77 | cy.api({ 78 | url: baseURL + "/booking/" + bookingIdValue, 79 | failOnStatusCode: false, 80 | method: "GET", 81 | headers: { 82 | "content-type": "application/json; charset=utf-8", 83 | "Cache-Control": "no-cache", 84 | followRedirect: false, 85 | Cookie: "token=" + tokenValue, 86 | }, 87 | }).as("GetBookingByGetCall"); 88 | 89 | cy.get("@GetBookingByGetCall").then((respo) => { 90 | expect(respo.status).to.equal(404); 91 | expect(respo.body).to.equal("Not Found"); 92 | }); 93 | }); 94 | }); 95 | }); 96 | }); 97 | }); 98 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/misc.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Misc', () => { 4 | beforeEach(() => { 5 | cy.visit('https://example.cypress.io/commands/misc') 6 | }) 7 | 8 | it('.end() - end the command chain', () => { 9 | // https://on.cypress.io/end 10 | 11 | // cy.end is useful when you want to end a chain of commands 12 | // and force Cypress to re-query from the root element 13 | cy.get('.misc-table').within(() => { 14 | // ends the current chain and yields null 15 | cy.contains('Cheryl').click().end() 16 | 17 | // queries the entire table again 18 | cy.contains('Charles').click() 19 | }) 20 | }) 21 | 22 | it('cy.exec() - execute a system command', () => { 23 | // execute a system command. 24 | // so you can take actions necessary for 25 | // your test outside the scope of Cypress. 26 | // https://on.cypress.io/exec 27 | 28 | // we can use Cypress.platform string to 29 | // select appropriate command 30 | // https://on.cypress/io/platform 31 | cy.log(`Platform ${Cypress.platform} architecture ${Cypress.arch}`) 32 | 33 | // on CircleCI Windows build machines we have a failure to run bash shell 34 | // https://github.com/cypress-io/cypress/issues/5169 35 | // so skip some of the tests by passing flag "--env circle=true" 36 | const isCircleOnWindows = Cypress.platform === 'win32' && Cypress.env('circle') 37 | 38 | if (isCircleOnWindows) { 39 | cy.log('Skipping test on CircleCI') 40 | 41 | return 42 | } 43 | 44 | // cy.exec problem on Shippable CI 45 | // https://github.com/cypress-io/cypress/issues/6718 46 | const isShippable = Cypress.platform === 'linux' && Cypress.env('shippable') 47 | 48 | if (isShippable) { 49 | cy.log('Skipping test on ShippableCI') 50 | 51 | return 52 | } 53 | 54 | cy.exec('echo Jane Lane') 55 | .its('stdout').should('contain', 'Jane Lane') 56 | 57 | if (Cypress.platform === 'win32') { 58 | cy.exec(`print ${Cypress.config('configFile')}`) 59 | .its('stderr').should('be.empty') 60 | } else { 61 | cy.exec(`cat ${Cypress.config('configFile')}`) 62 | .its('stderr').should('be.empty') 63 | 64 | cy.exec('pwd') 65 | .its('code').should('eq', 0) 66 | } 67 | }) 68 | 69 | it('cy.focused() - get the DOM element that has focus', () => { 70 | // https://on.cypress.io/focused 71 | cy.get('.misc-form').find('#name').click() 72 | cy.focused().should('have.id', 'name') 73 | 74 | cy.get('.misc-form').find('#description').click() 75 | cy.focused().should('have.id', 'description') 76 | }) 77 | 78 | context('Cypress.Screenshot', function () { 79 | it('cy.screenshot() - take a screenshot', () => { 80 | // https://on.cypress.io/screenshot 81 | cy.screenshot('my-image') 82 | }) 83 | 84 | it('Cypress.Screenshot.defaults() - change default config of screenshots', function () { 85 | Cypress.Screenshot.defaults({ 86 | blackout: ['.foo'], 87 | capture: 'viewport', 88 | clip: { x: 0, y: 0, width: 200, height: 200 }, 89 | scale: false, 90 | disableTimersAndAnimations: true, 91 | screenshotOnRunFailure: true, 92 | onBeforeScreenshot () { }, 93 | onAfterScreenshot () { }, 94 | }) 95 | }) 96 | }) 97 | 98 | it('cy.wrap() - wrap an object', () => { 99 | // https://on.cypress.io/wrap 100 | cy.wrap({ foo: 'bar' }) 101 | .should('have.property', 'foo') 102 | .and('include', 'bar') 103 | }) 104 | }) 105 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/utilities.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Utilities', () => { 4 | beforeEach(() => { 5 | cy.visit('https://example.cypress.io/utilities') 6 | }) 7 | 8 | it('Cypress._ - call a lodash method', () => { 9 | // https://on.cypress.io/_ 10 | cy.request('https://jsonplaceholder.cypress.io/users') 11 | .then((response) => { 12 | let ids = Cypress._.chain(response.body).map('id').take(3).value() 13 | 14 | expect(ids).to.deep.eq([1, 2, 3]) 15 | }) 16 | }) 17 | 18 | it('Cypress.$ - call a jQuery method', () => { 19 | // https://on.cypress.io/$ 20 | let $li = Cypress.$('.utility-jquery li:first') 21 | 22 | cy.wrap($li) 23 | .should('not.have.class', 'active') 24 | .click() 25 | .should('have.class', 'active') 26 | }) 27 | 28 | it('Cypress.Blob - blob utilities and base64 string conversion', () => { 29 | // https://on.cypress.io/blob 30 | cy.get('.utility-blob').then(($div) => { 31 | // https://github.com/nolanlawson/blob-util#imgSrcToDataURL 32 | // get the dataUrl string for the javascript-logo 33 | return Cypress.Blob.imgSrcToDataURL('https://example.cypress.io/assets/img/javascript-logo.png', undefined, 'anonymous') 34 | .then((dataUrl) => { 35 | // create an element and set its src to the dataUrl 36 | let img = Cypress.$('', { src: dataUrl }) 37 | 38 | // need to explicitly return cy here since we are initially returning 39 | // the Cypress.Blob.imgSrcToDataURL promise to our test 40 | // append the image 41 | $div.append(img) 42 | 43 | cy.get('.utility-blob img').click() 44 | .should('have.attr', 'src', dataUrl) 45 | }) 46 | }) 47 | }) 48 | 49 | it('Cypress.minimatch - test out glob patterns against strings', () => { 50 | // https://on.cypress.io/minimatch 51 | let matching = Cypress.minimatch('/users/1/comments', '/users/*/comments', { 52 | matchBase: true, 53 | }) 54 | 55 | expect(matching, 'matching wildcard').to.be.true 56 | 57 | matching = Cypress.minimatch('/users/1/comments/2', '/users/*/comments', { 58 | matchBase: true, 59 | }) 60 | 61 | expect(matching, 'comments').to.be.false 62 | 63 | // ** matches against all downstream path segments 64 | matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/**', { 65 | matchBase: true, 66 | }) 67 | 68 | expect(matching, 'comments').to.be.true 69 | 70 | // whereas * matches only the next path segment 71 | 72 | matching = Cypress.minimatch('/foo/bar/baz/123/quux?a=b&c=2', '/foo/*', { 73 | matchBase: false, 74 | }) 75 | 76 | expect(matching, 'comments').to.be.false 77 | }) 78 | 79 | it('Cypress.Promise - instantiate a bluebird promise', () => { 80 | // https://on.cypress.io/promise 81 | let waited = false 82 | 83 | /** 84 | * @return Bluebird 85 | */ 86 | function waitOneSecond () { 87 | // return a promise that resolves after 1 second 88 | return new Cypress.Promise((resolve, reject) => { 89 | setTimeout(() => { 90 | // set waited to true 91 | waited = true 92 | 93 | // resolve with 'foo' string 94 | resolve('foo') 95 | }, 1000) 96 | }) 97 | } 98 | 99 | cy.then(() => { 100 | // return a promise to cy.then() that 101 | // is awaited until it resolves 102 | return waitOneSecond().then((str) => { 103 | expect(str).to.eq('foo') 104 | expect(waited).to.be.true 105 | }) 106 | }) 107 | }) 108 | }) 109 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/querying.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Querying', () => { 4 | beforeEach(() => { 5 | cy.visit('https://example.cypress.io/commands/querying') 6 | }) 7 | 8 | // The most commonly used query is 'cy.get()', you can 9 | // think of this like the '$' in jQuery 10 | 11 | it('cy.get() - query DOM elements', () => { 12 | // https://on.cypress.io/get 13 | 14 | cy.get('#query-btn').should('contain', 'Button') 15 | 16 | cy.get('.query-btn').should('contain', 'Button') 17 | 18 | cy.get('#querying .well>button:first').should('contain', 'Button') 19 | // ↲ 20 | // Use CSS selectors just like jQuery 21 | 22 | cy.get('[data-test-id="test-example"]').should('have.class', 'example') 23 | 24 | // 'cy.get()' yields jQuery object, you can get its attribute 25 | // by invoking `.attr()` method 26 | cy.get('[data-test-id="test-example"]') 27 | .invoke('attr', 'data-test-id') 28 | .should('equal', 'test-example') 29 | 30 | // or you can get element's CSS property 31 | cy.get('[data-test-id="test-example"]') 32 | .invoke('css', 'position') 33 | .should('equal', 'static') 34 | 35 | // or use assertions directly during 'cy.get()' 36 | // https://on.cypress.io/assertions 37 | cy.get('[data-test-id="test-example"]') 38 | .should('have.attr', 'data-test-id', 'test-example') 39 | .and('have.css', 'position', 'static') 40 | }) 41 | 42 | it('cy.contains() - query DOM elements with matching content', () => { 43 | // https://on.cypress.io/contains 44 | cy.get('.query-list') 45 | .contains('bananas') 46 | .should('have.class', 'third') 47 | 48 | // we can pass a regexp to `.contains()` 49 | cy.get('.query-list') 50 | .contains(/^b\w+/) 51 | .should('have.class', 'third') 52 | 53 | cy.get('.query-list') 54 | .contains('apples') 55 | .should('have.class', 'first') 56 | 57 | // passing a selector to contains will 58 | // yield the selector containing the text 59 | cy.get('#querying') 60 | .contains('ul', 'oranges') 61 | .should('have.class', 'query-list') 62 | 63 | cy.get('.query-button') 64 | .contains('Save Form') 65 | .should('have.class', 'btn') 66 | }) 67 | 68 | it('.within() - query DOM elements within a specific element', () => { 69 | // https://on.cypress.io/within 70 | cy.get('.query-form').within(() => { 71 | cy.get('input:first').should('have.attr', 'placeholder', 'Email') 72 | cy.get('input:last').should('have.attr', 'placeholder', 'Password') 73 | }) 74 | }) 75 | 76 | it('cy.root() - query the root DOM element', () => { 77 | // https://on.cypress.io/root 78 | 79 | // By default, root is the document 80 | cy.root().should('match', 'html') 81 | 82 | cy.get('.query-ul').within(() => { 83 | // In this within, the root is now the ul DOM element 84 | cy.root().should('have.class', 'query-ul') 85 | }) 86 | }) 87 | 88 | it('best practices - selecting elements', () => { 89 | // https://on.cypress.io/best-practices#Selecting-Elements 90 | cy.get('[data-cy=best-practices-selecting-elements]').within(() => { 91 | // Worst - too generic, no context 92 | cy.get('button').click() 93 | 94 | // Bad. Coupled to styling. Highly subject to change. 95 | cy.get('.btn.btn-large').click() 96 | 97 | // Average. Coupled to the `name` attribute which has HTML semantics. 98 | cy.get('[name=submission]').click() 99 | 100 | // Better. But still coupled to styling or JS event listeners. 101 | cy.get('#main').click() 102 | 103 | // Slightly better. Uses an ID but also ensures the element 104 | // has an ARIA role attribute 105 | cy.get('#main[role=button]').click() 106 | 107 | // Much better. But still coupled to text content that may change. 108 | cy.contains('Submit').click() 109 | 110 | // Best. Insulated from all changes. 111 | cy.get('[data-cy=submit]').click() 112 | }) 113 | }) 114 | }) 115 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/traversal.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Traversal', () => { 4 | beforeEach(() => { 5 | cy.visit('https://example.cypress.io/commands/traversal') 6 | }) 7 | 8 | it('.children() - get child DOM elements', () => { 9 | // https://on.cypress.io/children 10 | cy.get('.traversal-breadcrumb') 11 | .children('.active') 12 | .should('contain', 'Data') 13 | }) 14 | 15 | it('.closest() - get closest ancestor DOM element', () => { 16 | // https://on.cypress.io/closest 17 | cy.get('.traversal-badge') 18 | .closest('ul') 19 | .should('have.class', 'list-group') 20 | }) 21 | 22 | it('.eq() - get a DOM element at a specific index', () => { 23 | // https://on.cypress.io/eq 24 | cy.get('.traversal-list>li') 25 | .eq(1).should('contain', 'siamese') 26 | }) 27 | 28 | it('.filter() - get DOM elements that match the selector', () => { 29 | // https://on.cypress.io/filter 30 | cy.get('.traversal-nav>li') 31 | .filter('.active').should('contain', 'About') 32 | }) 33 | 34 | it('.find() - get descendant DOM elements of the selector', () => { 35 | // https://on.cypress.io/find 36 | cy.get('.traversal-pagination') 37 | .find('li').find('a') 38 | .should('have.length', 7) 39 | }) 40 | 41 | it('.first() - get first DOM element', () => { 42 | // https://on.cypress.io/first 43 | cy.get('.traversal-table td') 44 | .first().should('contain', '1') 45 | }) 46 | 47 | it('.last() - get last DOM element', () => { 48 | // https://on.cypress.io/last 49 | cy.get('.traversal-buttons .btn') 50 | .last().should('contain', 'Submit') 51 | }) 52 | 53 | it('.next() - get next sibling DOM element', () => { 54 | // https://on.cypress.io/next 55 | cy.get('.traversal-ul') 56 | .contains('apples').next().should('contain', 'oranges') 57 | }) 58 | 59 | it('.nextAll() - get all next sibling DOM elements', () => { 60 | // https://on.cypress.io/nextall 61 | cy.get('.traversal-next-all') 62 | .contains('oranges') 63 | .nextAll().should('have.length', 3) 64 | }) 65 | 66 | it('.nextUntil() - get next sibling DOM elements until next el', () => { 67 | // https://on.cypress.io/nextuntil 68 | cy.get('#veggies') 69 | .nextUntil('#nuts').should('have.length', 3) 70 | }) 71 | 72 | it('.not() - remove DOM elements from set of DOM elements', () => { 73 | // https://on.cypress.io/not 74 | cy.get('.traversal-disabled .btn') 75 | .not('[disabled]').should('not.contain', 'Disabled') 76 | }) 77 | 78 | it('.parent() - get parent DOM element from DOM elements', () => { 79 | // https://on.cypress.io/parent 80 | cy.get('.traversal-mark') 81 | .parent().should('contain', 'Morbi leo risus') 82 | }) 83 | 84 | it('.parents() - get parent DOM elements from DOM elements', () => { 85 | // https://on.cypress.io/parents 86 | cy.get('.traversal-cite') 87 | .parents().should('match', 'blockquote') 88 | }) 89 | 90 | it('.parentsUntil() - get parent DOM elements from DOM elements until el', () => { 91 | // https://on.cypress.io/parentsuntil 92 | cy.get('.clothes-nav') 93 | .find('.active') 94 | .parentsUntil('.clothes-nav') 95 | .should('have.length', 2) 96 | }) 97 | 98 | it('.prev() - get previous sibling DOM element', () => { 99 | // https://on.cypress.io/prev 100 | cy.get('.birds').find('.active') 101 | .prev().should('contain', 'Lorikeets') 102 | }) 103 | 104 | it('.prevAll() - get all previous sibling DOM elements', () => { 105 | // https://on.cypress.io/prevall 106 | cy.get('.fruits-list').find('.third') 107 | .prevAll().should('have.length', 2) 108 | }) 109 | 110 | it('.prevUntil() - get all previous sibling DOM elements until el', () => { 111 | // https://on.cypress.io/prevuntil 112 | cy.get('.foods-list').find('#nuts') 113 | .prevUntil('#veggies').should('have.length', 3) 114 | }) 115 | 116 | it('.siblings() - get all sibling DOM elements', () => { 117 | // https://on.cypress.io/siblings 118 | cy.get('.traversal-pills .active') 119 | .siblings().should('have.length', 2) 120 | }) 121 | }) 122 | -------------------------------------------------------------------------------- /cypress/e2e/3-advanced-api-examples/Post-Post-Put-Get.cy.js: -------------------------------------------------------------------------------- 1 | //https://restful-booker.herokuapp.com/apidoc/index.html 2 | 3 | describe("PUT", () => { 4 | const baseURL = "https://restful-booker.herokuapp.com"; 5 | it("Post-Post-Put-Get", () => { 6 | //Auth Token-Post 7 | cy.api({ 8 | url: baseURL + "/auth", 9 | method: "POST", 10 | body: { 11 | username: "admin", 12 | password: "password123", 13 | }, 14 | headers: { 15 | "content-type": "application/json; charset=utf-8", 16 | "Cache-Control": "no-cache", 17 | followRedirect: false, // turn off following redirects 18 | }, 19 | }).as("GetAuthTokenByPostCall"); 20 | 21 | cy.get("@GetAuthTokenByPostCall") 22 | .then(function (respo) { 23 | expect(respo.status).to.equal(200); 24 | //Got the Auth token 25 | let tokenValue = respo.body.token; 26 | return tokenValue; 27 | }) 28 | .then((tokenValue) => { 29 | //Booking created 30 | cy.api({ 31 | url: baseURL + "/booking", 32 | method: "POST", 33 | body: { 34 | firstname: "Atulx", 35 | lastname: "Kumarx", 36 | totalprice: 168, 37 | depositpaid: true, 38 | bookingdates: { 39 | checkin: "2018-11-01", 40 | checkout: "2019-12-01", 41 | }, 42 | additionalneeds: "Breakfasto", 43 | }, 44 | headers: { 45 | "content-type": "application/json; charset=utf-8", 46 | "Cache-Control": "no-cache", 47 | followRedirect: false, // turn off following redirects 48 | Cookie: "token=" + tokenValue, 49 | }, 50 | }).as("BookingCreatedByPostCall"); 51 | 52 | cy.get("@BookingCreatedByPostCall") 53 | .then((respo) => { 54 | expect(respo.status).to.equal(200); 55 | let bookingIdValue = respo.body.bookingid; 56 | return bookingIdValue; 57 | }) 58 | .then(function (bookingIdValue) { 59 | cy.log("value of token is-->" + tokenValue); 60 | //Booking updated 61 | cy.api({ 62 | url: baseURL + "/booking/" + bookingIdValue, 63 | method: "PUT", 64 | body: { 65 | firstname: "Lucky", 66 | lastname: "Bhardwaj", 67 | totalprice: 21218, 68 | depositpaid: false, 69 | bookingdates: { 70 | checkin: "2018-01-01", 71 | checkout: "2019-02-01", 72 | }, 73 | additionalneeds: "dosa, chai, mocha", 74 | }, 75 | headers: { 76 | "content-type": "application/json; charset=utf-8", 77 | "Cache-Control": "no-cache", 78 | followRedirect: false, // turn off following redirects 79 | Cookie: "token=" + tokenValue, 80 | }, 81 | }).as("BookingUpdatedByPutCall"); 82 | 83 | cy.get("@BookingUpdatedByPutCall") 84 | .then((respo) => { 85 | expect(respo.status).to.equal(200); 86 | }) 87 | .then(() => { 88 | cy.api({ 89 | url: baseURL + "/booking/" + bookingIdValue, 90 | method: "GET", 91 | headers: { 92 | "content-type": "application/json; charset=utf-8", 93 | "Cache-Control": "no-cache", 94 | followRedirect: false, // turn off following redirects 95 | Cookie: "token=" + tokenValue, 96 | }, 97 | }).as("GetBookingByGetCall"); 98 | 99 | cy.get("@GetBookingByGetCall").then((respo) => { 100 | expect(respo.status).to.equal(200); 101 | 102 | expect(respo.body).to.have.property("firstname", "Lucky"); 103 | expect(respo.body).to.have.property("lastname", "Bhardwaj"); 104 | expect(respo.body).to.have.property("depositpaid", false); 105 | expect(respo.body).to.have.property( 106 | "additionalneeds", 107 | "dosa, chai, mocha" 108 | ); 109 | }); 110 | }); 111 | }); 112 | }); 113 | }); 114 | }); 115 | -------------------------------------------------------------------------------- /cypress/e2e/3-advanced-api-examples/Post.cy.js: -------------------------------------------------------------------------------- 1 | const dataJson = require("../../fixtures/post.json"); 2 | 3 | describe("Post", () => { 4 | const baseURL = "https://jsonplaceholder.typicode.com"; 5 | 6 | it("CreatePost + fixtures Json", () => { 7 | cy.request({ 8 | method: "POST", 9 | url: baseURL + "/posts", 10 | body: { 11 | title: dataJson.title, 12 | body: dataJson.body, 13 | userID: dataJson.userID, 14 | }, 15 | headers: { 16 | "content-type": "application/json; charset=utf-8", 17 | "Cache-Control": "no-cache", 18 | followRedirect: false, // turn off following redirects 19 | }, 20 | }).as("CreatePostJSON"); 21 | 22 | cy.get("@CreatePostJSON").then((response) => { 23 | cy.log(JSON.stringify(response)); 24 | //response: status 25 | expect(response.status).to.equal(201); 26 | expect(response.status).to.eq(201); 27 | 28 | //response body: key only 29 | expect(response.body).to.have.property("userID"); 30 | expect(response.body).to.have.property("id"); 31 | expect(response.body).to.have.property("title"); 32 | expect(response.body).to.have.property("body"); 33 | expect(response).to.have.property("headers"); 34 | expect(response).to.have.property("duration"); 35 | 36 | //response body: key & value 37 | expect(response.body).to.have.property("userID", "168"); 38 | expect(response.body).to.have.property("title", "Luckyily"); 39 | expect(response.body).has.property("body", "testers body"); 40 | 41 | //response headers 42 | expect(response).to.include.keys("headers", "duration"); 43 | expect(response.headers).to.have.property( 44 | "content-type", 45 | "application/json; charset=utf-8" 46 | ); 47 | expect(response.headers).property("content-type").to.be.a("string"); 48 | expect(response.headers) 49 | .property("X-Ratelimit-Remaining".toLowerCase()) 50 | .to.be.a("string"); 51 | 52 | //response body- Data Types 53 | expect(response.body).property("userID").to.be.a("string"); 54 | expect(response.body).property("title").to.be.a("string"); 55 | expect(response.body).property("body").to.be.a("string"); 56 | expect(response.body).property("id").to.be.a("number"); 57 | }); 58 | }); 59 | 60 | it("CreatePost + fixtures Json", () => { 61 | cy.fixture("post.json").then(function (payload) { 62 | cy.request({ 63 | method: "POST", 64 | url: baseURL + "/posts", 65 | body: { 66 | title: payload.title, 67 | body: payload.body, 68 | userID: payload.userID, 69 | }, 70 | headers: { 71 | "content-type": "application/json; charset=utf-8", 72 | "Cache-Control": "no-cache", 73 | followRedirect: false, // turn off following redirects 74 | }, 75 | }).as("CreatePostJSON"); 76 | 77 | cy.get("@CreatePostJSON").then((response) => { 78 | cy.log(JSON.stringify(response)); 79 | //response: status 80 | expect(response.status).to.equal(201); 81 | expect(response.status).to.eq(201); 82 | 83 | //response body: key only 84 | expect(response.body).to.have.property("userID"); 85 | expect(response.body).to.have.property("id"); 86 | expect(response.body).to.have.property("title"); 87 | expect(response.body).to.have.property("body"); 88 | expect(response).to.have.property("headers"); 89 | expect(response).to.have.property("duration"); 90 | 91 | //response body: key & value 92 | expect(response.body).to.have.property("userID", payload.userID); 93 | expect(response.body).to.have.property("title", payload.title); 94 | expect(response.body).has.property("body", payload.body); 95 | 96 | //response headers 97 | expect(response).to.include.keys("headers", "duration"); 98 | expect(response.headers).to.have.property( 99 | "content-type", 100 | "application/json; charset=utf-8" 101 | ); 102 | expect(response.headers).property("content-type").to.be.a("string"); 103 | expect(response.headers) 104 | .property("X-Ratelimit-Remaining".toLowerCase()) 105 | .to.be.a("string"); 106 | 107 | //response body- Data Types 108 | expect(response.body).property("userID").to.be.a("string"); 109 | expect(response.body).property("title").to.be.a("string"); 110 | expect(response.body).property("body").to.be.a("string"); 111 | expect(response.body).property("id").to.be.a("number"); 112 | }); 113 | }); 114 | }); 115 | }); 116 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Cypress](https://www.cypress.io/) 2 | 3 | > Cypress API Testing Framework using JavaScript 4 | 5 | 6 | exemplo imagem 7 | 8 | 9 | > Test Result 10 | 11 | CyCapture 12 | 13 | ## Links 14 | 15 | - [Cypress code](https://github.com/cypress-io/cypress) 16 | - [Cypress recipes](https://github.com/cypress-io/cypress-example-recipes) - Various recipes for testing common scenarios with Cypress. 17 | - [Effective React Tests with Cypress (2020)](https://glebbahmutov.com/blog/effective-react-tests/) 18 | - [Tricks to make cypress tests run faster (2020)](https://twitter.com/oleg008/status/1314114975783362561) 19 | - [Thank you, Dr. Bahmutov for Cypress (2020)](https://changelog.com/jsparty/148) - Gleb Bahmutov, PhD joins the show for a fun conversation around end-to-end testing. 20 | - [cypress-routines](https://github.com/maximilianschmitt/cypress-routines) - Easily write scalable Node.js setup code for Cypress. ([Article](https://maxschmitt.me/posts/cypress-routines/)) 21 | - [Cypress Testing Library](https://github.com/testing-library/cypress-testing-library) - Simple and complete custom Cypress commands and utilities that encourage good testing practices. 22 | - [Keep your Documentation updated with Cypress and Github Actions (2020)](https://emasuriano.com/blog/keep-your-documentation-updated-with-cypress-and-github-actions) 23 | - [Cypress Recorder](https://github.com/KabaLabs/Cypress-Recorder) - Chrome developer tool that records user interaction within a web application and generates Cypress scripts to allow the developer to replicate that particular session. 24 | - [cypress-wait-until](https://github.com/NoriSte/cypress-wait-until) - Add the Cypress waiting power to virtually everything. 25 | - [Mastering UI Testing with Cypress](https://github.com/NoriSte/working-software-mastering-ui-testing) 26 | - [Cypress Real Events](https://github.com/dmtrKovalenko/cypress-real-events) - Fire native system events from Cypress. 27 | - [HN: Cypress (2020)](https://news.ycombinator.com/item?id=25381242) 28 | - [Cypress Image Snapshot](https://github.com/jaredpalmer/cypress-image-snapshot) - Catch visual regressions in Cypress. 29 | - [sorry-cypress](https://github.com/sorry-cypress/sorry-cypress) - Open-source, on-premise, self-hosted alternative to Cypress dashboard. ([Docs](https://sorry-cypress.dev/)) 30 | - [Knapsack Pro for Cypress.io](https://github.com/KnapsackPro/knapsack-pro-cypress) - Runs your E2E tests with Cypress.io test runner and does dynamic tests allocation across parallel CI nodes using KnapsackPro.com Queue Mode to provide the fastest CI build time (optimal test suite timing).. 31 | - [cypress-graphql-mock](https://github.com/tgriesser/cypress-graphql-mock) - Adds commands for executing a mocked GraphQL server using only the client. 32 | - [Backend Code Coverage from Cypress API tests (2021)](https://glebbahmutov.com/blog/backend-coverage/) 33 | - [Gleb Bahmutov's articles on Cypress](https://glebbahmutov.com/blog/tags/cypress/) 34 | - [CI and End to End Testing: Cypress Percy CircleCI (2021)](https://medium.com/diffgram/implementing-a-ci-system-with-e2e-testing-using-cypress-percy-and-circleci-246b50be466c) 35 | - [cypress-react-selector](https://github.com/abhinaba-ghosh/cypress-react-selector) - Cypress plugin to locate react elements by component, props and state. 36 | - [Cypress vs Selenium vs Playwright vs Puppeteer speed comparison (2021)](https://blog.checklyhq.com/cypress-vs-selenium-vs-playwright-vs-puppeteer-speed-comparison/) 37 | - [cypress-websocket-testing](https://github.com/lensesio/cypress-websocket-testing) - Test your WebSocket endpoints using Cypress. 38 | - [Improve your custom command logs in Cypress (2021)](https://filiphric.com/improve-your-custom-command-logs-in-cypress) 39 | - [Cypress Fail Fast](https://github.com/javierbrea/cypress-fail-fast) - Cypress plugin to skip tests on first failure. 40 | - [Visual testing with Cypress and Percy](https://github.com/percy/percy-cypress) 41 | - [Cypress Plugin Snapshots](https://github.com/meinaart/cypress-plugin-snapshots) 42 | - [A Practical Guide to Intercepting Network Requests in Cypress](https://egghead.io/blog/intercepting-network-requests-in-cypress) 43 | - [How To Quickly Add Cypress To Your Next.js App (2021)](https://dev.to/ashconnolly/how-to-quickly-add-cypress-to-your-next-js-app-2oc6) 44 | - [cypress-axe](https://github.com/component-driven/cypress-axe) - Test accessibility with axe-core in Cypress. 45 | - [Cypress Visual Regression](https://github.com/mjhea0/cypress-visual-regression) - Module for adding visual regression testing to Cypress. 46 | - [Cypress GitHub Action](https://github.com/cypress-io/github-action) 47 | - [Cypress oAuth2.0](https://docs.cypress.io/guides/end-to-end-testing/google-authentication#Custom-Command-for-Google-Authentication) 48 | - [Cypress Vs WebDriver.io](https://www.browserstack.com/guide/cypress-vs-webdriverio) 49 | 50 | -------------------------------------------------------------------------------- /cypress/e2e/3-advanced-api-examples/Get.cy.js: -------------------------------------------------------------------------------- 1 | const baseURL = "https://jsonplaceholder.typicode.com"; 2 | 3 | describe("Get Call", () => { 4 | it("GetPostById", () => { 5 | cy.request(baseURL + "/posts/1").as("GetPostById"); 6 | 7 | cy.get("@GetPostById").then((response) => { 8 | cy.log(JSON.stringify(response)); 9 | //response: status 10 | expect(response.status).to.equal(200); 11 | expect(response.status).to.eq(200); 12 | 13 | //response body: key only 14 | expect(response.body).to.have.property("userId"); 15 | expect(response.body).to.have.property("id"); 16 | expect(response.body).to.have.property("title"); 17 | expect(response.body).to.have.property("body"); 18 | expect(response).to.have.property("headers"); 19 | expect(response).to.have.property("duration"); 20 | 21 | //response body: key & value 22 | expect(response.body).to.have.property("userId", 1); 23 | expect(response.body).to.have.property("id", 1); 24 | expect(response.body).to.have.property("title"); 25 | expect(response.body).to.have.property("body"); 26 | 27 | //response headers 28 | expect(response).to.include.keys("headers", "duration"); 29 | expect(response.headers).to.have.property( 30 | "content-type", 31 | "application/json; charset=utf-8" 32 | ); 33 | expect(response.headers).property("content-type").to.be.a("string"); 34 | expect(response.headers) 35 | .property("X-Ratelimit-Remaining".toLowerCase()) 36 | .to.be.a("string"); 37 | 38 | //response body- Data Types 39 | expect(response.body).property("userId").to.be.a("number"); 40 | expect(response.body).property("id").to.be.a("number"); 41 | expect(response.body).property("id").to.be.a("number"); 42 | expect(response.body).property("id").to.be.a("number"); 43 | 44 | //response body- key & value 45 | expect(response.body).property("title").to.contain("sunt aut facere"); 46 | expect(response.body.title).contains("sunt aut facere"); 47 | expect(response).property("body").to.contain({ 48 | title: 49 | "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", 50 | body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto", 51 | }); 52 | }); 53 | }); 54 | it("GetPostById + options object req", () => { 55 | // options (Object) : Pass in an options object to change the default behavior of cy.request() 56 | cy.request({ 57 | method: "GET", 58 | url: baseURL + "/posts/1", 59 | headers: { 60 | "content-type": "application/json; charset=utf-8", 61 | "Cache-Control": "no-cache", 62 | followRedirect: false, // turn off following redirects 63 | }, 64 | }).as("GetPostByIdJSON"); 65 | 66 | cy.get("@GetPostByIdJSON").then((response) => { 67 | cy.log(JSON.stringify(response)); 68 | //response: status 69 | expect(response.status).to.equal(200); 70 | expect(response.status).to.eq(200); 71 | 72 | //response body: key only 73 | expect(response.body).to.have.property("userId"); 74 | expect(response.body).to.have.property("id"); 75 | expect(response.body).to.have.property("title"); 76 | expect(response.body).to.have.property("body"); 77 | expect(response).to.have.property("headers"); 78 | expect(response).to.have.property("duration"); 79 | 80 | //response body: key & value 81 | expect(response.body).to.have.property("userId", 1); 82 | expect(response.body).to.have.property("id", 1); 83 | expect(response.body).to.have.property("title"); 84 | expect(response.body).to.have.property("body"); 85 | 86 | //response headers 87 | expect(response).to.include.keys("headers", "duration"); 88 | expect(response.headers).to.have.property( 89 | "content-type", 90 | "application/json; charset=utf-8" 91 | ); 92 | expect(response.headers).property("content-type").to.be.a("string"); 93 | expect(response.headers) 94 | .property("X-Ratelimit-Remaining".toLowerCase()) 95 | .to.be.a("string"); 96 | 97 | //response body- Data Types 98 | expect(response.body).property("userId").to.be.a("number"); 99 | expect(response.body).property("id").to.be.a("number"); 100 | expect(response.body).property("id").to.be.a("number"); 101 | expect(response.body).property("id").to.be.a("number"); 102 | 103 | //response body- key & value 104 | expect(response.body).property("title").to.contain("sunt aut facere"); 105 | expect(response.body.title).contains("sunt aut facere"); 106 | expect(response).property("body").to.contain({ 107 | title: 108 | "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", 109 | body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto", 110 | }); 111 | }); 112 | }); 113 | }); 114 | -------------------------------------------------------------------------------- /cypress/e2e/3-advanced-api-examples/GetWithChain.cy.js: -------------------------------------------------------------------------------- 1 | const baseURL = "https://jsonplaceholder.typicode.com"; 2 | 3 | describe("Get Call", () => { 4 | it("GetPostById", () => { 5 | cy.request(baseURL + "/posts/1").as("GetPostById"); 6 | 7 | cy.get("@GetPostById").then((response) => { 8 | cy.log(JSON.stringify(response)); 9 | //response: status 10 | expect(response.status).to.equal(200); 11 | expect(response.status).to.eq(200); 12 | 13 | //response body: key only 14 | expect(response.body).to.have.property("userId"); 15 | expect(response.body).to.have.property("id"); 16 | expect(response.body).to.have.property("title"); 17 | expect(response.body).to.have.property("body"); 18 | expect(response).to.have.property("headers"); 19 | expect(response).to.have.property("duration"); 20 | 21 | //response body: key & value 22 | expect(response.body).to.have.property("userId", 1); 23 | expect(response.body).to.have.property("id", 1); 24 | expect(response.body).to.have.property("title"); 25 | expect(response.body).to.have.property("body"); 26 | 27 | //response headers 28 | expect(response).to.include.keys("headers", "duration"); 29 | expect(response.headers).to.have.property( 30 | "content-type", 31 | "application/json; charset=utf-8" 32 | ); 33 | expect(response.headers).property("content-type").to.be.a("string"); 34 | expect(response.headers) 35 | .property("X-Ratelimit-Remaining".toLowerCase()) 36 | .to.be.a("string"); 37 | 38 | //response body- Data Types 39 | expect(response.body).property("userId").to.be.a("number"); 40 | expect(response.body).property("id").to.be.a("number"); 41 | expect(response.body).property("id").to.be.a("number"); 42 | expect(response.body).property("id").to.be.a("number"); 43 | 44 | //response body- key & value 45 | expect(response.body).property("title").to.contain("sunt aut facere"); 46 | expect(response.body.title).contains("sunt aut facere"); 47 | expect(response).property("body").to.contain({ 48 | title: 49 | "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", 50 | body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto", 51 | }); 52 | }); 53 | }); 54 | it("GetPostById + options object req", () => { 55 | // options (Object) : Pass in an options object to change the default behavior of cy.request() 56 | cy.request({ 57 | method: "GET", 58 | url: baseURL + "/posts/1", 59 | headers: { 60 | "content-type": "application/json; charset=utf-8", 61 | "Cache-Control": "no-cache", 62 | followRedirect: false, // turn off following redirects 63 | }, 64 | }).as("GetPostByIdJSON"); 65 | 66 | cy.get("@GetPostByIdJSON").then((response) => { 67 | cy.log(JSON.stringify(response)); 68 | //response: status 69 | expect(response.status).to.equal(200); 70 | expect(response.status).to.eq(200); 71 | 72 | //response body: key only 73 | expect(response.body).to.have.property("userId"); 74 | expect(response.body).to.have.property("id"); 75 | expect(response.body).to.have.property("title"); 76 | expect(response.body).to.have.property("body"); 77 | expect(response).to.have.property("headers"); 78 | expect(response).to.have.property("duration"); 79 | 80 | //response body: key & value 81 | expect(response.body).to.have.property("userId", 1); 82 | expect(response.body).to.have.property("id", 1); 83 | expect(response.body).to.have.property("title"); 84 | expect(response.body).to.have.property("body"); 85 | 86 | //response headers 87 | expect(response).to.include.keys("headers", "duration"); 88 | expect(response.headers).to.have.property( 89 | "content-type", 90 | "application/json; charset=utf-8" 91 | ); 92 | expect(response.headers).property("content-type").to.be.a("string"); 93 | expect(response.headers) 94 | .property("X-Ratelimit-Remaining".toLowerCase()) 95 | .to.be.a("string"); 96 | 97 | //response body- Data Types 98 | expect(response.body).property("userId").to.be.a("number"); 99 | expect(response.body).property("id").to.be.a("number"); 100 | expect(response.body).property("id").to.be.a("number"); 101 | expect(response.body).property("id").to.be.a("number"); 102 | 103 | //response body- key & value 104 | expect(response.body).property("title").to.contain("sunt aut facere"); 105 | expect(response.body.title).contains("sunt aut facere"); 106 | expect(response).property("body").to.contain({ 107 | title: 108 | "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", 109 | body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto", 110 | }); 111 | }); 112 | }); 113 | }); 114 | -------------------------------------------------------------------------------- /cypress/e2e/2-advanced-examples/assertions.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | context('Assertions', () => { 4 | beforeEach(() => { 5 | cy.visit('https://example.cypress.io/commands/assertions') 6 | }) 7 | 8 | describe('Implicit Assertions', () => { 9 | it('.should() - make an assertion about the current subject', () => { 10 | // https://on.cypress.io/should 11 | cy.get('.assertion-table') 12 | .find('tbody tr:last') 13 | .should('have.class', 'success') 14 | .find('td') 15 | .first() 16 | // checking the text of the element in various ways 17 | .should('have.text', 'Column content') 18 | .should('contain', 'Column content') 19 | .should('have.html', 'Column content') 20 | // chai-jquery uses "is()" to check if element matches selector 21 | .should('match', 'td') 22 | // to match text content against a regular expression 23 | // first need to invoke jQuery method text() 24 | // and then match using regular expression 25 | .invoke('text') 26 | .should('match', /column content/i) 27 | 28 | // a better way to check element's text content against a regular expression 29 | // is to use "cy.contains" 30 | // https://on.cypress.io/contains 31 | cy.get('.assertion-table') 32 | .find('tbody tr:last') 33 | // finds first element with text content matching regular expression 34 | .contains('td', /column content/i) 35 | .should('be.visible') 36 | 37 | // for more information about asserting element's text 38 | // see https://on.cypress.io/using-cypress-faq#How-do-I-get-an-element’s-text-contents 39 | }) 40 | 41 | it('.and() - chain multiple assertions together', () => { 42 | // https://on.cypress.io/and 43 | cy.get('.assertions-link') 44 | .should('have.class', 'active') 45 | .and('have.attr', 'href') 46 | .and('include', 'cypress.io') 47 | }) 48 | }) 49 | 50 | describe('Explicit Assertions', () => { 51 | // https://on.cypress.io/assertions 52 | it('expect - make an assertion about a specified subject', () => { 53 | // We can use Chai's BDD style assertions 54 | expect(true).to.be.true 55 | const o = { foo: 'bar' } 56 | 57 | expect(o).to.equal(o) 58 | expect(o).to.deep.equal({ foo: 'bar' }) 59 | // matching text using regular expression 60 | expect('FooBar').to.match(/bar$/i) 61 | }) 62 | 63 | it('pass your own callback function to should()', () => { 64 | // Pass a function to should that can have any number 65 | // of explicit assertions within it. 66 | // The ".should(cb)" function will be retried 67 | // automatically until it passes all your explicit assertions or times out. 68 | cy.get('.assertions-p') 69 | .find('p') 70 | .should(($p) => { 71 | // https://on.cypress.io/$ 72 | // return an array of texts from all of the p's 73 | const texts = $p.map((i, el) => Cypress.$(el).text()) 74 | 75 | // jquery map returns jquery object 76 | // and .get() convert this to simple array 77 | const paragraphs = texts.get() 78 | 79 | // array should have length of 3 80 | expect(paragraphs, 'has 3 paragraphs').to.have.length(3) 81 | 82 | // use second argument to expect(...) to provide clear 83 | // message with each assertion 84 | expect(paragraphs, 'has expected text in each paragraph').to.deep.eq([ 85 | 'Some text from first p', 86 | 'More text from second p', 87 | 'And even more text from third p', 88 | ]) 89 | }) 90 | }) 91 | 92 | it('finds element by class name regex', () => { 93 | cy.get('.docs-header') 94 | .find('div') 95 | // .should(cb) callback function will be retried 96 | .should(($div) => { 97 | expect($div).to.have.length(1) 98 | 99 | const className = $div[0].className 100 | 101 | expect(className).to.match(/heading-/) 102 | }) 103 | // .then(cb) callback is not retried, 104 | // it either passes or fails 105 | .then(($div) => { 106 | expect($div, 'text content').to.have.text('Introduction') 107 | }) 108 | }) 109 | 110 | it('can throw any error', () => { 111 | cy.get('.docs-header') 112 | .find('div') 113 | .should(($div) => { 114 | if ($div.length !== 1) { 115 | // you can throw your own errors 116 | throw new Error('Did not find 1 element') 117 | } 118 | 119 | const className = $div[0].className 120 | 121 | if (!className.match(/heading-/)) { 122 | throw new Error(`Could not find class "heading-" in ${className}`) 123 | } 124 | }) 125 | }) 126 | 127 | it('matches unknown text between two elements', () => { 128 | /** 129 | * Text from the first element. 130 | * @type {string} 131 | */ 132 | let text 133 | 134 | /** 135 | * Normalizes passed text, 136 | * useful before comparing text with spaces and different capitalization. 137 | * @param {string} s Text to normalize 138 | */ 139 | const normalizeText = (s) => s.replace(/\s/g, '').toLowerCase() 140 | 141 | cy.get('.two-elements') 142 | .find('.first') 143 | .then(($first) => { 144 | // save text from the first element 145 | text = normalizeText($first.text()) 146 | }) 147 | 148 | cy.get('.two-elements') 149 | .find('.second') 150 | .should(($div) => { 151 | // we can massage text before comparing 152 | const secondText = normalizeText($div.text()) 153 | 154 | expect(secondText, 'second text').to.equal(text) 155 | }) 156 | }) 157 | 158 | it('assert - assert shape of an object', () => { 159 | const person = { 160 | name: 'Joe', 161 | age: 20, 162 | } 163 | 164 | assert.isObject(person, 'value is object') 165 | }) 166 | 167 | it('retries the should callback until assertions pass', () => { 168 | cy.get('#random-number') 169 | .should(($div) => { 170 | const n = parseFloat($div.text()) 171 | 172 | expect(n).to.be.gte(1).and.be.lte(10) 173 | }) 174 | }) 175 | }) 176 | }) 177 | -------------------------------------------------------------------------------- /cypress/e2e/1-getting-started/todo.cy.js: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // Welcome to Cypress! 4 | // 5 | // This spec file contains a variety of sample tests 6 | // for a todo list app that are designed to demonstrate 7 | // the power of writing tests in Cypress. 8 | // 9 | // To learn more about how Cypress works and 10 | // what makes it such an awesome testing tool, 11 | // please read our getting started guide: 12 | // https://on.cypress.io/introduction-to-cypress 13 | 14 | describe('example to-do app', () => { 15 | beforeEach(() => { 16 | // Cypress starts out with a blank slate for each test 17 | // so we must tell it to visit our website with the `cy.visit()` command. 18 | // Since we want to visit the same URL at the start of all our tests, 19 | // we include it in our beforeEach function so that it runs before each test 20 | cy.visit('https://example.cypress.io/todo') 21 | }) 22 | 23 | it('displays two todo items by default', () => { 24 | // We use the `cy.get()` command to get all elements that match the selector. 25 | // Then, we use `should` to assert that there are two matched items, 26 | // which are the two default items. 27 | cy.get('.todo-list li').should('have.length', 2) 28 | 29 | // We can go even further and check that the default todos each contain 30 | // the correct text. We use the `first` and `last` functions 31 | // to get just the first and last matched elements individually, 32 | // and then perform an assertion with `should`. 33 | cy.get('.todo-list li').first().should('have.text', 'Pay electric bill') 34 | cy.get('.todo-list li').last().should('have.text', 'Walk the dog') 35 | }) 36 | 37 | it('can add new todo items', () => { 38 | // We'll store our item text in a variable so we can reuse it 39 | const newItem = 'Feed the cat' 40 | 41 | // Let's get the input element and use the `type` command to 42 | // input our new list item. After typing the content of our item, 43 | // we need to type the enter key as well in order to submit the input. 44 | // This input has a data-test attribute so we'll use that to select the 45 | // element in accordance with best practices: 46 | // https://on.cypress.io/selecting-elements 47 | cy.get('[data-test=new-todo]').type(`${newItem}{enter}`) 48 | 49 | // Now that we've typed our new item, let's check that it actually was added to the list. 50 | // Since it's the newest item, it should exist as the last element in the list. 51 | // In addition, with the two default items, we should have a total of 3 elements in the list. 52 | // Since assertions yield the element that was asserted on, 53 | // we can chain both of these assertions together into a single statement. 54 | cy.get('.todo-list li') 55 | .should('have.length', 3) 56 | .last() 57 | .should('have.text', newItem) 58 | }) 59 | 60 | it('can check off an item as completed', () => { 61 | // In addition to using the `get` command to get an element by selector, 62 | // we can also use the `contains` command to get an element by its contents. 63 | // However, this will yield the