Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

browser testing: enable (or make it easier) to copy/paste text #6746

Closed
4 tasks done
luisrudge opened this issue Oct 19, 2024 · 11 comments · May be fixed by #6769
Closed
4 tasks done

browser testing: enable (or make it easier) to copy/paste text #6746

luisrudge opened this issue Oct 19, 2024 · 11 comments · May be fixed by #6769
Labels
enhancement: pending triage p2-to-be-discussed Enhancement under consideration (priority)

Comments

@luisrudge
Copy link

Clear and concise description of the problem

I want to paste text into an element

Suggested solution

no idea 😅 I'm sure the drivers must have support for the clipboard api somehow

Alternative

No response

Additional context

No response

Validations

@luisrudge luisrudge changed the title enable (or make it easier) to copy/paste text browser testing: enable (or make it easier) to copy/paste text Oct 19, 2024
@hi-ogawa
Copy link
Contributor

no idea 😅 I'm sure the drivers must have support for the clipboard api somehow

I'm not sure. There are some issue on playwright microsoft/playwright#15860 microsoft/playwright#24039, which suggest workaround using ClipboardEvent or navigator.clipboard on window (so no cdp or bid based mechanism I suppose?)

Have you tried testing-library's clipboard api? https://testing-library.com/docs/user-event/clipboard

@luisrudge
Copy link
Author

yeah I tried RTL with

await userEventTestingLibrary.keyboard('{Control}{c}');
await userEventTestingLibrary.keyboard('{Control}{v}');

and also

await userEventTestingLibrary.paste('test');

but it didn't work

@luisrudge
Copy link
Author

to be clear, I don't want to interact with window.navigator.clipboard. I need to test what happens when you paste into a specific text input

@hi-ogawa
Copy link
Contributor

hi-ogawa commented Oct 20, 2024

Once again, it looks working with this example of mine 😅 https://stackblitz.com/edit/vitest-dev-vitest-ccmzqe?file=test%2Frepro.test.ts (please test it locally to use playwright) Note that {Control>} is the command to hold down the key.

Screenshot
import { test } from 'vitest';
import { page, userEvent } from '@vitest/browser/context';

test('clipboard', async () => {
  document.body.innerHTML = `
    <input placeholder="first" />
    <input placeholder="second" />
  `;

  // write "hello" and copy to clipboard
  await userEvent.click(page.getByPlaceholder('first'));
  await userEvent.keyboard('hello');
  await userEvent.keyboard('{Control>}{a}{/Control}');
  await userEvent.keyboard('{Control>}{c}{/Control}');

  // paste twice into second
  await userEvent.click(page.getByPlaceholder('second'));
  await userEvent.keyboard('{Control>}{v}{/Control}');
  await userEvent.keyboard('{Control>}{v}{/Control}');

  // hellohello
  console.log(page.getByPlaceholder('second').query()?.value);
});

image

(Tested with playwright chromium and webdriverio chrome)

Can you share how you code looks like?

@hi-ogawa hi-ogawa added the p2-to-be-discussed Enhancement under consideration (priority) label Oct 21, 2024
@hi-ogawa
Copy link
Contributor

hi-ogawa commented Oct 21, 2024

"Control+C/X/V" combo seems to mostly work on playwright microsoft/playwright#8114 and webdriverio https://webdriver.io/docs/api/expect-webdriverio/#tohaveclipboardtext, so we could implement testling-library-like copy/cut/paste API on top of that https://testing-library.com/docs/user-event/clipboard/
I'm not sure how we can expose DataTransfer though.

@luisrudge
Copy link
Author

thanks for the repro, but it seems like it's not working?
image

the value is not there and nothing is logged to the console.

@luisrudge
Copy link
Author

luisrudge commented Oct 21, 2024

it also doesn't work locally
image

@hi-ogawa
Copy link
Contributor

Hmm weird, It's working on my Linux PC. Do you use Mac? According to microsoft/playwright#8114, you might need Meta instead of Control for modifier.

@sheremet-va
Copy link
Member

The copy/paste userEvent API is supposed to be implemented at some point: #5770 (comment)

PRs are welcome.

@luisrudge
Copy link
Author

luisrudge commented Oct 22, 2024

after my conversation in discord with @hi-ogawa, we figured out the issue:

  • when you run in stackblitz, it always run in 'preview' (even if you configured playwright or webdriverio)
  • so I had to test it locally, but since I'm using a Mac, I have to use the Meta key and not Control

For other people with the same issue, this is how you copy/paste content:

Mac

import { test } from 'vitest';
import { page, userEvent } from '@vitest/browser/context';

test('clipboard', async () => {
  document.body.innerHTML = `
    <input placeholder="first" />
    <input placeholder="second" />
  `;

  // write "hello" and copy to clipboard
  await userEvent.click(page.getByPlaceholder('first'));
  await userEvent.keyboard('hello');
  await userEvent.keyboard('{selectall}');
  await userEvent.keyboard('{Meta>}{c}{/Meta}');

  // paste twice into second
  await userEvent.click(page.getByPlaceholder('second'));
  await userEvent.keyboard('{Meta>}{v}{/Meta}');
  await userEvent.keyboard('{Meta>}{v}{/Meta}');

  // hellohello
  console.log(page.getByPlaceholder('second').query()?.value);
});

Linux/Windows

import { test } from 'vitest';
import { page, userEvent } from '@vitest/browser/context';

test('clipboard', async () => {
  document.body.innerHTML = `
    <input placeholder="first" />
    <input placeholder="second" />
  `;

  // write "hello" and copy to clipboard
  await userEvent.click(page.getByPlaceholder('first'));
  await userEvent.keyboard('hello');
  await userEvent.keyboard('{selectall}');
  await userEvent.keyboard('{Control>}{c}{/Control}');

  // paste twice into second
  await userEvent.click(page.getByPlaceholder('second'));
  await userEvent.keyboard('{Control>}{v}{/Control}');
  await userEvent.keyboard('{Control>}{v}{/Control}');

  // hellohello
  console.log(page.getByPlaceholder('second').query()?.value);
});

@luisrudge
Copy link
Author

luisrudge commented Oct 22, 2024

oh, nevermind. Playwright supports the ControlOrMeta key natively, so you can use just that 😅
https://playwright.dev/docs/api/class-keyboard#keyboard-press

import { test } from 'vitest';
import { page, userEvent } from '@vitest/browser/context';

test('clipboard', async () => {
  document.body.innerHTML = `
    <input placeholder="first" />
    <input placeholder="second" />
  `;

  // write "hello" and copy to clipboard
  await userEvent.click(page.getByPlaceholder('first'));
  await userEvent.keyboard('hello');
  await userEvent.keyboard('{selectall}');
  await userEvent.keyboard('{ControlOrMeta>}{c}{/ControlOrMeta}');

  // paste twice into second
  await userEvent.click(page.getByPlaceholder('second'));
  await userEvent.keyboard('{ControlOrMeta>}{v}{/ControlOrMeta}');
  await userEvent.keyboard('{ControlOrMeta>}{v}{/ControlOrMeta}');

  // hellohello
  console.log(page.getByPlaceholder('second').query()?.value);
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement: pending triage p2-to-be-discussed Enhancement under consideration (priority)
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants