Back to Test Automation
2026-02-199 min read

We have several examples of doing this in our logging in recipes.

Learn We have several examples of doing this in our logging in recipes. step by step with clear examples and exercises.

Title: Test Automation with JavaScript: A full guide to Selenium, Cypress, and Playwright


Why This Matters

In today's fast-paced world, test automation has become a necessity for ensuring software quality and efficiency. With the help of JavaScript and popular libraries like Selenium, Cypress, and Playwright, you can automate repetitive tasks, save time, and catch bugs early in the development process. This guide will walk you through the core concepts, worked examples, common mistakes, practice questions, and frequently asked questions to help you master test automation using JavaScript.


Prerequisites

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

  1. HTML and CSS for creating web pages
  2. JavaScript for writing client-side scripts
  3. Familiarity with browser developer tools (Inspect Element)
  4. Understanding of asynchronous JavaScript using Promises or async/await
  5. Basic knowledge of the command line interface (CLI)
  6. Familiarity with Git for version control (optional but recommended)
  7. Knowledge of a text editor or Integrated Development Environment (IDE) like Visual Studio Code, Atom, or Sublime Text
  8. Understanding of modern JavaScript features such as ES6 syntax and arrow functions
  9. Familiarity with web applications and their user interfaces
  10. Basic understanding of HTTP requests and responses

Core Concept

Test automation involves writing scripts that execute a series of actions on an application, compare the results with expected outcomes, and report any differences as failures. This process helps developers catch issues early in the development cycle, saving time and resources. In this guide, we will focus on three popular test automation libraries for JavaScript: Selenium, Cypress, and Playwright.

Selenium

Selenium is a powerful tool that allows you to write tests in several languages, including JavaScript, using the WebDriver API. It can simulate user interactions with web applications, such as clicking buttons, filling forms, and reading output. Selenium supports multiple browsers and platforms, making it a versatile choice for test automation.

Selenium Architecture

Selenium consists of four components:

  1. WebDriver: The core of Selenium that provides an API to interact with the browser.
  2. WebDriver Client Libraries: These libraries allow you to write tests in various programming languages, such as Java, Python, C#, and JavaScript.
  3. Browser Drivers: Each browser has a specific driver that communicates between WebDriver and the browser. For example, ChromeDriver for Google Chrome or GeckoDriver for Firefox.
  4. Test Runner: A tool that executes your tests and provides test results. You can choose from several test runners like Mocha, Jest, or Karma.

Installing Selenium

To set up a new project using Selenium, follow these steps:

  1. Install Node.js (https://nodejs.org/)
  2. Initialize a new npm project: npm init -y
  3. Install the necessary dependencies: npm install selenium-webdriver chrome-launcher

Cypress

Cypress is a newer open-source testing library that focuses on providing a faster and more reliable testing experience compared to Selenium. It runs directly in the browser, eliminating the need for a separate server or test runner. Cypress also provides real-time replay of tests, making it easier to debug issues.

Cypress Architecture

Cypress consists of three main components:

  1. Test Runner: A built-in test runner that runs your tests in the browser.
  2. Plugin System: An extensible system for adding custom functionality to your tests.
  3. Command Line Interface (CLI): A command line tool for running Cypress commands and managing your tests.

Installing Cypress

To set up a new Cypress project, follow these steps:

  1. Install Node.js (https://nodejs.org/)
  2. Create a new directory for your project: mkdir my-cypress-project && cd my-cypress-project
  3. Initialize a new npm project: npm init
  4. Install Cypress as a development dependency: npm install cypress --save-dev
  5. Run the following command to download the necessary dependencies: npm run install

Playwright

Playwright is another modern open-source library that supports multiple browsers and platforms. It offers features like network interception, screenshot capture, and PDF generation, making it a powerful tool for end-to-end testing. Playwright also provides fast test execution times and can be integrated with popular build tools like Webpack and Rollup.

Playwright Architecture

Playwright consists of three main components:

  1. Browser: A headless browser that supports multiple platforms and browsers.
  2. API: An API for interacting with the browser, similar to Selenium's WebDriver.
  3. CLI: A command line tool for running Playwright commands and managing your tests.

Installing Playwright

To set up a new Playwright project, follow these steps:

  1. Install Node.js (https://nodejs.org/)
  2. Create a new directory for your project: mkdir my-playwright-project && cd my-playwright-project
  3. Initialize a new npm project: npm init
  4. Install Playwright as a development dependency: npm install playwright --save-dev
  5. Run the following command to download the necessary dependencies: npm run install

Worked Example

In this section, we will walk through an example of writing a simple test automation script using Selenium, Cypress, and Playwright. We will create tests for a basic login form on a web page.

Selenium Example

First, let's set up our project by installing the necessary dependencies:

npm init -y
npm install selenium-webdriver chrome-launcher

Next, create a new JavaScript file called selenium_example.js and write the following code:

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

async function main() {
let driver = await chromium.launch({ args: ['--headless'] });
let page = await driver.newPage();

// Navigate to the login page
await page.goto('http://example.com/login');

// Find and fill in the username input field
const usernameInput = await page.$('#username');
await usernameInput.sendKeys('test_user');

// Find and fill in the password input field
const passwordInput = await page.$('#password');
await passwordInput.sendKeys('secret_pass');

// Click the login button
const loginButton = await page.$('#login-button');
await loginButton.click();

// Check if the user is successfully logged in
const welcomeMessage = await page.$eval('#welcome-message', (element) => element.textContent);
expect(welcomeMessage).toEqual('Welcome, test_user!');

// Close the browser
await driver.close();
}

main().catch((err) => console.error(err));

Cypress Example

To set up a new Cypress project, run the following command:

npm init cypress
cd cypress
npm install

Next, create a new spec file called login_spec.js and write the following code:

describe('Login', () => {
it('should allow valid login', () => {
// Visit the login page
cy.visit('http://example.com/login');

// Fill in the username input field
cy.get('#username').type('test_user');

// Fill in the password input field
cy.get('#password').type('secret_pass{enter}');

// Check if the user is successfully logged in
cy.contains('Welcome, test_user!');
});
});

Playwright Example

To set up a new Playwright project, run the following command:

npm init playwright
cd playwright
npm install

Next, create a new JavaScript file called playwright_example.js and write the following code:

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

async function main() {
const browser = await chromium.launch();
const page = await browser.newPage();

// Navigate to the login page
await page.goto('http://example.com/login');

// Fill in the username input field
await page.fill('#username', 'test_user');

// Fill in the password input field
await page.fill('#password', 'secret_pass');

// Click the login button
await page.click('#login-button');

// Check if the user is successfully logged in
const welcomeMessage = await page.$eval('#welcome-message', (element) => element.textContent);
expect(welcomeMessage).toEqual('Welcome, test_user!');

// Close the browser
await browser.close();
}

main().catch(console.error);

Common Mistakes

  1. Forgetting to import necessary libraries or modules
  2. Using incorrect selectors for finding elements on the page
  3. Not handling asynchronous actions properly (e.g., waiting for pages to load)
  4. Ignoring browser-specific quirks and differences
  5. Not properly handling errors and exceptions during testing
  6. Writing tests that are too brittle or tightly coupled to the application's implementation
  7. Neglecting to clean up resources after each test (e.g., closing browser windows)
  8. Failing to use a consistent naming convention for tests, functions, and variables
  9. Not documenting tests properly, making them difficult to understand and maintain
  10. Running tests too frequently or without proper monitoring, leading to false positives and wasted resources

Practice Questions

  1. Write a test for a form that submits data using Selenium, Cypress, and Playwright.
  2. Modify the login example to handle incorrect credentials and display an error message.
  3. Create a test that verifies the functionality of a dropdown menu using Selenium, Cypress, and Playwright.
  4. Write a test that checks the correctness of a calculation performed by a JavaScript function using Jest (not covered in this guide).
  5. Write a test that verifies the correct display of a date picker using Selenium, Cypress, and Playwright.
  6. Write a test that verifies the functionality of a modal dialog box using Selenium, Cypress, and Playwright.
  7. Write a test that checks the performance of a JavaScript function using Jest (not covered in this guide).
  8. Write a test that verifies the correct display of a progress bar using Selenium, Cypress, and Playwright.
  9. Write a test that checks the correctness of an AJAX request using Selenium, Cypress, and Playwright.
  10. Write a test that verifies the functionality of a drag-and-drop feature using Selenium, Cypress, and Playwright.

FAQ

What is test automation?

Test automation involves writing scripts to execute a series of actions on an application, compare the results with expected outcomes, and report any differences as failures. The goal is to save time, improve efficiency, and catch bugs early in the development process.

Why use JavaScript for test automation?

JavaScript is widely used in web development, making it a natural choice for test automation of web applications. It allows you to write tests that simulate user interactions with the application, ensuring that the application behaves as expected.

What are the advantages of using Selenium for test automation?

Selenium is a powerful tool that supports multiple browsers and platforms, making it a versatile choice for test automation. It also has a large community and extensive documentation, making it easy to find solutions to common problems.

What are the advantages of using Cypress for test automation?

Cypress runs directly in the browser, eliminating the need for a separate server or test runner. It provides real-time replay of tests, making it easier to debug issues. Additionally, Cypress has a friendly API and offers features like network interception and screenshot capture.

What are the advantages of using Playwright for test automation?

Playwright supports multiple browsers and platforms, offering fast test execution times and integration with popular build tools like Webpack and Rollup. It also provides features like network interception, screenshot capture, and PDF generation, making it a powerful tool for end-to-end testing.

How can I handle asynchronous actions in my tests?

To handle asynchronous actions in your tests, you should use Promises or async/await to properly manage the flow of control. For example, when clicking a button that triggers an AJAX request, you should wait for the request to complete before checking the results.

How can I write tests that are less brittle and more maintainable?

To write tests that are less brittle and more maintainable, you should use selectors that are specific to the application

We have several examples of doing this in our logging in recipes. | Test Automation | XQA Learn