How to Read Data from Excel in Playwright

Cody Schneider••7 min read

Automating tests with Playwright is a game-changer, but hardcoding test data directly into your scripts can quickly turn your clean code into a maintenance nightmare. Tying your tests to data from an Excel spreadsheet is an elegant solution, allowing you to separate test logic from test data. This article will walk you step-by-step through how to read data from an Excel file and use it to power your data-driven Playwright tests.

GraphedGraphed

Build AI Agents for Marketing

Build virtual employees that run your go to market. Connect your data sources, deploy autonomous agents, and grow your company.

Watch Graphed demo video

Why Bother with Excel for Your Test Data?

Before diving into the "how," let's quickly cover the "why." Using external data sources, especially something as common as Excel, offers several practical advantages for test automation:

  • Data-Driven Testing: This is the biggest win. You can design one test script, like a login flow, and run it dozens of times with different data sets (e.g., valid users, invalid users, users with different permission levels). You just add a new row to your spreadsheet to create a new test case.
  • Separation of Concerns: Your test logic (the code that navigates, clicks, and asserts) remains separate from your test data. This makes your scripts cleaner, shorter, and much easier to read and maintain. If a username or password changes, you update the spreadsheet, not the code.
  • Accessibility for Everyone: Not everyone on your team is a developer. Product managers, business analysts, and QA specialists are often more comfortable working in Excel than in a code editor. This approach empowers them to contribute to the testing process by creating and managing test scenarios directly in a spreadsheet.
  • Better Scalability: Need to test 100 different product variations? Instead of writing 100 tests, you write one test and add 100 rows to your Excel file. This approach is far more scalable and efficient as your application grows in complexity.

Getting Started: Your Project Setup

To get things rolling, you first need a Playwright project and a library to handle the Excel file interaction. Playwright doesn't read Excel files out of the box, but a simple package from npm solves this easily.

1. Initialize Your Playwright Project

If you're starting from scratch, open your terminal and initialize a new Playwright project. If you already have one, you can skip this step.

npm init playwright@latest

Follow the on-screen prompts to configure your project. Playwright will set up the necessary file structure and configuration for you.

2. Install a Library to Read Excel Files

There are several libraries for handling Excel files in Node.js. One of the most popular and straightforward is ExcelJS. It has great documentation and handles modern .xlsx files without any issues.

Install it in your project using npm:

npm install exceljs

Free PDF · the crash course

AI Agents for Marketing Crash Course

Learn how to deploy AI marketing agents across your go-to-market — the best tools, prompts, and workflows to turn your data into autonomous execution without writing code.

3. Create Your Test Data File

Now, create a simple Excel file. Let's call it testData.xlsx and save it in the root of your project directory. For this tutorial, we'll create test data for a login form.

Open the spreadsheet and create two sheets: validUsers and invalidUsers. In the validUsers sheet, add the following data:

Sheet: validUsers

The column headers (username, password, expectedUrl) are important, as we'll use them to create structured data objects.

Creating a Reusable Function to Read Excel Data

To keep our code clean, we'll create a dedicated helper function to read the Excel file and parse its contents. This makes the logic reusable across multiple test files.

Create a new file in your project, perhaps in a utils folder, named excelReader.js.

// utils/excelReader.js

const ExcelJS = require('exceljs'),
const path = require('path'),

async function readExcel(fileName, sheetName) {
    // Construct the absolute path to the Excel file
    const filePath = path.join(__dirname, '..', fileName),
    const workbook = new ExcelJS.Workbook(),

    try {
        await workbook.xlsx.readFile(filePath),
        const worksheet = workbook.getWorksheet(sheetName),

        if (!worksheet) {
            throw new Error(`Sheet "${sheetName}" not found in ${fileName}`),
        }

        const data = [],
        // The first row is the header row
        const headerRow = worksheet.getRow(1).values,

        // Start from the second row to read the actual data
        worksheet.eachRow({ includeEmpty: false }, (row, rowNumber) => {
            if (rowNumber > 1) {
                let rowData = {},
                // Map header names to row values
                row.values.forEach((value, index) => {
                    const header = headerRow[index],
                    if (header) {
                        rowData[header] = value,
                    }
                }),
                data.push(rowData),
            }
        }),

        return data,
    } catch (error) {
        console.error("Error reading Excel file:", error),
        throw error, // Rethrow the error to fail the test if data can't be read
    }
}

module.exports = { readExcel },
GraphedGraphed

Build AI Agents for Marketing

Build virtual employees that run your go to market. Connect your data sources, deploy autonomous agents, and grow your company.

Watch Graphed demo video

Breaking Down the Code Script:

  • Import Libraries: We import exceljs to work with the spreadsheet and path to help locate the file correctly, regardless of where we run the tests from.
  • Define the Function: The function is async because file I/O operations are asynchronous in Node.js. It takes fileName and sheetName as arguments to make it versatile.
  • Load the Workbook: It creates a new Workbook instance and uses readFile() to load our testData.xlsx.
  • Get the Worksheet: It grabs the specific sheet we're interested in using getWorksheet(sheetName).
  • Parse the Data: It iterates through each row, identifies the first row as the header, and then creates a JavaScript object for each subsequent row, using the header values as keys.
  • Return Data: It returns an array of these objects, perfect for looping through in our test.
  • Error Handling: A try...catch block ensures that if the file doesn't exist or a sheet name is wrong, our test fails with a clear message.

Putting It All Together: Using the Data in a Playwright Test

With our helper function ready, let's wire it up to a Playwright test. We'll create a login test for the Sauce Demo website.

Create a new test file, for instance, in the tests folder, named login.spec.js.

// tests/login.spec.js

const { test, expect } = require('@playwright/test'),
const { readExcel } = require('../utils/excelReader'),

// Load Data From Excel
const testData = await readExcel('testData.xlsx', 'validUsers'),

test.describe('Sauce Demo Login Tests - Data-Driven from Excel', () => {
    // Use a for...of loop to iterate over the test data
    for (const data of testData) {
        test(`should login successfully as ${data.username}`, async ({ page }) => {
            await page.goto('https://www.saucedemo.com/'),

            // Fill the login form using data from the current iteration
            await page.locator('[data-test="username"]').fill(data.username),
            await page.locator('[data-test="password"]').fill(data.password),
            await page.locator('[data-test="login-button"]').click(),

            // Assert that the login was successful by checking the URL
            await expect(page).toHaveURL(data.expectedUrl),
        }),
    }
}),

Free PDF · the crash course

AI Agents for Marketing Crash Course

Learn how to deploy AI marketing agents across your go-to-market — the best tools, prompts, and workflows to turn your data into autonomous execution without writing code.

How This Test Script Works:

  1. Import Dependencies: We import the necessary modules from Playwright and our new readExcel helper function.
  2. Load Test Data: Crucially, readExcel('testData.xlsx', 'validUsers') is called once at the top level of the file. This reads the spreadsheet and loads all the test cases into the testData array before any tests start running.
  3. Create Dynamic Tests with a Loop: Instead of a single test() block, we use a for...of loop to iterate through each object in the testData array. In each iteration, a new test is generated.
  4. Custom Test Titles: We use a template literal test(should login successfully as ${data.username}) to create a unique and descriptive title for each test run.
  5. Use the Data: Inside the test function, we access the data for the current iteration using data.username, data.password, and data.expectedUrl.

Now, when you run your Playwright tests, it will execute the login test for every single row in your validUsers worksheet.

Final Thoughts

Integrating Excel with Playwright is a simple yet powerful technique that elevates your test automation strategy. It makes your tests more scalable, easier to maintain, and empowers non-technical team members to contribute directly to the testing process. By writing a reusable helper function, you can implement this data-driven approach cleanly across your entire test suite.

Automating tests saves you from manual repetition, and just as Playwright automates testing your application, your tools can automate the analysis of your business results. After you confirm your application is working, the next step is to understand how your customers are using it. Instead of manually stitching together data from Google Analytics, Salesforce, and Shopify, we built Graphed to connect all your data sources instantly. You can then ask questions in simple, natural language - like "show me which marketing campaigns are driving the most sales this month" - and get a real-time dashboard in seconds, skipping the reporting drudgery entirely.

Related Articles