Back to Test Automation
2026-01-125 min read

End-to-end testing (Test Automation)

Learn End-to-end testing (Test Automation) step by step with clear examples and exercises.

Title: End-to-End Testing with JavaScript: Selenium, Cypress, and Playwright


Why This Matters

In the fast-paced world of web development, ensuring your applications function as intended is crucial. Manual testing can be time-consuming and prone to human error. Enter test automation, a method that allows us to automatically execute tests for our web applications. In this lesson, we'll focus on end-to-end testing using popular tools like Selenium, Cypress, and Playwright with JavaScript examples.

End-to-end testing verifies the entire application flow from user interactions to database operations, ensuring a seamless experience for your users. By automating these tests, you can save time, reduce human error, and catch issues early in the development process.

Prerequisites

To follow this lesson, you should have a basic understanding of:

  1. JavaScript (ES6 syntax)
  2. HTML and CSS
  3. Familiarity with web browsers and their developer tools
  4. Node.js and npm installed on your system

Core Concept

Selenium

Selenium is an open-source tool for automating browsers. It supports multiple programming languages, including JavaScript, and offers a variety of APIs to interact with web elements, navigate pages, and perform actions.

Example: Basic Selenium Test in JavaScript

const {Builder, By, Key, until} = require('selenium-webdriver');

async function test() {
let driver = await new Builder().forBrowser('chrome').build();
try {
await driver.get('http://www.example.com');
await driver.findElement(By.name('q')).sendKeys('selenium');
await driver.findElement(By.name('btnK')).click();
await driver.wait(until.titleIs('Google search results for selenium'));
} finally {
await driver.quit();
}
}

test();

In this example, we import the necessary Selenium modules and create a function test() that performs a simple Google search using Selenium WebDriver. We first build a Chrome browser instance, navigate to the Google homepage, enter 'selenium' in the search box, click the search button, and wait for the page title to match our expected result.

Cypress

Cypress is an end-to-end testing framework that runs directly in the browser, making it faster and more reliable than Selenium. It also supports real-time reloading and debugging, which can significantly improve your testing workflow.

Example: Basic Cypress Test

describe('Google Search', () => {
it('should search for selenium', () => {
cy.visit('http://www.example.com');
cy.get('#searchInput').type('selenium{enter}');
cy.title().should('include', 'Google search results for selenium');
});
});

In this example, we use Cypress's describe() and it() functions to organize our tests. We visit the Google homepage, find the search input field using its id, type 'selenium', simulate a key press ({enter}), and verify that the page title includes the expected result.

Playwright

Playwright is a Node.js library for web testing and automation. It supports Chromium, Firefox, and WebKit browsers and offers features like network interception, screenshot capture, and more.

Example: Basic Playwright Test

const { chromium } = require('playwright');

(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('http://www.example.com');
await page.fill('#searchInput', 'selenium');
await page.keyboard.press('Enter');
await page.waitForSelector('.result-heading');
await browser.close();
})();

In this example, we use Playwright to launch a Chromium browser, create a new page, navigate to the Google homepage, find the search input field using its id, type 'selenium', simulate a key press (keyboard.press('Enter')), wait for a selector that represents the search results, and close the browser.

Worked Example

In this worked example, we'll create an end-to-end test for a simple web application that allows users to add items to a shopping cart. We'll use Cypress for our tests.

  1. Install Cypress: npm install cypress --save-dev
  2. Create a new spec file (e.g., shopping_cart_spec.js) in the cypress/integration folder.
  3. Write the test:
describe('Shopping Cart', () => {
it('should add items to the cart', () => {
cy.visit('/');
// Add an apple to the cart
cy.get('#apple').click();
cy.get('.cart-count').should('contain', '1');

// Add a banana to the cart
cy.get('#banana').click();
cy.get('.cart-count').should('contain', '2');

// Verify that the total price is correct
cy.get('.total-price').should('contain', '$3.50');
});
});

In this example, we visit our application's homepage and simulate adding an apple and a banana to the shopping cart by clicking their respective buttons. We then verify that the cart count correctly displays the number of items added, and the total price is as expected.

Common Mistakes

  1. Not waiting for elements to load: Always use cy.wait() or other wait functions to ensure that web elements are fully loaded before interacting with them.
  2. Ignoring browser-specific issues: Make sure to test your application in multiple browsers (Chrome, Firefox, Safari) and address any differences you encounter.
  3. Not handling asynchronous actions properly: Use cy.wrap() or other functions to handle asynchronous actions like AJAX requests or timers correctly.
  4. Hardcoding selectors: Instead of hardcoding selectors, use data attributes or class names that are less likely to change.
  5. Not handling errors gracefully: Make sure your tests can handle unexpected errors and continue running even if one test fails.

Practice Questions

  1. Write a Selenium test for adding an item to the shopping cart from our example (using the same selector strategy as in the Cypress worked example).
  2. Modify the Cypress test from the worked example to include a test for removing items from the cart.
  3. Write a Playwright test for verifying that the login page of your application requires a valid username and password.
  4. Implement a test using any of the tools (Selenium, Cypress, or Playwright) to ensure that the search functionality on your web application returns the expected results.

FAQ

  1. Why is end-to-end testing important? End-to-end testing ensures that all parts of an application work together seamlessly and helps catch issues early in the development process, reducing the likelihood of problems for users.
  2. What are some common pitfalls to avoid when writing tests? Some common pitfalls include not waiting for elements to load, ignoring browser-specific issues, not handling asynchronous actions properly, hardcoding selectors, and not handling errors gracefully.
  3. Can I use Selenium, Cypress, or Playwright with other programming languages besides JavaScript? Yes, all three tools support multiple programming languages, including Java, Python, and C# for Selenium, TypeScript for Cypress, and Go for Playwright.
  4. How can I set up continuous integration (CI) for my tests using one of these tools? Each tool has its own CI setup process. For Selenium, you can use Jenkins or CircleCI; for Cypress, you can use GitHub Actions, CircleCI, or Bitbucket Pipelines; and for Playwright, you can use any CI/CD tool that supports Node.js projects.
  5. How do I handle authentication (login/logout) in my tests? To handle authentication, you can create separate tests for login and logout functions, and include these steps in your end-to-end tests as needed. Some tools also offer plugins or APIs to simplify this process.
End-to-end testing (Test Automation) | Test Automation | XQA Learn