diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 8b05238..30f178e 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -7,6 +7,7 @@ jobs:
matrix:
exampleDir:
- click
+ - clipboard
- customMatchers
- deleteCookies
- emulate
diff --git a/clipboard/README.md b/clipboard/README.md
new file mode 100644
index 0000000..3f61bbd
--- /dev/null
+++ b/clipboard/README.md
@@ -0,0 +1,20 @@
+# `clipboard` Example
+
+This directory contains the example files for interacting with the system clipboard using
+WebDriverIO.
+
+## Prerequisite
+
+Make sure to run this first, to set up the example repository:
+
+```sh
+npm install
+```
+
+## Example
+
+Run example via:
+
+```sh
+npm run clipboard
+```
diff --git a/clipboard/chrome-example.js b/clipboard/chrome-example.js
new file mode 100644
index 0000000..6a6dec2
--- /dev/null
+++ b/clipboard/chrome-example.js
@@ -0,0 +1,39 @@
+import { browser, expect, $ } from '@wdio/globals'
+
+describe('Clipboard: Chrome', () => {
+ before(() => browser.url('/example.html'))
+
+ it('should allow the browser to read the clipboard', async () => {
+ // set clipboard permissions
+ await browser.setPermissions({ name: 'clipboard-read' }, 'granted')
+
+ const btn = await $('#copyBtn')
+ await btn.click()
+
+ // Use a focus event to trigger the async clipboard read, then save
+ // the result to a global variable on the window object
+ // Without this the clipboard read may be blocked
+ // with "NotAllowedError: Document is not focused."
+ // See: https://stackoverflow.com/questions/56306153/domexception-on-calling-navigator-clipboard-readtext
+ await browser.execute(() => {
+ const _asyncCopyFn = (async () => {
+ setTimeout(async () => {
+ window.clipboardText = await navigator.clipboard.readText();
+ document.body.removeEventListener("click", _asyncCopyFn);
+ }, 200);
+ });
+ document.body.addEventListener("click", _asyncCopyFn);
+ });
+
+ await $('body').click();
+
+ await browser.pause(300);
+
+ // now you can read the clipboard text from the global variable
+ const clipboardText = await browser.execute(() => window.clipboardText);
+ console.log('Clipboard text:', clipboardText);
+
+ await expect(clipboardText).toBe('Hello from WebdriverIO clipboard test!')
+ })
+
+})
diff --git a/clipboard/example.html b/clipboard/example.html
new file mode 100644
index 0000000..17e19e7
--- /dev/null
+++ b/clipboard/example.html
@@ -0,0 +1,21 @@
+
+
+
+
+ Clipboard Test
+
+
+
+
+
+
+
diff --git a/clipboard/firefox-example.js b/clipboard/firefox-example.js
new file mode 100644
index 0000000..ea289d7
--- /dev/null
+++ b/clipboard/firefox-example.js
@@ -0,0 +1,16 @@
+import { browser, expect } from '@wdio/globals'
+
+describe('Clipboard: Firefox', () => {
+ before(() => browser.url('/example.html'))
+
+ it('should allow the browser to read the clipboard', async () => {
+ const btn = await $('#copyBtn')
+ await btn.click()
+
+ // now you can read the clipboard via, e.g.
+ const clipboardText = await browser.execute(() => navigator.clipboard.readText())
+
+ await expect(clipboardText).toBe('Hello from WebdriverIO clipboard test!')
+ })
+
+})
diff --git a/package.json b/package.json
index 8c1eb9b..354a5a5 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,9 @@
"scripts": {
"api/webdriver": "cross-env EXAMPLE_RECIPE=api wdio run ./wdio.conf.js --spec ./api/webdriver/*.js",
"click": "cross-env EXAMPLE_RECIPE=click wdio run ./wdio.conf.js --spec ./click/example.js",
+ "clipboard": "run-s clipboard:*",
+ "clipboard:chrome": "cross-env BROWSER=chrome EXAMPLE_RECIPE=clipboard wdio run ./wdio.browserChoice.conf.js --spec ./clipboard/chrome-example.js",
+ "clipboard:firefox": "cross-env BROWSER=firefox EXAMPLE_RECIPE=clipboard wdio run ./wdio.browserChoice.conf.js --spec ./clipboard/firefox-example.js",
"component-testing": "run-s component-testing:*",
"component-testing:svelte": "wdio run ./wdio.comp.conf.js --spec ./component-testing/svelte-example.js",
"customMatchers": "cross-env TS_NODE_PROJECT=./customMatchers/tsconfig.json EXAMPLE_RECIPE=customMatchers wdio run ./wdio.conf.js --spec ./customMatchers/example.ts",
diff --git a/wdio.browserChoice.conf.js b/wdio.browserChoice.conf.js
index 868c190..80367dd 100644
--- a/wdio.browserChoice.conf.js
+++ b/wdio.browserChoice.conf.js
@@ -15,8 +15,9 @@ const { FIREFOX_BINARY_PATH } = process.env
const chromeOptions = {
capabilities: {
browserName: 'chrome',
+ acceptInsecureCerts: true,
"goog:chromeOptions": {
- args: process.env.CI ? ['headless', 'disable-gpu'] : ['disable-gpu'],
+ args: process.env.CI ? ['headless', 'disable-gpu'] : [],
prefs: {
"download.default_directory": downloadsDir
}
@@ -31,6 +32,7 @@ const firefoxOptions = {
"moz:firefoxOptions": {
args: process.env.CI ? ['-headless'] : [],
prefs: {
+ "dom.events.asyncClipboard.readText": true, // Allow clipboard read
"browser.download.dir": downloadsDir,
"browser.download.folderList": 2,
"browser.download.manager.showWhenStarting": false,