Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Microsoft Playwright Test Function

From Leeroopedia
Knowledge Sources
Domains Testing, Browser_Automation
Last Updated 2026-02-11 00:00 GMT

Overview

Concrete tool for structuring test code into executable test cases with grouping, hooks, and fixtures, provided by the Playwright library.

Description

The test function is the core API for defining test cases in Playwright Test. It is exported from the @playwright/test package and serves as both a function (for defining individual tests) and a namespace (for accessing describe, beforeEach, afterEach, beforeAll, afterAll, and other organizational methods).

Internally, the test function is implemented in testType.ts as a TestTypeImpl class. When test(title, body) is called, it creates a TestCase object and registers it in the current Suite. The test.describe() method creates nested Suite instances. Lifecycle hooks like test.beforeEach() push hook functions onto the current suite's hook arrays. All registration uses wrapFunctionWithLocation to capture source locations for error reporting.

The test body function receives fixtures as its argument. Playwright's built-in fixtures include page, context, browser, and request. Custom fixtures can be defined using test.extend(), which creates a new test type with additional fixtures available.

Usage

Use the test function in every Playwright test file to define individual test cases. Use test.describe to group related tests. Use test.beforeEach and test.afterEach for shared setup and teardown. Use test.extend when custom fixtures are needed across multiple test files.

Code Reference

Source Location

  • Repository: playwright
  • File: packages/playwright/src/common/testType.ts (lines 39-184)

Signature

// Define a test case
function test(title: string, body: (args: PlaywrightTestArgs & PlaywrightTestOptions, testInfo: TestInfo) => Promise<void> | void): void;

// Define a test case with additional details
function test(title: string, details: TestDetails, body: (args: PlaywrightTestArgs & PlaywrightTestOptions, testInfo: TestInfo) => Promise<void> | void): void;

// Group tests into a describe block
test.describe(title: string, callback: () => void): void;

// Define a beforeEach hook
test.beforeEach(fn: (args: PlaywrightTestArgs & PlaywrightTestOptions, testInfo: TestInfo) => Promise<void> | void): void;

// Define an afterEach hook
test.afterEach(fn: (args: PlaywrightTestArgs & PlaywrightTestOptions, testInfo: TestInfo) => Promise<void> | void): void;

// Define a beforeAll hook
test.beforeAll(fn: (args: PlaywrightWorkerArgs & PlaywrightWorkerOptions, workerInfo: WorkerInfo) => Promise<void> | void): void;

// Define an afterAll hook
test.afterAll(fn: (args: PlaywrightWorkerArgs & PlaywrightWorkerOptions, workerInfo: WorkerInfo) => Promise<void> | void): void;

// Extend test with custom fixtures
test.extend<T>(fixtures: Fixtures<T>): TestType<PlaywrightTestArgs & T, PlaywrightWorkerArgs>;

Import

import { test } from '@playwright/test';

I/O Contract

Inputs

Name Type Required Description
title string Yes The name of the test case or describe block. Used for identification, filtering, and reporting.
details TestDetails No Optional object with tag and annotation fields for categorizing and annotating tests.
body Function Yes The test body function that receives destructured fixtures (e.g., { page }) and a TestInfo object. For test.describe, this is a synchronous callback that contains nested test() calls.
fn (hooks) Function Yes Hook function for beforeEach, afterEach, beforeAll, afterAll. Receives the same fixture arguments as test bodies.
fnOrDetails TestDetails Yes For the overloaded form, either the test body directly or a TestDetails object followed by the body.

Outputs

Name Type Description
TestCase TestCase (internal) Calling test() registers a TestCase instance in the current Suite. This is an internal data structure used by the test runner.
Suite Suite (internal) Calling test.describe() creates a nested Suite within the current suite hierarchy.
Hook registration void Calling test.beforeEach() or similar methods pushes the hook function onto the current suite's hook array.

Usage Examples

Basic Example

import { test, expect } from '@playwright/test';

test('has title', async ({ page }) => {
  await page.goto('https://playwright.dev/');
  await expect(page).toHaveTitle(/Playwright/);
});

test('get started link', async ({ page }) => {
  await page.goto('https://playwright.dev/');
  await page.getByRole('link', { name: 'Get started' }).click();
  await expect(page).toHaveURL(/.*intro/);
});

Describe and Hooks Example

import { test, expect } from '@playwright/test';

test.describe('navigation', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('https://playwright.dev/');
  });

  test('main navigation', async ({ page }) => {
    await expect(page.getByRole('link', { name: 'Docs' })).toBeVisible();
  });

  test('search functionality', async ({ page }) => {
    await page.getByRole('button', { name: 'Search' }).click();
    await expect(page.getByRole('dialog')).toBeVisible();
  });
});

Custom Fixtures Example

import { test as base, expect } from '@playwright/test';

type MyFixtures = {
  todoPage: Page;
};

const test = base.extend<MyFixtures>({
  todoPage: async ({ page }, use) => {
    await page.goto('https://demo.playwright.dev/todomvc');
    await use(page);
  },
});

test('should add a todo item', async ({ todoPage }) => {
  await todoPage.getByPlaceholder('What needs to be done?').fill('Buy milk');
  await todoPage.getByPlaceholder('What needs to be done?').press('Enter');
  await expect(todoPage.getByTestId('todo-title')).toHaveText('Buy milk');
});

Related Pages

Implements Principle

Requires Environment

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment