Clipboard permissions with selenium

2,320 views
Skip to first unread message

truffl...@gmail.com

unread,
Aug 29, 2019, 9:19:15 PM8/29/19
to ChromeDriver Users
Hi - 
Is it possible to set default clipboard permissions to allow with selenium? 

Thing's I've tried - 
chromeOptions.addArguments("--disable-notifications")

// trying to mimic behavior from preferences
Map<String, Object> prefs = new HashMap<>();
Map<String, Object> clipboardSetting = new HashMap<>();
clipboardSetting.put("last_modified", new Date().getTime());
clipboardSetting.put("setting", 1);
Map<String, Object> siteSetting = new HashMap<>();
siteSetting.put("http://localhost:9005,*", clipboardSetting);
prefs.put("profile.content_settings.exceptions.clipboard", siteSetting);
chromeOptions.setExperimentalOption("prefs", prefs);y and paste but it's always denied.

Thanks in advance!


truffl...@gmail.com

unread,
Aug 29, 2019, 9:43:48 PM8/29/19
to ChromeDriver Users
To clarify the above works in GUI, non-headless mode but not in headless mode which is what's required for the automation test...

tri...@google.com

unread,
Aug 30, 2019, 3:50:29 PM8/30/19
to ChromeDriver Users
Hi,
There are restrictions in how clipboard works in headless mode. 
On Macs, the Ctrl C doesn't work correctly.
On Linux & Windows, Cut and Paste within the Chrome session should work, but it will not interact with the system clipboard. So you can't cut something, run the tests, and expect to paste the previous cut. The cut and paste both have to be within the test code.

We could tell more about your case if you attach a verbose ChromeDriver log and the code you use for the cut and the paste.

truffl...@gmail.com

unread,
Aug 30, 2019, 6:43:36 PM8/30/19
to ChromeDriver Users
Thanks for the quick reply!
Link to log is here https://drive.google.com/file/d/1-ZXFfy3b_Mn6hMi_iKG2aSrmWX5CYN6I/view?usp=sharing ( can't seem to figure out how to attach to this reply rip)

We have a web application that needs to support copy and paste btwn different instances of the app (browser tabs in this case) and system clipboard was the most intuitive solution for us..

Test snippet
IWebElement typeNode = graphHomePage.getDraggableNode(NodePaletteTypes.EXPRESSION);
typeNode.dragTo(graphSurface);
assertEquals(1, graphHomePage.getGraphNodesOnCanvas().size());
IWebElement firstNodeOnGraph = graphHomePage.getNodeOnGraph(NodePaletteTypes.EXPRESSION);
firstNodeOnGraph.sendInfernoAltHotKeyCombo("c");
// now paste
firstNodeOnGraph.sendInfernoAltHotKeyCombo("v");


assertEquals(2, graphHomePage.getGraphNodesOnCanvas().size());

There is a listener registered in our app code that listens to alt+c and alt+v respectively.

under the hood of the app we use the navigator.clipboard api to do the copying and pasting
navigator.clipboard
.writeText(graphString)
.then(() => addMessage(Msg.info('Selection copied.')))
.catch(() => addMessage(Msg.warning('Unable to copy selection.')))
navigator.clipboard
.readText()
.then(result => graphService.xmlToGraph(result))
.catch(err => {
// eslint-disable-next-line
console.error('paste & parse error: ', err);
return { err };
})

T Crichton

unread,
Aug 30, 2019, 7:15:13 PM8/30/19
to ChromeDriver Users
What library are you using to connect to ChromeDriver? Those commands are not familiar to us.

truffl...@gmail.com

unread,
Aug 30, 2019, 9:43:28 PM8/30/19
to ChromeDriver Users
Selenium webdriver.

Set up is like this - 
System.setProperty("webdriver.chrome.logfile", "./chromedriver.log");
System.setProperty("webdriver.chrome.verboseLogging", "true");

ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("--window-size=2880,1800");
chromeOptions.addArguments("enable-automation"); // https://stackoverflow.com/a/43840128/1689770
chromeOptions.addArguments("--no-sandbox"); //https://stackoverflow.com/a/50725918/1689770
chromeOptions.addArguments("--disable-dev-shm-usage"); //https://stackoverflow.com/a/50725918/1689770
chromeOptions.addArguments("--disable-browser-side-navigation"); //https://stackoverflow.com/a/49123152/1689770
chromeOptions.addArguments("--disable-gpu"); //https://stackoverflow.com/questions/51959986/how-to-solve-selenium-chromedriver-timed-out-receiving-message-from-renderer-exc
chromeOptions.addArguments("--disable-popup-blocking");
chromeOptions.addArguments("--allow-insecure-localhost");
chromeOptions.addArguments("--ignore-certificate-errors");
chromeOptions.addArguments("--disable-notifications");

String host = config.getString("defaultBaseUrl");

Map<String, Object> prefs = new HashMap<>();
Map<String, Object> clipboardSetting = new HashMap<>();
clipboardSetting.put("last_modified", new Date().getTime());
clipboardSetting.put("setting", 1);
Map<String, Object> siteSetting = new HashMap<>();
siteSetting.put(host + ",*", clipboardSetting);
prefs.put("profile.content_settings.exceptions.clipboard", siteSetting);
chromeOptions.setExperimentalOption("prefs", prefs);

headless = config.getBoolean("headless");

if (headless) {
chromeOptions.addArguments("--headless");
} else {
chromeOptions.addArguments("--disable-infobars");
}

driver = new ChromeDriver(chromeOptions);
driver.get(host);

truffl...@gmail.com

unread,
Aug 30, 2019, 9:45:10 PM8/30/19
to ChromeDriver Users
from the chromedriver log, this is immediately after we fired off the trigger that requires access to the clipboard

[1567204220.324][DEBUG]: DevTools WebSocket Event: Runtime.consoleAPICalled F50EE23E9DCB809A10F0CD7C332B9131 {
   "args": [ {
      "type": "string",
      "value": "paste & parse error: "
   }, {
      "className": "DOMException",
      "description": "DOMException",
      "objectId": "{\"injectedScriptId\":1,\"id\":1}",
      "preview": {
         "description": "DOMException",
         "overflow": false,
         "properties": [ {
            "name": "code",
            "type": "number",
            "value": "0"
         }, {
            "name": "name",
            "type": "string",
            "value": "NotAllowedError"
         }, {
            "name": "message",
            "type": "string",
            "value": "Read permission denied."
         } ],
         "subtype": "error",
         "type": "object"
      },
      "subtype": "error",
      "type": "object"
   } ],
   "executionContextId": 1,
   "stackTrace": {
      "callFrames": [ {
         "columnNumber": 138517,
         "functionName": "",
         "lineNumber": 19,
         "scriptId": "13",
         "url": "http://localhost:9005/static/js/main.0aa8304e.js"
      } ]
   },
   "timestamp": 1567204220323.537,
   "type": "error"
}

T Crichton

unread,
Sep 3, 2019, 6:35:40 PM9/3/19
to ChromeDriver Users
I was able to reproduce the behavior you see.

Setting permissions using the Prefs object is known to not work in headless mode. In version 78, ChromeDriver adds a command to set permissions, but I don't currently see any means to invoke that command from Selenium code. 

I need to do some additional testing to determine if the permissions you need are supported by our new permission command, if so, we'll need to update the Selenium code to support this change as well. If the clipboard permissions aren't supported, ChromeDriver would need more work as well.

So, the clipboard api with headless mode should be supported in a future release of ChromeDriver and Selenium, but it is not today.

Here's how we usually simulate cut and paste:

    Actions action = new Actions(driver);
    action.moveToElement(from).click();
    action.keyDown(Keys.CONTROL).sendKeys("a").keyUp(Keys.CONTROL);
    action.keyDown(Keys.CONTROL).sendKeys("c").keyUp(Keys.CONTROL);
    action.perform();

    action.moveToElement(to).click();
    action.keyDown(Keys.CONTROL).sendKeys("a").keyUp(Keys.CONTROL);
    action.keyDown(Keys.CONTROL).sendKeys("v").keyUp(Keys.CONTROL);
    action.perform();

I confirmed today that this does work in headless mode and between tabs.

But I don't think this will match your use case; I think your web app itself is invoking the clipboard api? 



truffl...@gmail.com

unread,
Sep 3, 2019, 6:41:47 PM9/3/19
to ChromeDriver Users
I think your web app itself is invoking the clipboard api? 

That is correct, hence the pref "hack" to allow permission...
Will you keep me posted on the results of the investigation? The other option we have currently is to get the docker image to work with a virtual display which I'm not looking forward to..


T Crichton

unread,
Sep 6, 2019, 5:14:47 PM9/6/19
to ChromeDriver Users
I confirmed that the command is working for clipboard-read and clipboard-write. It might not work to set the permission to prompt; there's an open bug for that issue with Chromium. I make the changes to the Selenium Java bindings and opened a pull request, but I have no estimate as to when it might make it to a new version of Selenium. You can follow the issue on Selenium: https://github.com/SeleniumHQ/selenium/issues/7539
Reply all
Reply to author
Forward
0 new messages