Bỏ qua để vào nội dung chính
Playwright Component Testing: Test Your React Components in a Real Browser

Playwright Component Testing: Test Your React Components in a Real Browser

Bởi Isabella Chen
22 thg 3, 20267 phút đọc

Playwright Component Testing mounts real components in a real browser for testing. Learn how it differs from jsdom-based testing, when to use it, and how to write effective component tests.

Why Component Testing in a Real Browser?

Jest + React Testing Library uses jsdom — a JavaScript implementation of the DOM that runs in Node.js. It's fast but not a real browser. CSS doesn't apply correctly, browser APIs are faked, and layout-dependent behavior can't be tested. Playwright Component Testing runs your components in actual Chromium/Firefox/WebKit — what you see in tests is what users see.

Setting Up Playwright CT

npm install --save-dev @playwright/experimental-ct-react
npx playwright install
// playwright-ct.config.ts
import { defineConfig, devices } from '@playwright/experimental-ct-react';

export default defineConfig({
  testDir: './tests/components',
  snapshotDir: './tests/__snapshots__',
  timeout: 10 * 1000,
  use: {
    ctPort: 3100,
    ctViteConfig: {
      // Import your actual project CSS
      resolve: {
        alias: { '@': new URL('./src', import.meta.url).pathname }
      }
    }
  },
  projects: [
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
    { name: 'mobile', use: { ...devices['iPhone 14'] } },
  ],
});

Writing Your First Component Test

// tests/components/Button.spec.tsx
import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from '../../src/components/Button';

test.describe('Button component', () => {
  test('renders with correct text', async ({ mount }) => {
    const component = await mount(
      <Button variant="primary">Click Me</Button>
    );
    await expect(component).toContainText('Click Me');
  });

  test('calls onClick when clicked', async ({ mount }) => {
    let clicked = false;
    const component = await mount(
      <Button onClick={() => { clicked = true; }}>Click</Button>
    );
    await component.click();
    expect(clicked).toBe(true);
  });

  test('is disabled when disabled prop set', async ({ mount }) => {
    const component = await mount(
      <Button disabled>Disabled</Button>
    );
    await expect(component).toBeDisabled();
  });

  test('visual snapshot matches', async ({ mount }) => {
    const component = await mount(
      <Button variant="primary" size="lg">Submit</Button>
    );
    await expect(component).toHaveScreenshot('button-primary-lg.png');
  });
});

Testing Interactive Components

// tests/components/Dropdown.spec.tsx
test('dropdown shows options on click and selects correctly', async ({ mount }) => {
  const values: string[] = [];
  
  const component = await mount(
    <Dropdown
      options={['Option 1', 'Option 2', 'Option 3']}
      onSelect={(val) => values.push(val)}
    />
  );

  // Verify closed initially
  await expect(component.getByRole('listbox')).not.toBeVisible();

  // Open the dropdown
  await component.getByRole('button').click();
  await expect(component.getByRole('listbox')).toBeVisible();

  // Select an option
  await component.getByText('Option 2').click();
  expect(values).toEqual(['Option 2']);

  // Verify closed after selection
  await expect(component.getByRole('listbox')).not.toBeVisible();
});

When to Use Playwright CT vs RTL

  • Use RTL (React Testing Library) for: unit-level behavior tests, hook testing, fast feedback loops
  • Use Playwright CT for: visual regression, CSS-dependent behavior, cross-browser testing, complex interaction sequences

Running and CI Integration

# Run component tests
npx playwright test --config playwright-ct.config.ts

# Update visual snapshots
npx playwright test --update-snapshots --config playwright-ct.config.ts

# Run specific component
npx playwright test Button.spec.tsx --config playwright-ct.config.ts

Playwright CT and RTL are complementary. Use RTL as your default for speed; add Playwright CT for the tests that actually need a real browser environment.

Không spam, hủy đăng ký bất kỳ lúc nào.

Bài viết liên quan