{"id":24081468,"url":"https://github.com/vrknetha/playwright-clipboard","last_synced_at":"2025-04-30T16:26:42.580Z","repository":{"id":267029646,"uuid":"900068907","full_name":"vrknetha/playwright-clipboard","owner":"vrknetha","description":"Cross-browser clipboard testing solution for Playwright, providing reliable clipboard operations across Chromium, Firefox, and WebKit.","archived":false,"fork":false,"pushed_at":"2024-12-08T09:55:32.000Z","size":87,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-08T19:59:49.186Z","etag":null,"topics":["clipboard","playwright","test-automation","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vrknetha.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-07T19:22:38.000Z","updated_at":"2025-01-04T08:13:43.000Z","dependencies_parsed_at":"2024-12-07T20:24:04.696Z","dependency_job_id":"6784893b-86f7-4030-b01b-b942d419b698","html_url":"https://github.com/vrknetha/playwright-clipboard","commit_stats":null,"previous_names":["vrknetha/playwright-clipboard"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vrknetha%2Fplaywright-clipboard","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vrknetha%2Fplaywright-clipboard/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vrknetha%2Fplaywright-clipboard/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vrknetha%2Fplaywright-clipboard/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vrknetha","download_url":"https://codeload.github.com/vrknetha/playwright-clipboard/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":233270911,"owners_count":18650865,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clipboard","playwright","test-automation","typescript"],"created_at":"2025-01-09T23:12:19.138Z","updated_at":"2025-01-09T23:12:19.674Z","avatar_url":"https://github.com/vrknetha.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Playwright Clipboard\n\nA comprehensive solution for testing clipboard operations in web applications using Playwright. This package provides both standard clipboard operations and precise word-level text manipulation capabilities across all major browsers (Chromium, Firefox, and WebKit).\n\n## Features\n\n- ✨ Cross-browser clipboard operations (copy, paste, cut)\n- 📝 Rich text operations with HTML preservation\n- 🎯 Text selection operations with character and word-level control\n- 🔍 Word-level operations for precise text manipulation\n- 🔄 Clipboard content management with direct access\n- 🌐 Cross-browser compatibility (Chromium, Firefox, WebKit)\n- 📦 TypeScript support with full type definitions\n- 🛡️ Comprehensive error handling\n- 🔄 Fallback mechanisms for browser-specific limitations\n\n## Installation\n\n```bash\nnpm install --save-dev playwright-clipboard\n```\n\n## Configuration\n\n### Playwright Config\n\nCreate or update your `playwright.config.ts`:\n\n```typescript\nimport { defineConfig, devices } from '@playwright/test';\n\nexport default defineConfig({\n  testDir: './tests',\n  /* Run tests sequentially for clipboard operations */\n  fullyParallel: false,\n  use: {\n    /* Base URL for your test server */\n    baseURL: 'http://localhost:8080',\n    /* Increase timeouts for clipboard operations */\n    actionTimeout: 30000,\n  },\n  projects: [\n    {\n      name: 'chromium',\n      use: {\n        ...devices['Desktop Chrome'],\n        /* Enable clipboard permissions for Chromium */\n        permissions: ['clipboard-read', 'clipboard-write'],\n      },\n    },\n    {\n      name: 'firefox',\n      use: {\n        ...devices['Desktop Firefox'],\n        /* Firefox-specific preferences for clipboard */\n        launchOptions: {\n          firefoxUserPrefs: {\n            'dom.events.testing.asyncClipboard': true,\n            'dom.events.asyncClipboard.readText': true,\n            'dom.events.asyncClipboard.clipboardItem': true,\n            'dom.events.asyncClipboard.writeText': true,\n            'permissions.default.clipboard-read': 1,\n            'permissions.default.clipboard-write': 1,\n          },\n        },\n      },\n    },\n    {\n      name: 'webkit',\n      use: {\n        ...devices['Desktop Safari'],\n      },\n    },\n  ],\n});\n```\n\n## Usage\n\n### Test Fixtures\n\nCreate reusable clipboard fixtures for your tests:\n\n```typescript\nimport { test as base } from '@playwright/test';\nimport { PlaywrightClipboard } from 'playwright-clipboard';\n\n// Define clipboard fixture type\ninterface ClipboardFixtures {\n  clipboard: PlaywrightClipboard;\n}\n\n// Extend base test with clipboard fixture\nconst test = base.extend\u003cClipboardFixtures\u003e({\n  clipboard: async ({ page }, use) =\u003e {\n    const clipboard = new PlaywrightClipboard(page);\n    await use(clipboard);\n  },\n});\n\n// Export for use in test files\nexport { test };\nexport { expect } from '@playwright/test';\n```\n\n### Basic Operations\n\n```typescript\nimport { test, expect } from './fixtures';\n\ntest('basic clipboard operations', async ({ page, clipboard }) =\u003e {\n  // Copy text\n  await clipboard.copy('#source');\n  \n  // Paste text\n  await clipboard.paste('#target');\n  \n  // Cut text\n  await clipboard.cut('#source');\n  \n  // Get clipboard content\n  const content = await clipboard.getClipboardContent();\n  expect(content).toBe('Expected text');\n});\n```\n\n### Rich Text Operations\n\n```typescript\ntest('rich text operations', async ({ clipboard }) =\u003e {\n  // Copy rich text with HTML preservation\n  await clipboard.copyRichText('#richSource');\n  \n  // Paste rich text maintaining formatting\n  await clipboard.pasteRichText('#richTarget');\n  \n  // Cut rich text\n  await clipboard.cutRichText('#richSource');\n});\n```\n\n### Text Selection\n\n```typescript\ntest('text selection operations', async ({ clipboard }) =\u003e {\n  // Select specific range\n  await clipboard.select('#text', 7, 11);\n  \n  // Get selected text\n  const selectedText = await clipboard.getSelectedText();\n  \n  // Select all text\n  await clipboard.selectAll('#text');\n  \n  // Select word range\n  await clipboard.selectWordRange('#text', 1, 3);\n});\n```\n\n### Word Operations\n\n```typescript\ntest('word-level operations', async ({ clipboard }) =\u003e {\n  // Copy specific words\n  await clipboard.copyBetweenWords('#editor', 2, 3);\n  \n  // Paste after specific word\n  await clipboard.pasteAfterWord('#editor', 1);\n  \n  // Paste before word\n  await clipboard.pasteBeforeWord('#editor', 0);\n  \n  // Replace specific word\n  await clipboard.replaceWord('#editor', 4);\n});\n```\n\n### Error Handling\n\n```typescript\nimport { ClipboardError } from 'playwright-clipboard';\n\ntest('handle clipboard errors', async ({ clipboard }) =\u003e {\n  try {\n    await clipboard.copy('#nonexistent');\n  } catch (error) {\n    if (error.message === ClipboardError.COPY_ERROR) {\n      // Handle copy error\n    }\n  }\n});\n```\n\n## Browser Support\n\n| Feature | Chromium | Firefox | WebKit |\n|---------|----------|---------|--------|\n| Basic Operations | ✅ | ✅ | ✅ |\n| Rich Text | ✅ | ✅ | ✅ |\n| Word Operations | ✅ | ✅ | ✅ |\n| Text Selection | ✅ | ✅ | ✅ |\n\n## Technical Details\n\nThe package implements several fallback mechanisms to ensure consistent behavior across browsers:\n\n1. **Clipboard Access**:\n   - Primary: Native Clipboard API\n   - Fallback: Keyboard shortcuts (Meta+C, Meta+V, Meta+X)\n   - Last Resort: execCommand for WebKit\n\n2. **Text Selection**:\n   - Input/Textarea: Uses `setSelectionRange`\n   - Rich Text: Uses `Range` and `Selection` APIs\n   - Word-Level: Custom boundary detection\n\n3. **Rich Text Handling**:\n   - Preserves HTML structure where supported\n   - Graceful degradation to plain text\n   - Browser-specific optimizations\n\n## API Reference\n\n### Constructor\n\n```typescript\nconstructor(page: Page, options?: ClipboardOptions)\n```\n\nOptions:\n- `timeout?: number` - Operation timeout in milliseconds (default: 5000)\n\n### Methods\n\n#### Basic Operations\n- `copy(selector: string): Promise\u003cvoid\u003e` - Copy content from element\n- `paste(selector: string): Promise\u003cvoid\u003e` - Paste content to element\n- `cut(selector: string): Promise\u003cvoid\u003e` - Cut content from element\n\n#### Rich Text Operations\n- `copyRichText(selector: string): Promise\u003cvoid\u003e` - Copy with HTML preservation\n- `pasteRichText(selector: string): Promise\u003cvoid\u003e` - Paste with HTML preservation\n- `cutRichText(selector: string): Promise\u003cvoid\u003e` - Cut with HTML preservation\n\n#### Selection Operations\n- `selectAll(selector: string): Promise\u003cvoid\u003e` - Select all content\n- `select(selector: string, start: number, end: number): Promise\u003cvoid\u003e` - Select range\n- `getSelectedText(): Promise\u003cstring\u003e` - Get selected text\n\n#### Word Operations\n- `copyBetweenWords(selector: string, startWordIndex: number, endWordIndex: number): Promise\u003cvoid\u003e`\n- `pasteAfterWord(selector: string, wordIndex: number): Promise\u003cvoid\u003e`\n- `pasteBeforeWord(selector: string, wordIndex: number): Promise\u003cvoid\u003e`\n- `replaceWord(selector: string, wordIndex: number): Promise\u003cvoid\u003e`\n\n## Contributing\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## License\n\nMIT License - see the [LICENSE](LICENSE) file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvrknetha%2Fplaywright-clipboard","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvrknetha%2Fplaywright-clipboard","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvrknetha%2Fplaywright-clipboard/lists"}