Thursday, July 16, 2026

Playwright Cross-Browser Testing with Java (Chromium, Firefox & WebKit)

Introduction

Modern users access web applications using different browsers such as Google Chrome, Mozilla Firefox, Microsoft Edge, and Apple Safari. A feature that works perfectly in one browser may behave differently in another due to differences in rendering engines, JavaScript implementations, or browser-specific behaviors.

Cross-browser testing ensures your application delivers a consistent user experience across all supported browsers.

Playwright makes this process simple by providing built-in support for Chromium, Firefox, and WebKit using a single automation API.

In this guide, you'll learn how to execute the same Playwright test across multiple browsers using Java.


Why Cross-Browser Testing is Important

Testing across multiple browsers helps you:

  • Detect browser-specific bugs
  • Validate UI consistency
  • Improve customer experience
  • Increase application reliability
  • Meet enterprise quality standards

Instead of maintaining separate automation frameworks for different browsers, Playwright allows you to use one codebase for all supported browsers.


Browsers Supported by Playwright

Playwright supports three browser engines:

Browser EngineCommon Browsers
ChromiumGoogle Chrome, Microsoft Edge, Brave
FirefoxMozilla Firefox
WebKitApple Safari

This broad support enables comprehensive browser compatibility testing.


Project Setup

Ensure your Maven project includes the Playwright dependency.

<dependency>
    <groupId>com.microsoft.playwright</groupId>
    <artifactId>playwright</artifactId>
    <version>1.55.0</version>
</dependency>

After adding the dependency, install the required browser binaries.

mvn exec:java -Dexec.mainClass=com.microsoft.playwright.CLI -Dexec.args="install"

Launching Chromium

Chromium is the default browser used by many Playwright projects.

Playwright playwright = Playwright.create();

Browser browser =
        playwright.chromium().launch(
                new BrowserType.LaunchOptions()
                        .setHeadless(false));

BrowserContext context =
        browser.newContext();

Page page = context.newPage();

page.navigate("https://example.com");

Launching Firefox

To execute the same test in Firefox, change only the browser initialization.

Browser browser =
        playwright.firefox().launch(
                new BrowserType.LaunchOptions()
                        .setHeadless(false));

Everything else remains unchanged.


Launching WebKit

Testing Safari compatibility is equally straightforward.

Browser browser =
        playwright.webkit().launch(
                new BrowserType.LaunchOptions()
                        .setHeadless(false));

WebKit uses the same rendering engine as Safari, making it ideal for validating Safari behavior.


Parameterizing Browser Selection

Instead of maintaining separate test classes, you can parameterize the browser using TestNG.

@Parameters("browser")

@BeforeMethod

public void setup(String browserName) {

    playwright = Playwright.create();

    switch (browserName.toLowerCase()) {

        case "chromium":
            browser = playwright.chromium().launch();
            break;

        case "firefox":
            browser = playwright.firefox().launch();
            break;

        case "webkit":
            browser = playwright.webkit().launch();
            break;

        default:
            throw new IllegalArgumentException(
                    "Unsupported browser: " + browserName);
    }

    context = browser.newContext();

    page = context.newPage();
}

This approach keeps your framework flexible and avoids code duplication.


Configuring testng.xml

Pass the browser name through TestNG parameters.

<suite name="CrossBrowserSuite">

    <test name="Chromium">

        <parameter name="browser"
                   value="chromium"/>

        <classes>

            <class name="tests.LoginTest"/>

        </classes>

    </test>

    <test name="Firefox">

        <parameter name="browser"
                   value="firefox"/>

        <classes>

            <class name="tests.LoginTest"/>

        </classes>

    </test>

    <test name="WebKit">

        <parameter name="browser"
                   value="webkit"/>

        <classes>

            <class name="tests.LoginTest"/>

        </classes>

    </test>

</suite>

The same test class runs against all three browsers.


Running Tests in Parallel

To reduce execution time, enable parallel execution in TestNG.

<suite name="CrossBrowserSuite"
       parallel="tests"
       thread-count="3">

Each browser executes in its own thread.

Ensure every thread creates a separate BrowserContext and Page.


Example Login Test

@Test

public void verifyLogin() {

    page.navigate("https://example.com/login");

    page.fill("#username", "admin");

    page.fill("#password", "password123");

    page.click("#loginButton");

    assertThat(page)
            .hasURL("https://example.com/dashboard");
}

This single test can now validate functionality across Chromium, Firefox, and WebKit.


Best Practices

Use Separate Browser Contexts

Create a new BrowserContext for every test to isolate cookies, storage, and session data.


Avoid Browser-Specific Logic

Write browser-agnostic tests whenever possible.

If browser-specific behavior exists, document it clearly and minimize conditional code.


Run Headless in CI/CD

Headless mode is faster and better suited for build servers.

new BrowserType.LaunchOptions()
        .setHeadless(true);

Verify Critical User Flows

Prioritize cross-browser testing for high-value scenarios such as:

  • Login
  • Registration
  • Checkout
  • Payment
  • Search
  • File uploads
  • Form submission

Capture Screenshots on Failure

Integrate screenshot capture with your reporting framework (such as Allure) to simplify debugging across browsers.


Common Browser Differences

Although Playwright abstracts many browser differences, you may still encounter:

  • Font rendering variations
  • CSS layout differences
  • Native dialog behavior
  • Download handling
  • Browser security policies

Test these scenarios carefully when supporting multiple browsers.


Common Interview Questions

Which browsers are supported by Playwright?

Playwright supports Chromium, Firefox, and WebKit.


Can the same Playwright test run on multiple browsers?

Yes. Playwright uses a single API, allowing the same test code to execute across supported browser engines.


Why use BrowserContext instead of sharing a Browser instance?

A BrowserContext provides isolated sessions, preventing cookies and local storage from leaking between tests.


How do you execute Playwright tests on multiple browsers using TestNG?

Pass the browser as a TestNG parameter in testng.xml and initialize the corresponding browser in the setup method.


Is Microsoft Edge supported?

Yes. Microsoft Edge is Chromium-based, so Playwright can automate it using the Chromium engine or by launching the Edge executable if required.


Conclusion

Cross-browser testing is essential for delivering reliable web applications.

Playwright simplifies this process by providing a unified API for Chromium, Firefox, and WebKit, enabling teams to validate browser compatibility without maintaining separate automation frameworks.

In this tutorial, you learned how to:

  • Launch Chromium, Firefox, and WebKit
  • Parameterize browser selection with TestNG
  • Execute cross-browser tests in parallel
  • Follow best practices for browser isolation
  • Build a scalable, enterprise-ready automation framework

With these techniques, your automation suite will be better equipped to catch browser-specific issues before they reach production.

Wednesday, July 15, 2026

Playwright Docker Integration with Java (Run Tests Inside Containers)

One of the biggest challenges in automation testing is ensuring that tests run consistently across different environments. A test that works on a developer's machine may fail on a CI server due to differences in browser versions, operating systems, or installed dependencies.

Docker solves this problem by packaging your Playwright framework and all its dependencies into a portable container. Whether you run the container on your laptop, a Jenkins server, or a cloud platform, the environment remains the same.

In this tutorial, you'll learn how to containerize a Playwright Java framework using Docker and execute your tests inside a container.


What is Docker?

Docker is a containerization platform that allows applications to run in isolated environments called containers.

A container includes:

  • Application code
  • Java Runtime
  • Browser binaries
  • System libraries
  • Maven dependencies

This ensures that your automation framework behaves consistently across environments.


Why Run Playwright Inside Docker?

Running Playwright in Docker provides several advantages:

  • Consistent execution across environments
  • Easy setup for new team members
  • Simplified CI/CD integration
  • Isolated browser environments
  • Reduced "works on my machine" issues
  • Easy scaling for parallel execution

Prerequisites

Before you begin, ensure you have:

  • Java 17 or later
  • Maven installed
  • Docker Desktop (Windows/macOS) or Docker Engine (Linux)
  • A Playwright Java project
  • Browser binaries installed locally for development

Project Structure

Example project layout:

playwright-framework
│
├── src
├── pom.xml
├── Dockerfile
├── testng.xml
├── screenshots
├── videos
└── allure-results

Step 1: Create a Dockerfile

Create a file named Dockerfile in the project root.

FROM maven:3.9.9-eclipse-temurin-17

WORKDIR /app

COPY . .

RUN mvn dependency:resolve

RUN mvn exec:java \
    -Dexec.mainClass=com.microsoft.playwright.CLI \
    -Dexec.args="install --with-deps"

CMD ["mvn", "test"]

This Dockerfile:

  • Uses Maven with Java 17
  • Copies the project into the container
  • Downloads project dependencies
  • Installs Playwright browser binaries and required system libraries
  • Executes the test suite

Step 2: Build the Docker Image

Run the following command from the project root:

docker build -t playwright-java-framework .

Explanation:

  • build creates an image.
  • -t assigns a friendly name.
  • . indicates the current directory as the build context.

Step 3: Verify the Image

List available Docker images:

docker images

Example output:

REPOSITORY                  TAG       IMAGE ID
playwright-java-framework   latest    abc123xyz

Step 4: Run the Container

Execute your tests:

docker run --rm playwright-java-framework

The --rm option automatically removes the container after execution.


Passing Environment Variables

Most automation frameworks use environment variables for configuration.

Example:

docker run --rm \
-e ENV=QA \
-e BROWSER=chromium \
playwright-java-framework

Your Java code can access these values using System.getenv().


Mounting Volumes

To preserve reports, screenshots, or videos outside the container, mount a local folder.

Example:

docker run --rm \
-v ${PWD}/reports:/app/allure-results \
playwright-java-framework

This copies the generated Allure results to your local machine.


Running Specific TestNG Suites

Execute a specific suite:

docker run --rm \
playwright-java-framework \
mvn test -DsuiteXmlFile=testng.xml

This is useful when you want to run smoke or regression suites independently.


Integrating with Jenkins

Once the image is built, Jenkins can execute it as part of your pipeline.

Example pipeline stage:

stage('Run Docker Tests') {

    steps {

        sh 'docker build -t playwright-java-framework .'

        sh 'docker run --rm playwright-java-framework'
    }
}

Note: On Windows Jenkins agents, use bat instead of sh.


Running Multiple Containers

For parallel execution, start multiple containers.

Example:

docker run --rm playwright-java-framework

docker run --rm playwright-java-framework

docker run --rm playwright-java-framework

Each container executes in an isolated environment.


Best Practices

Keep Images Small

Use lightweight base images where possible and avoid installing unnecessary packages.


Use Headless Browsers

Containers typically run without a graphical interface.

Launch browsers in headless mode:

new BrowserType.LaunchOptions()
        .setHeadless(true);

Avoid Hardcoded Paths

Use relative paths or environment variables to improve portability.


Store Configuration Outside the Image

Keep URLs, credentials, and environment settings outside the Docker image.

Use:

  • Environment variables
  • Properties files
  • Secrets management

Clean Up Containers

Use:

docker run --rm

to automatically remove completed containers and avoid clutter.


Common Challenges

Browser Not Found

If browsers are missing, ensure Playwright installation is included during image creation:

playwright install --with-deps

Permission Issues

Verify that the container user has permission to read project files and write reports.


Slow Builds

To speed up builds:

  • Cache Maven dependencies.
  • Reuse Docker layers.
  • Avoid unnecessary image rebuilds.

Common Interview Questions

Why use Docker for Playwright automation?

Docker provides a consistent execution environment, making tests portable and reliable across development, testing, and CI/CD systems.


What is the purpose of a Dockerfile?

A Dockerfile defines how a Docker image is built, including the base image, dependencies, application files, and startup command.


Can Docker containers run Playwright browsers?

Yes. Containers can include Chromium, Firefox, and WebKit along with the required operating system libraries.


Why is headless execution recommended inside Docker?

Most containers do not have a graphical user interface. Running browsers in headless mode improves compatibility and performance.


How can Docker help with parallel execution?

Multiple containers can run simultaneously, allowing test suites to execute in parallel across isolated environments.


Conclusion

Docker has become an essential part of modern automation testing and DevOps workflows.

By containerizing your Playwright framework, you ensure that tests run consistently regardless of the underlying operating system or infrastructure.

In this guide, you learned how to:

  • Create a Dockerfile for a Playwright Java project
  • Build and run Docker images
  • Pass environment variables
  • Mount report directories
  • Integrate Docker with Jenkins
  • Apply enterprise best practices

With Docker in place, your Playwright framework becomes portable, reproducible, and ready for cloud-native CI/CD pipelines.

Monday, July 13, 2026

Playwright CI/CD Integration with Jenkins Using Java (Complete Guide)

Modern software development relies heavily on Continuous Integration and Continuous Delivery (CI/CD). Instead of running automation tests manually, teams execute them automatically whenever code changes are committed.

Jenkins is one of the most widely used CI/CD tools and integrates seamlessly with Playwright, Java, Maven, and TestNG.

In this guide, you'll learn how to configure Jenkins to execute Playwright automation tests and generate professional reports.


What is CI/CD?

CI/CD is a software development practice that automates building, testing, and deploying applications.

Continuous Integration (CI) focuses on:

  • Automatically building the application
  • Running unit and automation tests
  • Detecting defects early

Continuous Delivery (CD) focuses on:

  • Preparing applications for deployment
  • Delivering tested builds to staging or production environments

Automation testing plays a critical role in both stages.


Why Integrate Playwright with Jenkins?

Integrating Playwright with Jenkins provides several benefits:

  • Automatic test execution after every code commit
  • Scheduled regression testing
  • Faster feedback for developers
  • Centralized execution history
  • Integration with reporting tools like Allure
  • Support for distributed execution using Jenkins agents

Prerequisites

Before integrating Playwright with Jenkins, ensure you have:

  • Java 17 or later
  • Maven installed
  • Jenkins installed
  • Git repository containing your Playwright project
  • Playwright browser binaries installed
  • TestNG framework configured

Project Structure

Example project layout:

playwright-framework
│
├── src
├── pom.xml
├── testng.xml
├── Jenkinsfile
├── screenshots
├── videos
└── allure-results

Keeping the project organized simplifies CI/CD integration.


Step 1: Install Jenkins

Download and install Jenkins for your operating system.

After installation:

  1. Start the Jenkins service.
  2. Open the Jenkins dashboard in your browser.
  3. Unlock Jenkins using the initial administrator password.
  4. Install the recommended plugins.

Useful plugins include:

  • Git
  • Maven Integration
  • Pipeline
  • Allure Jenkins Plugin
  • HTML Publisher

Step 2: Configure Maven in Jenkins

Navigate to:

Manage Jenkins → Tools

Add a Maven installation.

Example:

  • Name: Maven-3.9
  • Install Automatically: Enabled

Jenkins will download and configure Maven for pipeline execution.


Step 3: Configure JDK

Under Manage Jenkins → Tools, configure a JDK installation.

Example:

  • Name: JDK-17
  • Install Automatically: Enabled

Ensure the JDK version matches the version used by your Playwright project.


Step 4: Connect Your Git Repository

Create a new Pipeline project.

Under Pipeline, configure:

  • Repository URL
  • Branch
  • Credentials (if required)

Whenever Jenkins triggers a build, it will fetch the latest code from Git.


Step 5: Create a Jenkinsfile

Store the following file in the root of your project.

pipeline {

    agent any

    tools {

        jdk 'JDK-17'

        maven 'Maven-3.9'
    }

    stages {

        stage('Checkout') {

            steps {

                checkout scm
            }
        }

        stage('Build') {

            steps {

                sh 'mvn clean compile'
            }
        }

        stage('Run Tests') {

            steps {

                sh 'mvn test'
            }
        }

        stage('Generate Allure Report') {

            steps {

                allure includeProperties: false,
                       results: [[path: 'allure-results']]
            }
        }
    }
}

Note: On Windows Jenkins agents, replace sh with bat.


Step 6: Execute the Pipeline

Click Build Now.

Jenkins will execute the pipeline in the following order:

  1. Clone the Git repository
  2. Build the Maven project
  3. Execute Playwright tests
  4. Generate Allure reports
  5. Display build status

Step 7: View Test Results

After execution, Jenkins displays:

  • Build status
  • Console output
  • Execution time
  • Test summary
  • Allure report link

This provides a centralized view of automation results.


Scheduling Automated Test Runs

Regression suites can be executed automatically using Jenkins schedules.

Example schedule:

H 2 * * *

This runs the job daily at approximately 2 AM, helping teams validate nightly builds.


Trigger Builds Automatically

Instead of scheduling builds, Jenkins can trigger jobs whenever new code is pushed to Git.

Common triggers include:

  • GitHub Webhooks
  • GitLab Webhooks
  • Bitbucket Webhooks
  • Poll SCM

This enables continuous integration.


Archive Test Artifacts

Store useful execution artifacts for debugging.

Examples:

  • Screenshots
  • Videos
  • Logs
  • HTML reports
  • Allure results

Artifact archiving allows failed test evidence to be reviewed even after the build completes.


Best Practices

Keep Pipelines Small

Separate:

  • Build
  • Test
  • Report
  • Deploy

This improves readability and troubleshooting.


Execute Smoke Tests First

Run smoke tests before regression suites.

If smoke tests fail, stop the pipeline early to save execution time.


Use Environment Variables

Store configurable values such as:

  • Base URL
  • Browser
  • Credentials
  • API keys

Avoid hardcoding them in source code.


Keep Browser Execution Headless

For CI/CD pipelines, run browsers in headless mode unless visual debugging is required.


Publish Reports

Generate reports for every build, regardless of success or failure.

This helps identify trends over time.


Sample CI/CD Flow

Developer Commit

        │

        ▼

Git Repository

        │

        ▼

Jenkins Pipeline

        │

        ▼

Maven Build

        │

        ▼

Playwright Tests

        │

        ▼

Allure Report

        │

        ▼

Email / Slack Notification

Common Interview Questions

Why integrate Playwright with Jenkins?

To automate test execution as part of the CI/CD pipeline, providing fast feedback and reducing manual effort.


What is a Jenkinsfile?

A Jenkinsfile defines the CI/CD pipeline as code, making build processes version-controlled and repeatable.


How can Jenkins trigger Playwright tests?

  • Manual execution
  • Scheduled jobs
  • Git webhooks
  • SCM polling

Why run Playwright in headless mode in Jenkins?

Headless execution consumes fewer resources and is better suited for server environments.


How do you publish Allure reports in Jenkins?

Install the Allure Jenkins Plugin, generate allure-results during test execution, and configure a report generation step in the pipeline.


Conclusion

Integrating Playwright with Jenkins transforms manual test execution into an automated CI/CD workflow.

In this guide, you learned how to:

  • Configure Jenkins for Playwright projects
  • Connect a Git repository
  • Build projects with Maven
  • Execute TestNG tests
  • Generate Allure reports
  • Schedule automated executions
  • Follow enterprise CI/CD best practices

A well-designed Jenkins pipeline improves software quality, accelerates release cycles, and provides continuous feedback to development teams. As your automation framework evolves, integrating it with CI/CD becomes an essential step toward building a production-ready testing solution.

Sunday, July 12, 2026

Playwright Data-Driven Testing with TestNG and Excel Using Java (Complete Step-by-Step Guide)

In real-world automation projects, hardcoding test data inside test scripts makes maintenance difficult. As applications evolve, test data changes frequently, and updating Java code for every change is inefficient.

Data-driven testing solves this problem by separating test logic from test data. Instead of embedding usernames, passwords, and other values directly in your test methods, you store them in external sources such as Excel files, CSV files, or databases.

In this tutorial, you'll learn how to build a data-driven Playwright framework using Java, TestNG, and Excel.


What is Data-Driven Testing?

Data-driven testing is a testing approach where the same test executes multiple times using different sets of input data.

For example, instead of writing separate login tests:

  • Login with Admin
  • Login with Manager
  • Login with Employee

You write one test and supply different credentials from an Excel sheet.

Benefits include:

  • Reduced code duplication
  • Easier maintenance
  • Better test coverage
  • Separation of test logic and data
  • Improved scalability

Project Structure

A clean folder structure helps keep the framework organized.

playwright-framework
│
├── src
│   ├── main
│   │    ├── pages
│   │    ├── utils
│   │    └── base
│   │
│   └── test
│        ├── tests
│        ├── resources
│        │     └── testdata
│        │            └── LoginData.xlsx
│        └── dataproviders
│
├── pom.xml
└── testng.xml

Step 1: Add Apache POI Dependencies

Apache POI is the most commonly used Java library for reading Excel files.

Add these dependencies to your pom.xml.

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.4.1</version>
</dependency>

Refresh your Maven project after saving the file.


Step 2: Create an Excel File

Create an Excel file named LoginData.xlsx.

Example:

UsernamePassword
adminAdmin@123
managerManager@123
employeeEmployee@123

Store the file under:

src/test/resources/testdata

Step 3: Create an Excel Utility Class

Use Apache POI to read Excel data.

public class ExcelUtils {

    public static Object[][] getLoginData() throws Exception {

        FileInputStream fis =
                new FileInputStream(
                "src/test/resources/testdata/LoginData.xlsx");

        Workbook workbook =
                WorkbookFactory.create(fis);

        Sheet sheet =
                workbook.getSheetAt(0);

        int rows = sheet.getPhysicalNumberOfRows();

        int columns =
                sheet.getRow(0).getLastCellNum();

        Object[][] data =
                new Object[rows - 1][columns];

        for (int i = 1; i < rows; i++) {

            for (int j = 0; j < columns; j++) {

                data[i - 1][j] =
                        sheet.getRow(i)
                             .getCell(j)
                             .toString();
            }
        }

        workbook.close();
        fis.close();

        return data;
    }
}

This utility reads the Excel file and returns a two-dimensional array suitable for TestNG.


Step 4: Create a DataProvider

Create a TestNG DataProvider.

@DataProvider(name = "loginData")

public Object[][] loginData()
throws Exception {

    return ExcelUtils.getLoginData();
}

The DataProvider supplies data to your test methods.


Step 5: Create a Login Page

Example Page Object.

public class LoginPage {

    private final Page page;

    public LoginPage(Page page) {

        this.page = page;
    }

    public void login(
            String username,
            String password) {

        page.fill("#username", username);

        page.fill("#password", password);

        page.click("#loginButton");
    }
}

Step 6: Create the Test Class

Use the DataProvider.

public class LoginTest extends BaseTest {

    @Test(dataProvider = "loginData",
          dataProviderClass =
          LoginDataProvider.class)

    public void verifyLogin(
            String username,
            String password) {

        page.navigate(
            "https://example.com/login");

        LoginPage login =
                new LoginPage(page);

        login.login(
                username,
                password);

        assertThat(page)
                .hasURL(
                "https://example.com/dashboard");
    }
}

TestNG executes the same test once for every row in the Excel sheet.


Execution Flow

Suppose your Excel contains three rows.

UsernamePassword
adminAdmin@123
managerManager@123
employeeEmployee@123

Execution:

Run 1 → admin

Run 2 → manager

Run 3 → employee

Only one test method is required.


Handling Different Data Types

Excel may contain:

  • Strings
  • Numbers
  • Dates
  • Booleans

Use Apache POI's DataFormatter to safely convert values.

Example:

DataFormatter formatter =
        new DataFormatter();

String value =
        formatter.formatCellValue(cell);

This preserves the displayed cell value and avoids formatting issues.


Parameterizing Different Test Scenarios

Data-driven testing isn't limited to login.

You can store:

  • Search keywords
  • Product IDs
  • Customer details
  • Payment information
  • API request data
  • Form inputs

The same approach can drive a wide variety of tests.


Best Practices

Keep Test Data Separate

Store test data outside Java classes.

Recommended locations:

  • Excel
  • JSON
  • CSV
  • YAML
  • Database

Avoid Duplicate Data

Use reusable datasets instead of copying values across multiple files.


Name Worksheets Clearly

Good examples:

  • LoginData
  • SearchData
  • PaymentData

Avoid generic names such as:

  • Sheet1
  • Test

Close Resources

Always close:

  • Workbook
  • FileInputStream

This prevents memory leaks and file locking issues.


Validate Expected Results

Don't verify only that a test runs.

Validate:

  • Successful login
  • Error messages
  • Dashboard visibility
  • Business rules

Common Interview Questions

What is Data-Driven Testing?

A testing approach where one test executes multiple times using different datasets.


Which library is commonly used to read Excel in Java?

Apache POI.


What is the purpose of TestNG's DataProvider?

It supplies multiple sets of data to a single test method, allowing the same test to run repeatedly with different inputs.


Can Playwright execute data-driven tests in parallel?

Yes. TestNG DataProviders can be combined with parallel execution, provided that browser sessions and test data remain thread-safe.


When should you use Excel instead of hardcoded values?

Excel is useful when test data changes frequently, is maintained by non-developers, or must support many test combinations. For API payloads or structured data, JSON may be a better choice.


Conclusion

Data-driven testing is a key technique for building scalable automation frameworks.

By combining Playwright, Java, TestNG, and Apache POI, you can separate test logic from test data, improve maintainability, and increase test coverage without duplicating code.

In this tutorial, you learned how to:

  • Read Excel data using Apache POI
  • Create a TestNG DataProvider
  • Execute Playwright tests with multiple datasets
  • Organize a maintainable framework
  • Follow best practices for enterprise automation

Once you've mastered data-driven testing, you'll be well prepared to build automation frameworks used in large enterprise applications.

Friday, July 10, 2026

Playwright Parallel Execution with TestNG Using Java (Complete Step-by-Step Guide)

As automation test suites grow, execution time also increases. Running hundreds of tests sequentially can take hours, slowing down development and delaying feedback.

Parallel execution solves this problem by running multiple tests simultaneously. Combined with Playwright's modern browser automation capabilities and TestNG's parallel execution features, you can significantly reduce execution time while maintaining reliable and scalable test automation.

In this guide, you'll learn how to configure parallel execution in Playwright using Java and TestNG.


Why Run Tests in Parallel?

Parallel execution offers several advantages:

  • Faster test execution
  • Reduced CI/CD pipeline duration
  • Better utilization of system resources
  • Quicker feedback for developers
  • Improved productivity for QA teams

For example:

Number of Tests Sequential Execution Parallel Execution (4 Threads)
100100 minutes25–30 minutes
500500 minutes130–150 minutes

The actual improvement depends on your application, hardware, and test design.


Understanding Thread Safety

Each test running in parallel must use its own isolated browser session.

Avoid sharing these objects across threads:

  • Playwright
  • BrowserContext
  • Page

Each test should create its own browser context to prevent data leakage and flaky tests.


BaseTest Class

Create browser resources for every test.

public class BaseTest {

    protected Playwright playwright;
    protected Browser browser;
    protected BrowserContext context;
    protected Page page;

    @BeforeMethod
    public void setup() {

        playwright = Playwright.create();

        browser = playwright.chromium()
                .launch(new BrowserType.LaunchOptions()
                        .setHeadless(true));

        context = browser.newContext();

        page = context.newPage();
    }

    @AfterMethod(alwaysRun = true)
    public void tearDown() {

        context.close();
        browser.close();
        playwright.close();
    }
}

Each test receives its own independent browser environment.


Creating Test Classes

Example:

public class LoginTest extends BaseTest {

    @Test
    public void verifyLogin() {

        page.navigate("https://example.com");

        page.locator("#username")
                .fill("admin");

        page.locator("#password")
                .fill("password");

        page.locator("#login")
                .click();
    }
}

You can create multiple test classes following the same pattern.


Configure TestNG for Parallel Execution

Update your testng.xml.

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">

<suite name="Playwright Suite"
       parallel="methods"
       thread-count="4">

    <test name="Regression Tests">

        <classes>

            <class name="tests.LoginTest"/>
            <class name="tests.SearchTest"/>
            <class name="tests.CartTest"/>

        </classes>

    </test>

</suite>

In this configuration:

  • parallel="methods" runs test methods simultaneously.
  • thread-count="4" allows up to four concurrent threads.

Parallel Execution Options

TestNG supports multiple execution modes.

Methods

Runs individual test methods in parallel.

parallel="methods"

Best for independent tests.


Classes

Runs entire classes in parallel.

parallel="classes"

Each class gets its own thread.


Tests

Runs <test> sections in parallel.

parallel="tests"

Useful for separating smoke, regression, or browser-specific suites.


Instances

Runs different object instances simultaneously.

parallel="instances"

Typically used with data-driven testing.


Running Tests on Multiple Browsers

Parameterize your tests to execute on different browsers.

Example:

@Parameters("browser")
@BeforeMethod
public void setup(String browserName) {

    playwright = Playwright.create();

    if ("chromium".equalsIgnoreCase(browserName)) {

        browser = playwright.chromium().launch();

    } else if ("firefox".equalsIgnoreCase(browserName)) {

        browser = playwright.firefox().launch();

    } else {

        browser = playwright.webkit().launch();
    }

    context = browser.newContext();

    page = context.newPage();
}

This enables cross-browser execution with minimal code changes.


Common Challenges

Shared Test Data

Avoid using the same user account across parallel tests.

Instead:

  • Create unique test users.
  • Generate dynamic test data.
  • Clean up data after execution.

Shared Files

Avoid writing to the same file from multiple threads.

Instead:

  • Create thread-specific filenames.
  • Use timestamp-based naming.

Example:

Report_Thread1.html
Report_Thread2.html

Browser Context Isolation

Always create a new BrowserContext for each test.

context = browser.newContext();

Never reuse contexts between threads.


Best Practices

Keep Tests Independent

Each test should execute successfully regardless of execution order.


Avoid Static Variables

Static objects may be shared across threads, leading to unpredictable behavior.


Use Explicit Assertions

Verify business outcomes such as:

  • Successful login
  • Order creation
  • Payment confirmation

Avoid relying solely on page titles or URLs.


Capture Screenshots on Failure

Integrate screenshots into your reporting solution (such as Allure) for easier debugging.


Monitor Resource Usage

Parallel execution increases CPU and memory usage.

Choose a thread count appropriate for your machine and CI/CD agents.


Performance Tips

  • Run headless in CI/CD environments.
  • Reuse browser binaries instead of reinstalling them.
  • Execute smoke tests before full regression suites.
  • Use separate environments when running large parallel suites.

Common Interview Questions

Can Playwright execute tests in parallel?

Yes. Playwright supports parallel execution, and when combined with TestNG, multiple tests can run simultaneously.


Why should each test use its own BrowserContext?

A BrowserContext isolates cookies, storage, and session data. Separate contexts prevent interference between parallel tests.


What happens if Page objects are shared across threads?

Tests may overwrite each other's actions, causing flaky failures and inconsistent results.


Which TestNG parallel mode is most commonly used?

parallel="methods" is widely used because it provides good scalability for independent test cases.


Conclusion

Parallel execution is one of the most effective ways to reduce automation execution time and improve feedback cycles.

In this guide, you learned how to:

  • Configure parallel execution with TestNG
  • Build thread-safe Playwright tests
  • Execute tests across multiple browsers
  • Avoid common concurrency issues
  • Apply enterprise best practices

By combining Playwright, Java, and TestNG, you can create fast, scalable, and reliable automation frameworks that meet the demands of modern software development and CI/CD pipelines.

Thursday, July 9, 2026

Playwright Reporting with Allure Reports Using Java (Complete Step-by-Step Guide)

Automation testing is not just about executing test cases—it's also about presenting the results in a clear and meaningful way. While TestNG provides basic HTML reports, enterprise teams often use Allure Reports because they offer interactive dashboards, screenshots, execution history, attachments, and detailed failure analysis.

In this guide, you'll learn how to integrate Allure Reports with Playwright using Java and TestNG.


Why Use Allure Reports?

Allure Reports provide:

  • Interactive HTML reports
  • Test execution history
  • Test categorization
  • Screenshots for failed tests
  • Video attachments
  • Environment information
  • Timeline view
  • Easy CI/CD integration

Compared to standard TestNG reports, Allure makes debugging faster and reporting more professional.


Prerequisites

Before starting, ensure you have:

  • Java 17 or later
  • Maven installed
  • Playwright project
  • TestNG framework
  • Browser binaries installed

Step 1: Add Maven Dependencies

Add the following dependencies to your pom.xml.

<dependencies>

    <dependency>
        <groupId>io.qameta.allure</groupId>
        <artifactId>allure-testng</artifactId>
        <version>2.30.0</version>
    </dependency>

    <dependency>
        <groupId>com.microsoft.playwright</groupId>
        <artifactId>playwright</artifactId>
        <version>1.55.0</version>
    </dependency>

</dependencies>

Refresh your Maven project after saving the file.


Step 2: Configure Maven Surefire Plugin

Add the Surefire plugin to enable TestNG execution.

<build>

<plugins>

<plugin>

<groupId>org.apache.maven.plugins</groupId>

<artifactId>maven-surefire-plugin</artifactId>

<version>3.5.3</version>

</plugin>

</plugins>

</build>

Step 3: Execute the Tests

Run your TestNG suite.

mvn clean test

During execution, Allure stores raw result files inside:

allure-results/

Each test generates JSON files containing execution details.


Step 4: Generate the Report

Once execution is complete, generate the HTML report.

allure serve allure-results

This command:

  • Builds the report
  • Starts a local server
  • Opens the report automatically in your browser

Understanding the Report Dashboard

The Allure dashboard provides valuable insights.

You'll find:

  • Total tests
  • Passed tests
  • Failed tests
  • Skipped tests
  • Duration
  • Success rate

This overview helps teams quickly assess test health.


Test Details

Clicking a test reveals:

  • Execution steps
  • Attachments
  • Error messages
  • Stack traces
  • Screenshots
  • Execution time

This detailed view speeds up root cause analysis.


Adding Screenshots to Allure

Capturing screenshots on failures greatly improves debugging.

Example helper method:

@Attachment(
value = "Failure Screenshot",
type = "image/png"
)

public byte[] attachScreenshot(Page page){

    return page.screenshot();

}

When called during a failed test, the screenshot is embedded directly in the report.


Attaching Text Logs

You can also include custom logs.

@Attachment(
value = "Execution Log",
type = "text/plain"
)

public String attachLog(String message){

    return message;

}

This is useful for recording API responses, SQL queries, or business events.


Attaching Videos

If Playwright records execution videos, attach them to the report.

@Attachment(
value = "Execution Video",
type = "video/webm"
)

public byte[] attachVideo(Path path)
throws IOException{

    return Files.readAllBytes(path);

}

Videos are invaluable when debugging intermittent failures.


Adding Test Descriptions

Allure supports annotations that make reports more readable.

@Description("Verify successful login using valid credentials")

@Test

public void loginTest(){

}

Descriptions appear directly in the report.


Categorizing Tests

Use features and stories to organize tests.

@Feature("Authentication")

@Story("Login")

@Test

public void loginTest(){

}

Reports become easier to navigate, especially in large projects.


Organizing the Project

Recommended folder structure:

project

├── allure-results

├── allure-report

├── screenshots

├── videos

├── src

├── pom.xml

└── testng.xml

Keeping artifacts separate improves project organization.


Best Practices

Capture Screenshots Only on Failure

Avoid capturing screenshots for every successful test to reduce storage usage.


Add Meaningful Descriptions

Use annotations to explain the purpose of each test.


Attach Logs for Failed Scenarios

Include:

  • API responses
  • Request payloads
  • Browser console logs
  • Custom debug messages

These details make troubleshooting much easier.


Store Environment Information

Create an environment.properties file containing details such as:

  • Browser
  • Operating system
  • Java version
  • Playwright version
  • Test environment

This information appears in the report and helps reproduce issues.


Archive Reports in CI/CD

When running tests in Jenkins, GitHub Actions, or Azure DevOps, archive the generated Allure reports as build artifacts. This allows team members to review historical execution results.


Common Interview Questions

Why is Allure preferred over the default TestNG report?

Because it provides interactive reports with screenshots, attachments, execution history, and a richer user experience.


How do you generate an Allure report?

Execute the tests and then run:

allure serve allure-results

Can Allure attach screenshots automatically?

Yes. By using the @Attachment annotation and capturing screenshots during test failures.


What types of files can be attached to Allure reports?

  • Screenshots
  • Videos
  • Text logs
  • JSON responses
  • XML files
  • PDFs
  • Any file that helps explain the test outcome

Conclusion

A good reporting solution is essential for every automation framework.

Allure Reports transform raw test execution data into an interactive, easy-to-understand dashboard that helps testers, developers, and managers quickly identify issues.

In this guide, you learned how to:

  • Integrate Allure with Playwright
  • Configure Maven
  • Generate reports
  • Attach screenshots, videos, and logs
  • Organize test results
  • Follow enterprise reporting best practices

By combining Playwright, TestNG, and Allure Reports, you can build a professional automation framework that is scalable, maintainable, and ready for enterprise projects.

Wednesday, July 8, 2026

Playwright TestNG Framework Setup Using Java (Step-by-Step Guide)

As automation projects grow, writing standalone Playwright scripts becomes difficult to maintain. Enterprise teams use testing frameworks like TestNG to organize test execution, manage test suites, perform assertions, generate reports, and execute tests in parallel.

In this guide, we'll build a Playwright TestNG framework from scratch using Java and follow industry best practices.


Why Use TestNG with Playwright?

TestNG offers several features that complement Playwright:

  • Test annotations (@Test, @BeforeMethod, @AfterMethod)
  • Test grouping
  • Parallel execution
  • Parameterized tests
  • Test dependencies
  • HTML reports
  • Easy integration with CI/CD tools

Combining Playwright with TestNG results in a scalable and maintainable automation framework.


Prerequisites

Before starting, ensure you have:

  • Java 17 or later
  • Maven installed
  • IntelliJ IDEA or Eclipse
  • Basic knowledge of Playwright
  • Browser binaries installed

Step 1: Create a Maven Project

Create a new Maven project in your IDE.

Suggested structure:

playwright-testng-framework
│
├── src
│   ├── main
│   │    └── java
│   │         ├── pages
│   │         ├── utils
│   │         └── base
│   │
│   └── test
│        └── java
│             └── tests
│
├── testng.xml
├── pom.xml
└── README.md

Step 2: Add Dependencies

Add the required dependencies to your pom.xml.

<dependencies>

    <dependency>
        <groupId>com.microsoft.playwright</groupId>
        <artifactId>playwright</artifactId>
        <version>1.55.0</version>
    </dependency>

    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.11.0</version>
        <scope>test</scope>
    </dependency>

</dependencies>

Refresh the Maven project after saving the file.


Step 3: Create the BaseTest Class

The BaseTest class is responsible for browser setup and cleanup.

public class BaseTest {

    protected Playwright playwright;
    protected Browser browser;
    protected BrowserContext context;
    protected Page page;

    @BeforeMethod
    public void setup() {

        playwright = Playwright.create();

        browser = playwright.chromium().launch(
                new BrowserType.LaunchOptions()
                        .setHeadless(false));

        context = browser.newContext();

        page = context.newPage();
    }

    @AfterMethod
    public void tearDown() {

        context.close();
        browser.close();
        playwright.close();
    }
}

This ensures every test starts with a fresh browser session.


Step 4: Create a Page Object

Example LoginPage.java.

public class LoginPage {

    private final Page page;

    public LoginPage(Page page) {
        this.page = page;
    }

    public void login(String username, String password) {

        page.fill("#username", username);

        page.fill("#password", password);

        page.click("#loginButton");
    }
}

Keeping page interactions separate improves maintainability.


Step 5: Create Your First Test

Create a TestNG test class.

public class LoginTest extends BaseTest {

    @Test

    public void verifySuccessfulLogin() {

        page.navigate("https://example.com/login");

        LoginPage loginPage =
                new LoginPage(page);

        loginPage.login(
                "admin",
                "password123");

        assertThat(page)
                .hasTitle("Dashboard");
    }
}

Notice how the test focuses only on business logic while setup is handled by BaseTest.


Step 6: Create testng.xml

TestNG uses an XML file to define test suites.

<!DOCTYPE suite SYSTEM
"https://testng.org/testng-1.0.dtd">

<suite name="Playwright Suite">

    <test name="Smoke Tests">

        <classes>

            <class name="tests.LoginTest"/>

        </classes>

    </test>

</suite>

You can execute all tests by running this suite file.


Step 7: Execute Tests

You can run tests in several ways:

  • Directly from IntelliJ IDEA
  • Using Eclipse
  • From Maven
  • Through Jenkins or another CI/CD pipeline

Example Maven command:

mvn test

Parallel Execution

TestNG supports parallel execution through testng.xml.

Example:

<suite name="Playwright Suite"
       parallel="methods"
       thread-count="4">

</suite>

This executes four test methods simultaneously, reducing execution time.


Adding Groups

TestNG groups help organize test cases.

Example:

@Test(groups = {"Smoke"})
public void loginTest() {

}

You can create groups such as:

  • Smoke
  • Regression
  • Sanity
  • API
  • UI

Generating Reports

After execution, TestNG automatically creates reports inside the test-output folder.

Common reports include:

  • HTML report
  • Failed test report
  • Execution summary

These reports provide quick insight into test results.


Recommended Framework Structure

As your project grows, consider organizing it like this:

src
├── main
│   ├── base
│   ├── pages
│   ├── utils
│   ├── constants
│   └── listeners
│
├── test
│   ├── tests
│   ├── testdata
│   └── resources
│
├── reports
├── screenshots
├── videos
└── testng.xml

This structure is easy to maintain and scales well for enterprise projects.


Best Practices

Keep Test Logic Separate

Business actions belong in page classes, not in test methods.


Reuse Browser Initialization

Initialize Playwright once in the base class instead of repeating code.


Use Assertions Wisely

Verify business outcomes rather than implementation details.

Examples:

  • User logged in successfully
  • Order created
  • Invoice downloaded

Capture Screenshots on Failure

Integrate screenshot capture inside the @AfterMethod hook for failed tests.


Store Test Data Separately

Avoid hardcoding values.

Instead, use:

  • JSON
  • Excel
  • CSV
  • Properties files

Common Interview Questions

Why combine Playwright with TestNG?

TestNG provides test lifecycle management, reporting, grouping, parameterization, and parallel execution, making Playwright projects easier to manage.


What is the purpose of @BeforeMethod?

It runs before every test method and is commonly used to initialize the browser and create a new page.


What is the role of BaseTest?

BaseTest centralizes browser setup and cleanup, reducing code duplication across test classes.


Can Playwright tests run in parallel with TestNG?

Yes. By configuring parallel and thread-count in testng.xml, multiple tests can run simultaneously.


Conclusion

Using Playwright with TestNG is an excellent choice for building robust and maintainable Java automation frameworks.

In this tutorial, you learned how to:

  • Create a Maven project
  • Add Playwright and TestNG dependencies
  • Build a reusable BaseTest
  • Implement the Page Object Model
  • Configure testng.xml
  • Execute tests
  • Enable parallel execution
  • Apply framework best practices

With this foundation, you're ready to build enterprise-grade automation frameworks that are scalable, reusable, and easy to integrate with CI/CD pipelines.