playwright-clipboard-testing 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,12 +24,15 @@ Testing the Clipboard API in Playwright usually requires boilerplate code to man
24
24
  - [Usage](#usage)
25
25
  - [Direct Usage](#direct-usage)
26
26
  - [Extended Usage](#extended-usage)
27
+ - [Subpath Exports](#subpath-exports)
27
28
  - [API](#api)
28
29
  - [Fixtures](#fixtures)
29
30
  - [ClipboardHandler](#clipboardhandler)
30
31
  - [toBeBlank Matcher](#tobeblank-matcher)
32
+ - [toHaveContentLength Matcher](#tohavecontentlength-matcher)
31
33
  - [toHaveTextContent Matcher](#tohavetextcontent-matcher)
32
34
  - [toHaveJSONContent Matcher](#tohavejsoncontent-matcher)
35
+ - [toMatchJSONContent Matcher](#tomatchjsoncontent-matcher)
33
36
  - [PATTERNS](#patterns)
34
37
  - [Author](#author)
35
38
  - [License](#license)
@@ -58,7 +61,7 @@ test('should copy text to clipboard', async ({ page, clipboard, browserName }) =
58
61
  If your Playwright setup runs tests in Firefox, manually configure `firefoxUserPrefs` in your Playwright config:
59
62
  ```ts
60
63
  import { defineConfig, devices } from '@playwright/test';
61
- import { firefoxClipboardPrefs } from 'playwright-clipboard-testing';
64
+ import { firefoxClipboardPrefs } from 'playwright-clipboard-testing/constants';
62
65
 
63
66
  export default defineConfig({
64
67
  projects: [
@@ -95,17 +98,26 @@ test('should copy text to clipboard', async ({ page, clipboard }) => {
95
98
  If you already have a custom test fixture file, extend Playwright's `test` and `expect` with `clipboardFixtures` and `clipboardMatchers`:
96
99
  ```ts
97
100
  import { expect as baseExpect, test as baseTest } from '@playwright/test';
98
- import {
99
- type ClipboardHandler,
100
- clipboardFixtures,
101
- clipboardMatchers,
102
- } from 'playwright-clipboard-testing';
101
+ import { type ClipboardHandler, clipboardFixtures } from 'playwright-clipboard-testing/fixtures';
102
+ import { clipboardMatchers } from 'playwright-clipboard-testing/matchers';
103
103
 
104
104
  export const test = baseTest.extend<{ clipboard: ClipboardHandler }>(clipboardFixtures);
105
105
 
106
106
  export const expect = baseExpect.extend(clipboardMatchers);
107
+
107
108
  ```
108
109
 
110
+ ## Subpath Exports
111
+
112
+ The package provides dedicated subpath exports to import specific utilities when extending Playwright:
113
+
114
+ | Import Path | Exports | Description |
115
+ |:-----------------------------------------|:------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------|
116
+ | `playwright-clipboard-testing` | `test`, `expect` | Ready-to-use Playwright `test` runner and `expect` assertion function with built-in clipboard support. |
117
+ | `playwright-clipboard-testing/constants` | `firefoxClipboardPrefs`, `PATTERNS` | Firefox browser preferences for clipboard permissions and regex patterns for clipboard assertions. |
118
+ | `playwright-clipboard-testing/fixtures` | `clipboardFixtures`, `clipboardFixture`, `contextFixture`, `ClipboardHandler` | Playwright test fixtures and `ClipboardHandler` class for extending custom test setups. |
119
+ | `playwright-clipboard-testing/matchers` | `clipboardMatchers` | Custom Playwright matchers for extending custom `expect`. |
120
+
109
121
  ## API
110
122
 
111
123
  ### Fixtures
@@ -118,13 +130,13 @@ The package exports the following fixtures for Playwright test configuration:
118
130
  ### ClipboardHandler
119
131
  The `clipboard` fixture provides direct access to the `ClipboardHandler` instance for managing clipboard state:
120
132
 
121
- | Method | Return Type | Description |
122
- |:-------------------------------|:------------------|:-------------------------------------------------------------------------------------------------------------------------|
123
- | `clipboard.read()` | `Promise<string>` | Reads plain text content from the clipboard. |
124
- | `clipboard.write(text)` | `Promise<void>` | Writes the specified plain text to the clipboard. |
125
- | `clipboard.readJSON<T>()` | `Promise<T>` | Reads clipboard content and parses it as a JSON object of type `T`. Throws an error if invalid JSON. |
126
- | `clipboard.writeJSON<T>(data)` | `Promise<void>` | Serializes an object of type `T` to JSON and writes it to the clipboard. Throws an error if object cannot be serialized. |
127
- | `clipboard.clear()` | `Promise<void>` | Clears all clipboard content. |
133
+ | Method | Return Type | Description |
134
+ |:---------------------|:------------------|:-------------------------------------------------------------------------------------------------------------------------|
135
+ | `read()` | `Promise<string>` | Reads plain text content from the clipboard. |
136
+ | `write(text)` | `Promise<void>` | Writes the specified plain text to the clipboard. |
137
+ | `readJSON<T>()` | `Promise<T>` | Reads clipboard content and parses it as a JSON object of type `T`. Throws an error if invalid JSON. |
138
+ | `writeJSON<T>(data)` | `Promise<void>` | Serializes an object of type `T` to JSON and writes it to the clipboard. Throws an error if object cannot be serialized. |
139
+ | `clear()` | `Promise<void>` | Clears all clipboard content. |
128
140
 
129
141
  ![NOTE](https://img.shields.io/badge/NOTE-For%20your%20tests%20we%20recommend%20using%20existing%20matchers%20to%20assert%20clipboard%20content-yellow)
130
142
 
@@ -142,6 +154,22 @@ await expect(clipboard).toBeBlank();
142
154
  await expect(clipboard).not.toBeBlank({ timeout: 5000 });
143
155
  ```
144
156
 
157
+ ### toHaveContentLength Matcher
158
+ `expect(clipboard).toHaveContentLength(expected, options?)`
159
+
160
+ Asserts that the clipboard content has the expected length. Uses Playwright's smart polling mechanism to wait for the clipboard to update.
161
+ - `expected: number` — Expected length of the clipboard content.
162
+ - `options.timeout: number (optional, default: 10000ms)` — Time in milliseconds to wait for the clipboard content to match.
163
+ - `options.trim: boolean (optional, default: false)` — Trims whitespace from the clipboard content before checking its length.
164
+ ```ts
165
+ // assert that the clipboard content has the expected length
166
+ await expect(clipboard).toHaveContentLength(13);
167
+ ```
168
+ ```ts
169
+ // assert that the clipboard content does not have the expected length with trim option
170
+ await expect(clipboard).not.toHaveContentLength(10, { trim: true });
171
+ ```
172
+
145
173
  ### toHaveTextContent Matcher
146
174
  `expect(clipboard).toHaveTextContent(expected, options?)`
147
175
 
@@ -177,22 +205,39 @@ await expect(clipboard).toHaveJSONContent({ message: 'Hello, World!' });
177
205
  await expect(clipboard).not.toHaveJSONContent({ message: 'Async copied value' }, { timeout: 5000 });
178
206
  ```
179
207
 
208
+ ### toMatchJSONContent Matcher
209
+ `expect(clipboard).toMatchJSONContent(expected, options?)`
210
+ Asserts that the expected JSON object is a subset of the clipboard content. Uses Playwright's smart polling mechanism to wait for the clipboard to update.
211
+ - `expected: unknown` — Expected JSON subset object to compare against.
212
+ - `options.timeout: number (optional, default: 10000ms)` — Time in milliseconds to wait for the clipboard content to match.
213
+ ```ts
214
+ // assert that the clipboard contains a subset of the expected JSON data
215
+ await expect(clipboard).toMatchJSONContent({ status: 'success' });
216
+ ```
217
+ ```ts
218
+ // assert that the clipboard is not containing a subset of the expected JSON data with a custom timeout
219
+ await expect(clipboard).not.toMatchJSONContent({ status: 'failed' }, { timeout: 5000 });
220
+ ```
221
+
180
222
  ### PATTERNS
181
223
  The package exports pre-defined regular expression patterns for common data formats (`PATTERNS`), which can be passed directly to `toHaveTextContent`:
182
224
 
183
- | Pattern | Description | Example Match |
184
- |:---------------------|:-------------------------------------|:------------------------------------------|
185
- | `PATTERNS.UUID` | UUID v1–v5 format | `123e4567-e89b-12d3-a456-426614174000` |
186
- | `PATTERNS.EMAIL` | Email address format | `user@example.com` |
187
- | `PATTERNS.JWT` | JWT token format | `header.payload.signature` |
188
- | `PATTERNS.BEARER` | Bearer authentication token format | `Bearer token123` |
189
- | `PATTERNS.HEX_COLOR` | HEX color format | `#FFF`, `#FFFFFF`, `#FFFFFFFF` |
190
- | `PATTERNS.IP.V4` | IPv4 address format | `192.168.1.1` |
191
- | `PATTERNS.IP.V6` | IPv6 address format | `2001:0db8:85a3:0000:0000:8a2e:0370:7334` |
192
- | `PATTERNS.IP.ANY` | Any IP address format (IPv4 or IPv6) | `192.168.1.1` or `2001:db8::1` |
193
-
225
+ | Pattern | Description | Example Match |
226
+ |:------------|:-------------------------------------|:------------------------------------------|
227
+ | `UUID` | UUID v1–v5 format | `123e4567-e89b-12d3-a456-426614174000` |
228
+ | `EMAIL` | Email address format | `user@example.com` |
229
+ | `PHONE` | Phone number in E.164 format | `+1234567890` |
230
+ | `JWT` | JWT token format | `header.payload.signature` |
231
+ | `BEARER` | Bearer authentication token format | `Bearer token123` |
232
+ | `HEX_COLOR` | HEX color format | `#FFF`, `#FFFFFF`, `#FFFFFFFF` |
233
+ | `IP.V4` | IPv4 address format | `192.168.1.1` |
234
+ | `IP.V6` | IPv6 address format | `2001:0db8:85a3:0000:0000:8a2e:0370:7334` |
235
+ | `IP.ANY` | Any IP address format (IPv4 or IPv6) | `192.168.1.1` or `2001:db8::1` |
236
+
237
+ To use a pattern in your test, import `PATTERNS` and pass the desired pattern to `toHaveTextContent`:
194
238
  ```ts
195
- import { test, expect, PATTERNS } from 'playwright-clipboard-testing';
239
+ import { expect, test } from 'playwright-clipboard-testing';
240
+ import { PATTERNS } from 'playwright-clipboard-testing/constants';
196
241
 
197
242
  test('should copy UUID to clipboard', async ({ page, clipboard }) => {
198
243
  await page.goto('https://example.com');
@@ -0,0 +1,51 @@
1
+ import { Page } from '@playwright/test';
2
+
3
+ /**
4
+ * Playwright-compatible Clipboard utilities.
5
+ *
6
+ * Core functions for interacting with the browser clipboard within Playwright tests.
7
+ * Provides wrappers for reading plain text and JSON.
8
+ *
9
+ * @remarks
10
+ * These utilities require 'clipboard-read' and 'clipboard-write' permissions
11
+ * to be granted in the browser context.
12
+ */
13
+
14
+ declare class ClipboardHandler {
15
+ private readonly page;
16
+ constructor(page: Page);
17
+ /**
18
+ * Reads the current text content from the browser clipboard.
19
+ * If the content is a JSON-encoded string (e.g., has extra quotes),
20
+ * it will be returned as is. Use readJSON for automatic parsing.
21
+ *
22
+ * @returns A promise that resolves to the clipboard string content.
23
+ */
24
+ read(): Promise<string>;
25
+ /**
26
+ * Reads the clipboard content and parses it as JSON.
27
+ * If the content is a string literal (e.g., '"value"'), it returns the unwrapped string ('value').
28
+ *
29
+ * @template T - The expected type of the parsed JSON object.
30
+ * @returns A promise that resolves to the parsed JSON object of type T.
31
+ * @throws {Error} If the clipboard content is not a valid JSON string.
32
+ */
33
+ readJSON<T = unknown>(): Promise<T>;
34
+ /**
35
+ * Writes the provided string data to the browser clipboard.
36
+ * @param data The data to write to the clipboard.
37
+ */
38
+ write(data: string): Promise<void>;
39
+ /**
40
+ * Writes the provided data to the browser clipboard as a JSON string.
41
+ * @param data The data to write to the clipboard. It will be stringified as JSON.
42
+ */
43
+ writeJSON<T = unknown>(data: T): Promise<void>;
44
+ /**
45
+ * Clears the browser clipboard by writing an empty string to it.
46
+ * This effectively removes any existing content from the clipboard.
47
+ */
48
+ clear(): Promise<void>;
49
+ }
50
+
51
+ export { ClipboardHandler as C };
@@ -0,0 +1,51 @@
1
+ import { Page } from '@playwright/test';
2
+
3
+ /**
4
+ * Playwright-compatible Clipboard utilities.
5
+ *
6
+ * Core functions for interacting with the browser clipboard within Playwright tests.
7
+ * Provides wrappers for reading plain text and JSON.
8
+ *
9
+ * @remarks
10
+ * These utilities require 'clipboard-read' and 'clipboard-write' permissions
11
+ * to be granted in the browser context.
12
+ */
13
+
14
+ declare class ClipboardHandler {
15
+ private readonly page;
16
+ constructor(page: Page);
17
+ /**
18
+ * Reads the current text content from the browser clipboard.
19
+ * If the content is a JSON-encoded string (e.g., has extra quotes),
20
+ * it will be returned as is. Use readJSON for automatic parsing.
21
+ *
22
+ * @returns A promise that resolves to the clipboard string content.
23
+ */
24
+ read(): Promise<string>;
25
+ /**
26
+ * Reads the clipboard content and parses it as JSON.
27
+ * If the content is a string literal (e.g., '"value"'), it returns the unwrapped string ('value').
28
+ *
29
+ * @template T - The expected type of the parsed JSON object.
30
+ * @returns A promise that resolves to the parsed JSON object of type T.
31
+ * @throws {Error} If the clipboard content is not a valid JSON string.
32
+ */
33
+ readJSON<T = unknown>(): Promise<T>;
34
+ /**
35
+ * Writes the provided string data to the browser clipboard.
36
+ * @param data The data to write to the clipboard.
37
+ */
38
+ write(data: string): Promise<void>;
39
+ /**
40
+ * Writes the provided data to the browser clipboard as a JSON string.
41
+ * @param data The data to write to the clipboard. It will be stringified as JSON.
42
+ */
43
+ writeJSON<T = unknown>(data: T): Promise<void>;
44
+ /**
45
+ * Clears the browser clipboard by writing an empty string to it.
46
+ * This effectively removes any existing content from the clipboard.
47
+ */
48
+ clear(): Promise<void>;
49
+ }
50
+
51
+ export { ClipboardHandler as C };
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/constants/index.ts
21
+ var constants_exports = {};
22
+ __export(constants_exports, {
23
+ PATTERNS: () => PATTERNS,
24
+ firefoxClipboardPrefs: () => firefoxClipboardPrefs
25
+ });
26
+ module.exports = __toCommonJS(constants_exports);
27
+
28
+ // src/constants/constants.ts
29
+ var firefoxClipboardPrefs = {
30
+ "dom.events.testing.asyncClipboard": true,
31
+ "dom.events.asyncClipboard.readText": true,
32
+ "dom.events.asyncClipboard.writeText": true,
33
+ "permissions.default.clipboard-read": 1,
34
+ "permissions.default.clipboard-write": 1
35
+ };
36
+
37
+ // src/constants/patterns.ts
38
+ var PATTERNS = {
39
+ /**
40
+ * UUID v1-v5 (example: 123e4567-e89b-12d3-a456-426614174000).
41
+ */
42
+ UUID: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
43
+ /**
44
+ * Email addresses (example: user@example.com).
45
+ */
46
+ EMAIL: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
47
+ /**
48
+ * Phone numbers in E.164 format (example: +1234567890).
49
+ */
50
+ PHONE: /^\+[1-9]\d{1,14}$/,
51
+ /**
52
+ * JWT tokens (example: header.payload.signature).
53
+ */
54
+ JWT: /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/,
55
+ /**
56
+ * Authorization Bearer tokens (example: Bearer <token>).
57
+ */
58
+ BEARER: /^Bearer\s+[a-zA-Z0-9._~+/-]+=*$/i,
59
+ /**
60
+ * HEX-colors (example: #FFF, #FFFFFF, #FFFFFFFF).
61
+ */
62
+ HEX_COLOR: /^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i,
63
+ /**
64
+ * IP (IPv4, IPv6 or any).
65
+ */
66
+ IP: {
67
+ /** IPv4 (example: 192.168.1.1 or 127.0.0.1) */
68
+ V4: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
69
+ /** IPv6 (example: 2001:0db8:85a3:0000:0000:8a2e:0370:7334) */
70
+ V6: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,
71
+ /** Any IP address (IPv4 or IPv6) */
72
+ ANY: /^(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])))$/
73
+ }
74
+ };
75
+ // Annotate the CommonJS export names for ESM import in node:
76
+ 0 && (module.exports = {
77
+ PATTERNS,
78
+ firefoxClipboardPrefs
79
+ });
80
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/constants/index.ts","../../src/constants/constants.ts","../../src/constants/patterns.ts"],"sourcesContent":["import { firefoxClipboardPrefs } from './constants.ts';\nimport { PATTERNS } from './patterns.ts';\n\nexport { firefoxClipboardPrefs, PATTERNS };\n","export const firefoxClipboardPrefs = {\n 'dom.events.testing.asyncClipboard': true,\n 'dom.events.asyncClipboard.readText': true,\n 'dom.events.asyncClipboard.writeText': true,\n 'permissions.default.clipboard-read': 1,\n 'permissions.default.clipboard-write': 1,\n};\n","/**\n * This module contains regular expression patterns for various common formats.\n * These patterns can be used for validation purposes in applications.\n */\nexport const PATTERNS = {\n /**\n * UUID v1-v5 (example: 123e4567-e89b-12d3-a456-426614174000).\n */\n UUID: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,\n\n /**\n * Email addresses (example: user@example.com).\n */\n EMAIL: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/,\n\n /**\n * Phone numbers in E.164 format (example: +1234567890).\n */\n PHONE: /^\\+[1-9]\\d{1,14}$/,\n\n /**\n * JWT tokens (example: header.payload.signature).\n */\n JWT: /^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/,\n\n /**\n * Authorization Bearer tokens (example: Bearer <token>).\n */\n BEARER: /^Bearer\\s+[a-zA-Z0-9._~+/-]+=*$/i,\n\n /**\n * HEX-colors (example: #FFF, #FFFFFF, #FFFFFFFF).\n */\n HEX_COLOR: /^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i,\n\n /**\n * IP (IPv4, IPv6 or any).\n */\n IP: {\n /** IPv4 (example: 192.168.1.1 or 127.0.0.1) */\n V4: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,\n\n /** IPv6 (example: 2001:0db8:85a3:0000:0000:8a2e:0370:7334) */\n V6: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,\n\n /** Any IP address (IPv4 or IPv6) */\n ANY: /^(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])))$/,\n },\n} as const;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,wBAAwB;AAAA,EACnC,qCAAqC;AAAA,EACrC,sCAAsC;AAAA,EACtC,uCAAuC;AAAA,EACvC,sCAAsC;AAAA,EACtC,uCAAuC;AACzC;;;ACFO,IAAM,WAAW;AAAA;AAAA;AAAA;AAAA,EAItB,MAAM;AAAA;AAAA;AAAA;AAAA,EAKN,OAAO;AAAA;AAAA;AAAA;AAAA,EAKP,OAAO;AAAA;AAAA;AAAA;AAAA,EAKP,KAAK;AAAA;AAAA;AAAA;AAAA,EAKL,QAAQ;AAAA;AAAA;AAAA;AAAA,EAKR,WAAW;AAAA;AAAA;AAAA;AAAA,EAKX,IAAI;AAAA;AAAA,IAEF,IAAI;AAAA;AAAA,IAGJ,IAAI;AAAA;AAAA,IAGJ,KAAK;AAAA,EACP;AACF;","names":[]}
@@ -0,0 +1,51 @@
1
+ declare const firefoxClipboardPrefs: {
2
+ 'dom.events.testing.asyncClipboard': boolean;
3
+ 'dom.events.asyncClipboard.readText': boolean;
4
+ 'dom.events.asyncClipboard.writeText': boolean;
5
+ 'permissions.default.clipboard-read': number;
6
+ 'permissions.default.clipboard-write': number;
7
+ };
8
+
9
+ /**
10
+ * This module contains regular expression patterns for various common formats.
11
+ * These patterns can be used for validation purposes in applications.
12
+ */
13
+ declare const PATTERNS: {
14
+ /**
15
+ * UUID v1-v5 (example: 123e4567-e89b-12d3-a456-426614174000).
16
+ */
17
+ readonly UUID: RegExp;
18
+ /**
19
+ * Email addresses (example: user@example.com).
20
+ */
21
+ readonly EMAIL: RegExp;
22
+ /**
23
+ * Phone numbers in E.164 format (example: +1234567890).
24
+ */
25
+ readonly PHONE: RegExp;
26
+ /**
27
+ * JWT tokens (example: header.payload.signature).
28
+ */
29
+ readonly JWT: RegExp;
30
+ /**
31
+ * Authorization Bearer tokens (example: Bearer <token>).
32
+ */
33
+ readonly BEARER: RegExp;
34
+ /**
35
+ * HEX-colors (example: #FFF, #FFFFFF, #FFFFFFFF).
36
+ */
37
+ readonly HEX_COLOR: RegExp;
38
+ /**
39
+ * IP (IPv4, IPv6 or any).
40
+ */
41
+ readonly IP: {
42
+ /** IPv4 (example: 192.168.1.1 or 127.0.0.1) */
43
+ readonly V4: RegExp;
44
+ /** IPv6 (example: 2001:0db8:85a3:0000:0000:8a2e:0370:7334) */
45
+ readonly V6: RegExp;
46
+ /** Any IP address (IPv4 or IPv6) */
47
+ readonly ANY: RegExp;
48
+ };
49
+ };
50
+
51
+ export { PATTERNS, firefoxClipboardPrefs };
@@ -0,0 +1,51 @@
1
+ declare const firefoxClipboardPrefs: {
2
+ 'dom.events.testing.asyncClipboard': boolean;
3
+ 'dom.events.asyncClipboard.readText': boolean;
4
+ 'dom.events.asyncClipboard.writeText': boolean;
5
+ 'permissions.default.clipboard-read': number;
6
+ 'permissions.default.clipboard-write': number;
7
+ };
8
+
9
+ /**
10
+ * This module contains regular expression patterns for various common formats.
11
+ * These patterns can be used for validation purposes in applications.
12
+ */
13
+ declare const PATTERNS: {
14
+ /**
15
+ * UUID v1-v5 (example: 123e4567-e89b-12d3-a456-426614174000).
16
+ */
17
+ readonly UUID: RegExp;
18
+ /**
19
+ * Email addresses (example: user@example.com).
20
+ */
21
+ readonly EMAIL: RegExp;
22
+ /**
23
+ * Phone numbers in E.164 format (example: +1234567890).
24
+ */
25
+ readonly PHONE: RegExp;
26
+ /**
27
+ * JWT tokens (example: header.payload.signature).
28
+ */
29
+ readonly JWT: RegExp;
30
+ /**
31
+ * Authorization Bearer tokens (example: Bearer <token>).
32
+ */
33
+ readonly BEARER: RegExp;
34
+ /**
35
+ * HEX-colors (example: #FFF, #FFFFFF, #FFFFFFFF).
36
+ */
37
+ readonly HEX_COLOR: RegExp;
38
+ /**
39
+ * IP (IPv4, IPv6 or any).
40
+ */
41
+ readonly IP: {
42
+ /** IPv4 (example: 192.168.1.1 or 127.0.0.1) */
43
+ readonly V4: RegExp;
44
+ /** IPv6 (example: 2001:0db8:85a3:0000:0000:8a2e:0370:7334) */
45
+ readonly V6: RegExp;
46
+ /** Any IP address (IPv4 or IPv6) */
47
+ readonly ANY: RegExp;
48
+ };
49
+ };
50
+
51
+ export { PATTERNS, firefoxClipboardPrefs };
@@ -0,0 +1,52 @@
1
+ // src/constants/constants.ts
2
+ var firefoxClipboardPrefs = {
3
+ "dom.events.testing.asyncClipboard": true,
4
+ "dom.events.asyncClipboard.readText": true,
5
+ "dom.events.asyncClipboard.writeText": true,
6
+ "permissions.default.clipboard-read": 1,
7
+ "permissions.default.clipboard-write": 1
8
+ };
9
+
10
+ // src/constants/patterns.ts
11
+ var PATTERNS = {
12
+ /**
13
+ * UUID v1-v5 (example: 123e4567-e89b-12d3-a456-426614174000).
14
+ */
15
+ UUID: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
16
+ /**
17
+ * Email addresses (example: user@example.com).
18
+ */
19
+ EMAIL: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
20
+ /**
21
+ * Phone numbers in E.164 format (example: +1234567890).
22
+ */
23
+ PHONE: /^\+[1-9]\d{1,14}$/,
24
+ /**
25
+ * JWT tokens (example: header.payload.signature).
26
+ */
27
+ JWT: /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/,
28
+ /**
29
+ * Authorization Bearer tokens (example: Bearer <token>).
30
+ */
31
+ BEARER: /^Bearer\s+[a-zA-Z0-9._~+/-]+=*$/i,
32
+ /**
33
+ * HEX-colors (example: #FFF, #FFFFFF, #FFFFFFFF).
34
+ */
35
+ HEX_COLOR: /^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i,
36
+ /**
37
+ * IP (IPv4, IPv6 or any).
38
+ */
39
+ IP: {
40
+ /** IPv4 (example: 192.168.1.1 or 127.0.0.1) */
41
+ V4: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
42
+ /** IPv6 (example: 2001:0db8:85a3:0000:0000:8a2e:0370:7334) */
43
+ V6: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,
44
+ /** Any IP address (IPv4 or IPv6) */
45
+ ANY: /^(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])))$/
46
+ }
47
+ };
48
+ export {
49
+ PATTERNS,
50
+ firefoxClipboardPrefs
51
+ };
52
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/constants/constants.ts","../../src/constants/patterns.ts"],"sourcesContent":["export const firefoxClipboardPrefs = {\n 'dom.events.testing.asyncClipboard': true,\n 'dom.events.asyncClipboard.readText': true,\n 'dom.events.asyncClipboard.writeText': true,\n 'permissions.default.clipboard-read': 1,\n 'permissions.default.clipboard-write': 1,\n};\n","/**\n * This module contains regular expression patterns for various common formats.\n * These patterns can be used for validation purposes in applications.\n */\nexport const PATTERNS = {\n /**\n * UUID v1-v5 (example: 123e4567-e89b-12d3-a456-426614174000).\n */\n UUID: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,\n\n /**\n * Email addresses (example: user@example.com).\n */\n EMAIL: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/,\n\n /**\n * Phone numbers in E.164 format (example: +1234567890).\n */\n PHONE: /^\\+[1-9]\\d{1,14}$/,\n\n /**\n * JWT tokens (example: header.payload.signature).\n */\n JWT: /^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/,\n\n /**\n * Authorization Bearer tokens (example: Bearer <token>).\n */\n BEARER: /^Bearer\\s+[a-zA-Z0-9._~+/-]+=*$/i,\n\n /**\n * HEX-colors (example: #FFF, #FFFFFF, #FFFFFFFF).\n */\n HEX_COLOR: /^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i,\n\n /**\n * IP (IPv4, IPv6 or any).\n */\n IP: {\n /** IPv4 (example: 192.168.1.1 or 127.0.0.1) */\n V4: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,\n\n /** IPv6 (example: 2001:0db8:85a3:0000:0000:8a2e:0370:7334) */\n V6: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,\n\n /** Any IP address (IPv4 or IPv6) */\n ANY: /^(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])))$/,\n },\n} as const;\n"],"mappings":";AAAO,IAAM,wBAAwB;AAAA,EACnC,qCAAqC;AAAA,EACrC,sCAAsC;AAAA,EACtC,uCAAuC;AAAA,EACvC,sCAAsC;AAAA,EACtC,uCAAuC;AACzC;;;ACFO,IAAM,WAAW;AAAA;AAAA;AAAA;AAAA,EAItB,MAAM;AAAA;AAAA;AAAA;AAAA,EAKN,OAAO;AAAA;AAAA;AAAA;AAAA,EAKP,OAAO;AAAA;AAAA;AAAA;AAAA,EAKP,KAAK;AAAA;AAAA;AAAA;AAAA,EAKL,QAAQ;AAAA;AAAA;AAAA;AAAA,EAKR,WAAW;AAAA;AAAA;AAAA;AAAA,EAKX,IAAI;AAAA;AAAA,IAEF,IAAI;AAAA;AAAA,IAGJ,IAAI;AAAA;AAAA,IAGJ,KAAK;AAAA,EACP;AACF;","names":[]}
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/fixtures/index.ts
21
+ var fixtures_exports = {};
22
+ __export(fixtures_exports, {
23
+ ClipboardHandler: () => ClipboardHandler,
24
+ clipboardFixture: () => clipboardFixture,
25
+ clipboardFixtures: () => clipboardFixtures,
26
+ contextFixture: () => contextFixture
27
+ });
28
+ module.exports = __toCommonJS(fixtures_exports);
29
+
30
+ // src/utils/clipboardHandler.ts
31
+ var ClipboardHandler = class {
32
+ constructor(page) {
33
+ this.page = page;
34
+ }
35
+ page;
36
+ /**
37
+ * Reads the current text content from the browser clipboard.
38
+ * If the content is a JSON-encoded string (e.g., has extra quotes),
39
+ * it will be returned as is. Use readJSON for automatic parsing.
40
+ *
41
+ * @returns A promise that resolves to the clipboard string content.
42
+ */
43
+ async read() {
44
+ return await this.page.evaluate(() => navigator.clipboard.readText());
45
+ }
46
+ /**
47
+ * Reads the clipboard content and parses it as JSON.
48
+ * If the content is a string literal (e.g., '"value"'), it returns the unwrapped string ('value').
49
+ *
50
+ * @template T - The expected type of the parsed JSON object.
51
+ * @returns A promise that resolves to the parsed JSON object of type T.
52
+ * @throws {Error} If the clipboard content is not a valid JSON string.
53
+ */
54
+ async readJSON() {
55
+ const text = await this.read();
56
+ try {
57
+ return JSON.parse(text);
58
+ } catch {
59
+ throw new Error(
60
+ `[playwright-clipboard] Clipboard content is not a valid JSON: ${JSON.stringify(text)}`
61
+ );
62
+ }
63
+ }
64
+ /**
65
+ * Writes the provided string data to the browser clipboard.
66
+ * @param data The data to write to the clipboard.
67
+ */
68
+ async write(data) {
69
+ await this.page.evaluate((value) => navigator.clipboard.writeText(value), data);
70
+ }
71
+ /**
72
+ * Writes the provided data to the browser clipboard as a JSON string.
73
+ * @param data The data to write to the clipboard. It will be stringified as JSON.
74
+ */
75
+ async writeJSON(data) {
76
+ const errorMessage = "[playwright-clipboard] Provided data cannot be stringified to valid JSON";
77
+ let jsonString;
78
+ try {
79
+ jsonString = JSON.stringify(data);
80
+ } catch (error) {
81
+ const message = error instanceof Error ? error : String(error);
82
+ throw new Error(`${errorMessage}: ${message}`);
83
+ }
84
+ if (jsonString === void 0) {
85
+ throw new Error(`${errorMessage} (received undefined).`);
86
+ }
87
+ await this.write(jsonString);
88
+ }
89
+ /**
90
+ * Clears the browser clipboard by writing an empty string to it.
91
+ * This effectively removes any existing content from the clipboard.
92
+ */
93
+ async clear() {
94
+ await this.write("");
95
+ }
96
+ };
97
+
98
+ // src/fixtures/clipboardFixture.ts
99
+ var clipboardFixture = async ({ page, browserName }, use) => {
100
+ if (browserName === "webkit") {
101
+ throw new Error(
102
+ `[playwright-clipboard] Browser '${browserName}' is not supported. Clipboard API testing is currently supported only in Chromium-based and Firefox browsers.
103
+ Add test.skip(browserName === 'webkit', 'Clipboard API is only supported in Chromium and Firefox'); to your test body.`
104
+ );
105
+ }
106
+ const handler = new ClipboardHandler(page);
107
+ await use(handler);
108
+ };
109
+
110
+ // src/fixtures/contextFixture.ts
111
+ var contextFixture = async ({ context, browserName }, use) => {
112
+ if (browserName === "chromium") {
113
+ await context.grantPermissions(["clipboard-read", "clipboard-write"]);
114
+ }
115
+ await use(context);
116
+ };
117
+
118
+ // src/fixtures/index.ts
119
+ var clipboardFixtures = {
120
+ context: contextFixture,
121
+ clipboard: clipboardFixture
122
+ };
123
+ // Annotate the CommonJS export names for ESM import in node:
124
+ 0 && (module.exports = {
125
+ ClipboardHandler,
126
+ clipboardFixture,
127
+ clipboardFixtures,
128
+ contextFixture
129
+ });
130
+ //# sourceMappingURL=index.cjs.map