playwright: [BUG] browser.newContext: Unknown permission: clipboard-read for webkit

Context:

  • Playwright Version: 1.20.1
  • Operating System: Mac
  • Node.js version: 14.6
  • Browser: webkit

Code Snippet

const config: PlaywrightTestConfig = {
    globalTeardown: require.resolve('../src/utils/teardown'),
    workers: configList.workers,
    use: {
        contextOptions: {
            userAgent: configList.userAgent,
            permissions: ['clipboard-read', 'clipboard-write']
        },
    test('test', async ({ browserName, page }) => {
        expect(await page.screenshot({ fullPage: true, timeout: 4000 })).toMatchSnapshot(`${browserName}-EN.png`);
    });

Describe the bug

Test is failing for webkit browser, if config file contains permissions: ['clipboard-read', 'clipboard-write'] however there is not any clipboard event is being used in this test

error :

  3) [Desktop Firefox] › search/.test.ts:38:5 › Landing page Test Suite › test

    browser.newContext: Unknown permission: clipboard-read

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 10
  • Comments: 27 (2 by maintainers)

Commits related to this issue

Most upvoted comments

We suggest to set permission per browser. Most likely, you already have test projects with different browsers configured, so just move permission to the respective project.

// playwright.config.ts

export default {
  projects: [
    {
      name: 'chromium',
      browserName: 'chromium',
      use: {
        contextOptions: {
          // chromium-specific permissions
          permissions: ['clipboard-read', 'clipboard-write'],
        },
      },
    },
    {
      name: 'firefox',
      browserName: 'firefox',
      use: {
        contextOptions: {
          // firefox-specific permissions
          permissions: ['geolocation'],
        },
      },
    },
  ],
};

This approach should work

projects: [{
  name: "chromium",
  use: {
    ...devices["Desktop Chrome"],
    contextOptions: {
      // chromium-specific permissions
      permissions: ['clipboard-read', 'clipboard-write'],
    },
  },
},


{
  name: "firefox",
  use: {
    ...devices["Desktop Firefox"],
    launchOptions: {
      firefoxUserPrefs: {
        'dom.events.asyncClipboard.readText': true,
        'dom.events.testing.asyncClipboard': true,
      },
    }
  },
},

{
  name: "webkit",
  use: { ...devices["Desktop Safari"] },
}]

im also facing the same issue.

any update on this issue?? i’m facing it on webkit and firefox ? @dgozman @mxschmitt

This worked for me, except in Safari. If anyone can give me a hint on how to setup the proper permissions for safari, I would be very happy.

In the meantime I solved it by mocking the clipborad API and find it might be worth sharing:

e2e/utils/index.ts

import { Page } from "@playwright/test";

/**
 * this will mock the browsers clipboard API, since it might not be available in the test environment
 * due to invalid permissions. It's recommended to use this function in the beforeAll or beforeEach hook
 * of the test to inject the mock into the page very early. It will e.g. not work if it's called after
 * page.goto() has been called.
 */
export const mockClipboardAPI = async (page: Page) =>
  await page.addInitScript(() => {
    // create a mock of the clipboard API
    const mockClipboard = {
      clipboardData: "",
      writeText: async (text: string) => {
        mockClipboard.clipboardData = text;
      },
      readText: async () => mockClipboard.clipboardData,
    };

    // override the native clipboard API
    Object.defineProperty(navigator, "clipboard", {
      value: mockClipboard,
      writable: false,
      enumerable: true,
      configurable: true,
    });
  });

e2e/mytest.ts

import { mockClipboardAPI } from "e2e/utils/testutils";

test.beforeEach(async ({ page }) => {
  await mockClipboardAPI(page);
});

test("I am a test that needs to validate that some text was copied into the clipboard", async ({
  page,
}) => {
  /**
   * this might be replaces by an interaction with the UI,
   * in which the user copies something into the clipboard
   */
  await page.evaluate(() =>
    navigator.clipboard.writeText("I was copied into the clipboard")
  );

  const clipboardText = await page.evaluate(() =>
    /**
     * this will call the mock instead of the real clipboard API. To make
     * sure the mock was actually used, go to the mockClipboardAPI function
     * and change the return value of the readText function to some test
     * data and see if will end up here.
     */
    navigator.clipboard.readText()
  );

  expect(clipboardText).toBe("I was copied into the clipboard");
});

I had the same issue in Firefox, CodeceptJS + Playwright. In Firefox no permission is needed to have working “copy of text to clipboard” (note it works in secure sites only).

It would be great if Playwright was able to suppress the error browser.newContext: Unknown permission: clipboard-write if given browser doesn’t provide that feature. Currently I must allow such setting in test for Chromium and not for Firefox which makes tests more complex.

@dgozman Could it be enhanced, so that if its included in the config file it will has no effect on webkit rather than make it fail, as the same config ia running agaisnt chrome and firefox in the same instance as well

Workaround for Firefox:

test('Firefox clipboard', async ({}) => {
  const browser = await firefox.launch({
    firefoxUserPrefs: {
      'dom.events.asyncClipboard.readText': true,
      'dom.events.testing.asyncClipboard': true,
    },
  });

  const page = await browser.newPage();

  await page.goto('https://copy-current-url-button.webflow.io/');
  await page.locator('#copy-status').click();

  const clipboardContents = await page.evaluate('navigator.clipboard.readText()');

  console.log(clipboardContents);
});