├── 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 |
7 |
8 |
9 | > Test Result
10 |
11 |
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