Testing 'The Internet' with Cypress—A List Of The Working Code Examples

Testing 'The Internet' with Cypress—A List Of The Working Code Examples

·

10 min read

Table of contents

Overview

I experimented on Dave Haeffner's website, the-internet.com, with cypress testing. It’s an open-source web application ideal for creating automated tests. Moreover, his free and weekly Selenium tip newsletter, Elemental Selenium, is read by thousands of testing specialists.

Usage

You can implement the majority of the functionality covered by these helpful code snippets into your project.

Note — At the end of this article, you’ll find a link to the complete source code.

Let’s Explore The Code Snippets...

it('Validate A/B testing with cookie', () => {
  cy.visit('/abtest');
  cy.log('Asserting the header test before adding cookie');
  cy.contains('A/B Test').should('be.visible');
  cy.log('Set Cookie').setCookie('optimizelyOptOut', 'true');
  cy.log('Refresh the page').reload();
  cy.log('Asserting the header test after adding cookie');
  cy.contains('No A/B Test').should('be.visible');
});
it('Validate A/B testing with opt out URL', () => {
  cy.visit('/abtest?optimizely_opt_out=true');
  cy.log('Handle alert');
  cy.on('window:alert', (alertText) => {
    expect(alertText).eq(
      'You have successfully opted out of Optimizely for this domain.',
    );
  });
  cy.contains('No A/B Test').should('be.visible');
});
it('Validate add/remove elements', () => {
  cy.visit('/add_remove_elements/');
  cy.log("Click 'Add Element button' and check it's visibility after click");
  cy.contains('Add Element').click().should('be.visible');
  cy.log(
    "Click 'Add Element button' using mouse action and check it's visibility after click",
  );
  cy.contains('Add Element').trigger('mouseover').click().should('be.visible');
  cy.log(
    "Click 'Add Element button' using keyboard action and check it's visibility",
  );
  cy.contains('Add Element').type('{enter}');
  cy.log("Click 'Delete button' and check it's length as expected");
  cy.get("button:contains('Delete')")
    .should('be.visible')
    .its('length')
    .should('eq', 3);
  cy.log('Click all delete button present');
  cy.get("button:contains('Delete')")
    .click({ multiple: true })
    .should('not.exist');
});
it('Validate basic auth', () => {
  cy.log(
    'Handle basic authentication with the credentials in the URL like this https://username:password@www.example.com/',
  );
  cy.visit('https://admin:admin@the-internet.herokuapp.com/basic_auth');
  cy.contains('Congratulations! You must have the proper credentials.').should(
    'be.visible',
  );
});
it('Check broken and non broken images in the page', () => {
  cy.visit('/broken_images');
  cy.get('.example > img').each((img) => {
    cy.wrap(img)
      .invoke('attr', 'src')
      .then((imgSrc) => {
        if (imgSrc.includes('asdf') || imgSrc.includes('hjkl')) {
          cy.log(`Logic to validate broken image whose 'src' is: /${imgSrc}`);
          expect(img[0].naturalWidth).to.be.eql(0);
          expect(img[0].naturalHeight).to.be.eql(0);
          cy.request({
            url: imgSrc,
            failOnStatusCode: false,
          }).then((response) => {
            expect(response.status).to.eq(404);
          });
        } else {
          cy.log(
            `Logic to validate non broken image whose 'src' is: /${imgSrc}`,
          );
          expect(img[0].naturalWidth).to.be.greaterThan(0);
          expect(img[0].naturalHeight).to.be.greaterThan(0);
          cy.request(imgSrc).then((response) => {
            expect(response.status).to.eq(200);
          });
        }
      });
  });
});
it('Validate check boxes', () => {
  cy.visit('/checkboxes');
  cy.log('Verify selected & unselected checkboxes')
    .get('#checkboxes > input:first-of-type')
    .should('not.be.checked')
    .get('#checkboxes > input:nth-of-type(2)')
    .should('be.checked');
  cy.log('Select check box 1');
  cy.get('#checkboxes > input:first-of-type').click().should('be.checked');
  cy.log('Un-select all checkbox')
    .get('input[type="checkbox"]')
    .uncheck()
    .should('not.be.checked');
});
it('Validate context menu', () => {
  cy.visit('/context_menu');
  cy.log('Do right click and handling alert').get('#hot-spot').rightclick();
  cy.on('window:alert', (alertText) => {
    expect(alertText).eq('You selected a context menu');
  });
});
// Use DataTransfer object in order to take data from one place and put it in another.

const dataTransfer = new DataTransfer();
it('Drag and drop', () => {
  cy.visit('/drag_and_drop');
  cy.log('Mouse drag and drop with data transfer');
  cy.contains('A').trigger('dragstart', { dataTransfer });
  cy.contains('B').trigger('drop', { dataTransfer });
});
it('Select and verify dropdowns', () => {
  cy.visit('/dropdown');
  cy.log('Select by value').get('select').select('1').should('have.value', '1');
  cy.log('Check selected option')
    .get('select#dropdown option:selected')
    .should('have.value', '1')
    .should('have.text', 'Option 1');
  cy.log('Select by index').get('select').select(2).should('have.value', '2');
  cy.log('Check selected option')
    .get('select#dropdown option:selected')
    .should('have.value', '2')
    .should('have.text', 'Option 2');
  cy.log('Select by text')
    .get('select')
    .select('Option 1')
    .should('have.value', '1');
  cy.log('Check selected option')
    .get('select#dropdown option:selected')
    .should('have.value', '1')
    .should('have.text', 'Option 1');
});
// Reference: https://stackoverflow.com/questions/61196857/storing-an-array-of-elements-using-cypress

it('Validate dynamic content', () => {
  let dynamicImgSrcAttrFirstVisit = [];
  let dynamicTrimContentFirstVisit = [];
  cy.visit('/dynamic_content');
  cy.log(`Store all the dynamic images' src attributes at first visit`);
  cy.get('.large-2 img').then(($imgFirstVisit) => {
    dynamicImgSrcAttrFirstVisit = Array.from($imgFirstVisit, (img) => img.src);
  });
  cy.log(`Store all the dynamic contents at first visit`);
  cy.get('.large-2 + .large-10').then(($contentFirstVisit) => {
    dynamicTrimContentFirstVisit = Array.from($contentFirstVisit, (element) =>
      element.innerText.trim(),
    );
  });
  cy.log('Refresh the page');
  cy.reload();
  cy.log(
    `Store all the dynamic images' src attributes at second visit and compare with first`,
  );
  cy.get('.large-2 img').then(($imgSecondVisit) => {
    const dynamicImgSrcAttrSecondVisit = Array.from(
      $imgSecondVisit,
      (img) => img.src,
    );
    expect(dynamicImgSrcAttrSecondVisit).not.to.deep.eq(
      dynamicImgSrcAttrFirstVisit,
    );
  });
  cy.log(
    `Store all the dynamic contents at second visit and compare with first`,
  );
  cy.get('.large-2 + .large-10').then(($contentSecondVisit) => {
    const dynamicTrimContentSecondVisit = Array.from(
      $contentSecondVisit,
      (element) => element.innerText.trim(),
    );
    expect(dynamicTrimContentFirstVisit).not.to.deep.eq(
      dynamicTrimContentSecondVisit,
    );
  });
});
beforeEach(() => {
  cy.visit('/dynamic_loading');
});
it('Validate Dynamic Loading - assert the hidden element', () => {
  cy.get('[href="/dynamic_loading/1"]')
    .contains('Example 1')
    .click()
    .get('h4')
    .contains('Example 1: Element on page that is hidden')
    .should('be.visible');
  cy.get('#finish').invoke('show').should('be.visible');
  cy.contains('Start')
    .click()
    .get('#loading')
    .contains('Loading', { timeout: 20000 })
    .should('not.be.visible')
    .get('#finish')
    .contains('Hello World!')
    .should('be.visible');
});
it('Validate Dynamic Loading - wait till element rendered', () => {
  cy.get('[href="/dynamic_loading/2"]')
    .contains('Example 2')
    .click()
    .get('h4')
    .contains('Example 2: Element rendered after the fact')
    .should('be.visible');
  cy.contains('Start')
    .click()
    .get('#loading')
    .contains('Loading', { timeout: 20000 })
    .should('not.be.visible')
    .get('#finish')
    .contains('Hello World!')
    .should('be.visible');
});
it('Close entry ad', () => {
  cy.visit('/entry_ad');
  cy.log('Close the entry ad');
  cy.contains('Close').click().should('not.be.visible');
});
// Reference to the yield file content and verify it: https://docs.cypress.io/api/commands/readfile#Existence

const path = require('path');
const downloadsFolder = Cypress.config('downloadsFolder');
it('Verify file download test for dynamic file', () => {
  cy.visit('/download');
  // Added the following logic based on this issue: https://github.com/cypress-io/cypress/issues/14857#issuecomment-785717474
  cy.log(`Added event listener 'click' to listen & trigger the page load event`)
    .window()
    .document()
    .then((doc) => {
      doc.addEventListener('click', () => {
        setTimeout(() => {
          doc.location.reload();
        }, 3000);
      });
    });
  cy.log('Create downloads folder').exec('mkdir cypress/downloads', {
    log: true,
    failOnNonZeroExit: false, // Not to fail if the command exits with a non-zero code
  });
  cy.log(
    'Added this defensive code to avoid test failure when executing the tests in interactive mode',
  ).exec('rm cypress/downloads/*', {
    log: true,
    failOnNonZeroExit: false,
  });
  cy.log(
    `Verify the file presence based on the count logic in the 'downloads' directory by comparing before file download vs after file download`,
  )
    .task('dynamicFiledownload', 'cypress/downloads')
    .then((before) => {
      cy.contains('.txt').click();
      cy.task('dynamicFiledownload', 'cypress/downloads').then((after) => {
        expect(after.length).to.be.eq(before.length + 1);
        const downloadedFileName = after.filter(
          (file) => !before.includes(file),
        )[0];
        expect(downloadedFileName).includes('.txt');
      });
    });
});
// Add "test.txt" to your project root directory - exampleProject/text.txt

const filePath = 'test.txt';
beforeEach(() => {
  cy.visit('/upload');
});
it('Upload file', () => {
  cy.get('#file-upload')
    .selectFile(filePath)
    .get('#file-submit')
    .click()
    .get('#uploaded-files')
    .contains(filePath)
    .should('be.visible');
});
it('Drag and drop file', () => {
  cy.get('#drag-drop-upload')
    .selectFile(filePath, { action: 'drag-drop' })
    .contains(filePath)
    .should('be.visible');
});
it('Validate floating menu', () => {
  cy.visit('/floating_menu');
  cy.get('#page-footer').scrollIntoView();
  cy.contains('About').should('be.visible').click();
  cy.log("Verify current URL has endpoint '#about'");
  cy.hash().should('contains', '#about');
});
it('Validate forgot password with API approach', () => {
  cy.request({
    method: 'POST',
    url: '/forgot_password', // BaseUrl is prepend to URL
    form: true, // Indicates the body should be form urlencoded and sets Content-Type: application/x-www-form-urlencoded headers
    body: {
      email: 'test@mail.com',
    },
  }).then((response) => {
    expect(response.status).to.eq(200); // Expect to fail as currently application throws 500 error
  });
});

it('Validate forgot password with UI approach', () => {
  cy.visit('/forgot_password');
  cy.log('Clear textbox and type')
    .get('#email')
    .type('{selectall}{backspace}test@mail.com');
  cy.contains('Retrieve password').click();
  cy.contains('#content', `Your e-mail's been sent!`, {
    timeout: 10000,
  }).should('be.visible'); // Expect to fail as currently application throws 500 error
});
// You may refer this https://github.com/kamranayub/cypress-browser-permissions which replaced the deprecated method
// example: force Mumbai geolocation

const latitude = 19.075984;
const longitude = 72.877656;
it('Validate GeoLocation', () => {
  cy.log('Customize Geo-Location in Chrome Browser');
  cy.visit('/geolocation');
  cy.log('Mocking Geolocation');
  cy.window().then(($window) => {
    cy.stub($window.navigator.geolocation, 'getCurrentPosition').callsFake(
      (callback) => {
        return callback({ coords: { latitude, longitude } });
      },
    );
  });
  cy.contains('Where am I?').click().should('be.visible');
  cy.contains(latitude).should('be.visible');
  cy.contains(longitude).should('be.visible');
});
beforeEach(() => {
  cy.visit('/horizontal_slider');
});
it('Validate horizontal silder - click on slider', () => {
  cy.get('input')
    .invoke('val', '2')
    .trigger('change')
    .get('#range')
    .should('have.text', '2');
});
it('Validate horizontal silder - key strokes', () => {
  cy.get('input')
    .focus()
    .type(Cypress._.repeat('{rightarrow}-{enter}', 5)) // Pressing right arrow key for 5 times
    .trigger('change')
    .get('#range')
    .should('have.text', '2.5');
});
it('Validate hovers', () => {
  cy.visit('/hovers');
  cy.log('Mouse hover');
  cy.get('.figcaption').first().invoke('show');
  cy.get('.figcaption')
    .first()
    .contains('h5', 'name: user1')
    .should('be.visible');
  cy.contains('a', 'View profile').should('be.visible');
});
const givenArraySize = 8;
const indexArray = [...Array(givenArraySize).keys()];
it('Infinite scroll', () => {
  cy.log('Spying network request & apply aliases')
    .intercept('/infinite_scroll/**')
    .as('paragraph');
  cy.visit('/infinite_scroll');
  cy.wrap(indexArray).each((index) => {
    cy.log(`Scroll to bottom with ${index + 1} time`);
    cy.log('Wait for the network request').wait('@paragraph');
    cy.window().scrollTo('bottom');
  });
  cy.get('.jscroll-added').its('length').should('eq', givenArraySize);
});
it('Validate input field', () => {
  cy.visit('/inputs');
  cy.log('Should not accept text')
    .get('input')
    .type('Hello!')
    .should('not.have.value', 'Hello!');
  cy.log('Should only accept numeric value')
    .get('input')
    .type(123)
    .should('have.value', 123);
});
beforeEach(() => {
  cy.visit('/javascript_alerts');
});
it('Validate alert box', () => {
  cy.contains('Click for JS Alert').click().should('be.visible');
  cy.on('window:alert', (alertText) => {
    expect(alertText).eq('I am a JS Alert');
  });
  cy.get('#result')
    .contains('You successfully clicked an alert')
    .should('be.visible');
});
it('Validate confirm box', () => {
  cy.contains('Click for JS Confirm').click().should('be.visible');
  cy.on('window:confirm', (alertText) => {
    expect(alertText).eq('I am a JS Confirm');
    return true;
    // By default, Cypress will automatically hit "Ok" for alert confirmation and no need to explicitly return true in this event callback
    // If we wanted to instead test a use case of someone clicking "Cancel", then we need to return false in this event callback
  });
  cy.get('#result').contains('You clicked: Ok').should('be.visible');
});
it('Validate prompt box', () => {
  cy.window().then(($win) => {
    cy.stub($win, 'prompt').returns('Hello Hi!!');
    cy.contains('Click for JS Prompt').click().should('be.visible');
  });
  cy.get('#result').contains('You entered: Hello Hi!!').should('be.visible');
});
// Added the following logic based on this good reference: https://github.com/cypress-io/cypress/issues/14857#issuecomment-785717474

const path = require('path');
const downloadsFolder = Cypress.config('downloadsFolder');
it('Validate JQuery UI menus', () => {
  cy.visit('/jqueryui/menu');
  // Added the following logic based on this issue: https://github.com/cypress-io/cypress/issues/14857#issuecomment-785717474
  cy.log(`Added event listener 'click' to listen & trigger the page load event`)
    .window()
    .document()
    .then((doc) => {
      doc.addEventListener('click', () => {
        setTimeout(() => {
          doc.location.reload();
        }, 3000);
      });
    });
  cy.contains('Enabled').trigger('mouseover');
  cy.contains('Downloads')
    .trigger('mouseover')
    .next('ul.ui-menu')
    .then(($thirdSubMenu) => {
      cy.wrap($thirdSubMenu).invoke('show');
      cy.wrap($thirdSubMenu).contains('PDF').click();
    });
  cy.log('Verify downloaded PDF file existance')
    .readFile(path.join(downloadsFolder, 'menu.pdf'))
    .should('exist');
});
// In order to handle tabbing, use this library: https://github.com/kuceb/cypress-plugin-tab

it('Verify key presses', () => {
  cy.visit('/key_presses');
  cy.log("Type 'Hello' then click backspace key")
    .get('#target')
    .type('Hello{backspace}');
  cy.get('#result').should('have.text', 'You entered: BACK_SPACE');
});
const users = [
  {
    username: 'tomsmith',
    password: 'SuperSecretPassword!',
  },
  {
    username: 'tomsmithfail',
    password: 'SuperSecretPasswordFail',
  },
];
it('Validate data driven login page with two users', () => {
  cy.visit('/login');
  cy.log('Checking for positive & negative user');
  users.forEach((user) => {
    cy.get('#username').type(user.username);
    cy.get('#password')
      .type(user.password)
      .get('.fa')
      .click()
      .should('be.visible');
    if (
      user.username == 'tomsmith' &&
      user.password == 'SuperSecretPassword!'
    ) {
      cy.get('h2').should('have.text', ' Secure Area');
      cy.contains('Logout').click();
    } else {
      cy.get('#flash').should('contain', 'Your username is invalid!');
    }
  });
});
it('Validate login page with UI approach', () => {
  cy.visit('/login');
  cy.get('#username').type('tomsmith');
  cy.get('#password')
    .type('SuperSecretPassword!')
    .get('.fa')
    .click()
    .get('h2')
    .should('have.text', ' Secure Area');
});
it('Validate login page with API approach', () => {
  cy.visit('/login');
  cy.request({
    method: 'POST',
    url: '/authenticate', // BaseUrl is prepend to URL
    form: true, // Indicates the body should be form urlencoded and sets Content-Type: application/x-www-form-urlencoded headers
    body: {
      username: 'tomsmith',
      password: 'SuperSecretPassword!',
    },
  }).then((response) => {
    expect(response.status).to.eq(200);
  });
  cy.visit('/secure');
  cy.contains('Secure Area').should('be.visible');
  cy.contains('.button', 'Logout').should('be.visible');
});
it('Navigate to multiple tabs & verify', () => {
  cy.visit('/windows');
  cy.contains('Click Here')
    .invoke('removeAttr', 'target')
    .click()
    .url()
    .should('include', '/windows/new')
    .get('h3')
    .should('have.text', 'New Window');
  // Navigate back to the previous or next URL in the browser’s history.
  cy.go('back');
  cy.contains('Click Here').should('be.visible');
});
// Reference: Jquery API contents() - https://api.jquery.com/contents/

const locators = ['left', 'middle', 'right', 'bottom'];
const actualFramesContent = [];
const expectedFramesContent = ['LEFT', 'MIDDLE', 'RIGHT', 'BOTTOM'];
it(`Validate nested frames in the page with Jquery API contents() way`, () => {
  cy.visit('/nested_frames');
  locators.forEach((locator) => {
    if (locator !== 'bottom') {
      cy.get('frame[src="/frame_top"]').within(($frame) => {
        cy.wrap(
          $frame.contents().find(`frame[src="/frame_${locator}"]`),
        ).within((frame) => {
          cy.wrap(frame.contents().find('body'))
            .invoke('text')
            .then((frameBodyText) => {
              actualFramesContent.push(frameBodyText.trim());
            });
        });
      });
    } else {
      cy.get('frame[src="/frame_bottom"]').within(($frame) => {
        cy.wrap($frame.contents()).within((frame) => {
          cy.wrap(frame.contents().find('body'))
            .invoke('text')
            .then((frameBodyText) => {
              actualFramesContent.push(frameBodyText.trim());
            });
        });
      });
    }
  });
  cy.wrap(actualFramesContent).should(
    'have.ordered.members',
    expectedFramesContent,
  );
});
it('Take screenshort', () => {
  cy.visit('/');
  cy.log('Takes full page screenshot');
  cy.screenshot();
  cy.log(
    'By default, Cypress automatically takes a screenshot when there is a failure when running cypress run',
  );
});
const status_codes = [200, 301, 404, 500];
it('Validate all status codes', () => {
  cy.visit('/status_codes');
  status_codes.forEach((status_code) => {
    // To not to fail the test, on response codes other than 2xx and 3xx then pass failOnStatusCode: false
    cy.request({
      url: `/status_codes/${status_code}`,
      failOnStatusCode: false,
    }).then((response) => {
      expect(response.status).to.eq(status_code);
      expect(response.body).to.include(`a ${status_code} status code`);
    });
  });
});

Conclusion

Here’s the source code on GitHub repository.

Feel free to utilize these examples, and let us know if you run across any problems or comparable use-cases. Here is the cypress documentation for further information. Hope you found this helpful!