Skip to content

feat(helpers): add seeInClipboard, seeClipboardEquals and clearClipboard - #5718

Open
DavertMik wants to merge 1 commit into
4.xfrom
feat/clipboard-actions
Open

DavertMik wants to merge 1 commit into
4.xfrom
feat/clipboard-actions

Conversation

@DavertMik

Copy link
Copy Markdown
Contributor

Adds seeInClipboard(), seeClipboardEquals() and clearClipboard() to every browser helper.

I.click('Copy to clipboard')
I.seeInClipboard('https://codecept.io')
I.seeClipboardEquals('https://codecept.io')
I.clearClipboard()

How each helper reads the clipboard

Helper Mechanism
Playwright page.context().grantPermissions(['clipboard-read', 'clipboard-write']) + page.evaluate
Puppeteer browserContext().overridePermissions(origin, [...])clipboard-sanitized-write is required too, or writeText stays denied
WebDriver browser.setPermissions({ name: 'clipboard-read' }, 'granted') + executeAsync, since execute does not await promises under W3C
CDPBrowser (inherited by Obscura, Kitesurf) raw Browser.grantPermissions with the CDP permission names clipboardReadWrite / clipboardSanitizedWrite
Appium native getClipboard / setClipboard device commands (base64), falling back to the WebDriver implementation on a non-mobile session

Two details worth calling out:

  • Permission is granted per call rather than at browser start, because session() and restart recreate the context.
  • The page is brought to front first — Chromium rejects readText() with "Document is not focused" when another tab holds focus, and the acceptance suite opens tabs.
  • The in-page read races against a 5s timeout, so a browser that neither grants nor denies access (a paste prompt that never appears in a headless run) fails the step instead of hanging it.

Tests

test/helper/webapi.js covers all helpers through the new /form/clipboard fixture, which uses a real copy button rather than writing the clipboard from the test, so the read path is genuinely exercised.

Obscura is skipped with a verified reason: its navigator.clipboard.writeText() resolves but stores nothing, so readText() always returns ''.

Verification

Check Result
npm run test:unit 832 passed, 0 failed
npm run test:runner 279 passed, 0 failed
definitions_test.js (def gate) 12 passing
Playwright / Puppeteer / CDPBrowser clipboard specs 9/9 passing
WebDriver against chromedriver directly read, write, clear and the negative assertion all pass
Playwright acceptance suite 64 passed, no hangs; the one failure is the pre-existing mock server test
eslint clean

npm run dtslint reports 2 errors about conflicting *Config identifiers — confirmed pre-existing by regenerating typings from a clean tree.

Not verified locally: WebDriver through Selenium Grid, Appium (no device), and Kitesurf. If Cloudflare's remote browser refuses Browser.grantPermissions, that suite will need an Obscura-style skip; no CI workflow runs it today.

docs/helpers/*.md is intentionally not included — the doc-generation workflow regenerates and commits it on push to 4.x.

🤖 Generated with Claude Code

Adds three clipboard actions to every browser helper:

- Playwright, Puppeteer, WebDriver, CDPBrowser (inherited by Obscura
  and Kitesurf) read and write through `navigator.clipboard`, granting
  clipboard permission per call and bringing the page to front first,
  since Chromium rejects a read from an unfocused document and contexts
  are recreated by `session()` and `restart`.
- Appium uses the native `getClipboard`/`setClipboard` device commands,
  falling back to the WebDriver implementation on a non-mobile session.

The in-page read races against a 5s timeout so a browser that neither
grants nor denies access fails the step instead of hanging it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant