DEV Community

Sergii
Sergii

Posted on Edited on

How to Test System Clipboard in Playwright (Without Boilerplate)

Testing clipboard interactions in End-to-End/Integration Playwright tests often comes with a few hidden challenges:

  1. Permissions: Browsers require explicit permissions (clipboard-read, clipboard-write) to allow clipboard access in automated environments.
  2. Flakiness: Asynchronous copy-paste operations can lead to flaky assertions if the clipboard state hasn't updated in time.
  3. JSON Handling: Parsing complex objects copied to the clipboard usually involves writing repetitive JSON.parse() wrapper functions.

To solve this cleanly, I built a lightweight open-source helper package: playwright-clipboard-testing.

Here is a quick guide on how to use it in your Playwright test suite.


Installation

Install the package as a development dependency:

npm install --save-dev playwright-clipboard-testing
Enter fullscreen mode Exit fullscreen mode

Direct Usage

If you don't use custom test fixtures, you can import test and expect directly from playwright-clipboard-testing. The package automatically grants Chromium permissions and manages the clipboard state.

import { test, expect } from 'playwright-clipboard-testing';

test('should copy text to clipboard', async ({ page, clipboard }) => {
  await page.goto('https://example.com');
  await page.locator('#copy-button').click();

  // Uses Playwright's built-in polling to wait for the expected content
  await expect(clipboard).toHaveData('Hello, World!');
});

Enter fullscreen mode Exit fullscreen mode

Testing JSON Data

If your web application serializes structured data (like table rows or state objects) into the clipboard, you can assert JSON directly:

test('should copy object as JSON', async ({ page, clipboard }) => {
  await page.goto('https://example.com');
  await page.locator('#copy-json-button').click();

  // Asserts deep object equality automatically
  await expect(clipboard).toHaveData({ id: 101, status: 'active' });
});
Enter fullscreen mode Exit fullscreen mode

You can also read parsed JSON directly into your test using clipboard.readJSON():

const data = await clipboard.readJSON<{ id: number }>();
console.log(data.id);
Enter fullscreen mode Exit fullscreen mode

Extending Existing Custom Fixtures

If your project already defines custom Playwright fixtures, you don't need to change your imports. You can extend your base fixtures using clipboardFixture and clipboardMatchers:

import { expect as baseExpect, test as baseTest } from '@playwright/test';
import { 
  type ClipboardHandler, 
  clipboardFixture, 
  clipboardMatchers 
} from 'playwright-clipboard-testing';

export const test = baseTest.extend<{ clipboard: ClipboardHandler }>({
  clipboard: clipboardFixture,
});

export const expect = baseExpect.extend(clipboardMatchers);
Enter fullscreen mode Exit fullscreen mode

Browser Support Note

⚠️ Note: The Web Clipboard Permissions API is currently supported in Chromium-based browsers. If your setup runs tests across multiple browser engines, simply skip non-Chromium runs:

test('clipboard test', async ({ page, clipboard, browserName }) => {
  test.skip(browserName !== 'chromium', 'Clipboard API is Chromium-only');

  // test logic...
});
Enter fullscreen mode Exit fullscreen mode

Summary & Links

📦 NPM Package: playwright-clipboard-testing
💻 GitHub Repository: playwright-clipboard-testing

If you find this fixture useful, feel free to drop a ⭐️ on GitHub! Feedback and suggestions are always welcome in the issues.

Top comments (0)