27

Is there any way to perform a copy and paste using Selenium 2 and the Python bindings?

I've highlighted the element I want to copy and then I perform the following actions

copyActionChain.key_down(Keys.COMMAND).send_keys('C').key_up(Keys.COMMAND)

However, the highlighted text isn't copied.

typ1232
  • 5,535
  • 6
  • 35
  • 51
aaronfalloon
  • 383
  • 1
  • 5
  • 10
  • 1
    It appears you can't perform copy/paste operations in OS X. I believe the command modifier is Keys.META. I've tried all the combinations with: `elem.send_keys(Keys.META, 'a') ` and also `actions.key_down(Keys.META).send_keys('a').perform()` to no avail. – siesta Apr 17 '15 at 21:15
  • I have also tried this in OSX and just cannot get it to work. (Meta, Command, etc.) I can get other keypresses like sending a backspace key to work, though. – Le Roux Bodenstein Jun 29 '15 at 15:41
  • 1
    Corresponding ChromeDriver issue — https://code.google.com/p/chromedriver/issues/detail?id=30 – kangax Nov 10 '15 at 12:39

9 Answers9

28

To do this on a Mac and on PC, you can use these alternate keyboard shortcuts for cut, copy and paste. Note that some of them aren't available on a physical Mac keyboard, but work because of legacy keyboard shortcuts.

Alternate keyboard shortcuts for cut, copy and paste on a Mac

  • Cut => control+delete, or control+K
  • Copy => control+insert
  • Paste => shift+insert, or control+Y

If this doesn't work, use Keys.META instead, which is the official key that replaces the command ⌘ key

source: https://w3c.github.io/uievents/#keyboardevent

Here is a fully functional example:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

browser = webdriver.Safari(executable_path = '/usr/bin/safaridriver')
browser.get("http://www.python.org")
elem = browser.find_element_by_name("q")
elem.clear()
actions = ActionChains(browser)
actions.move_to_element(elem)
actions.click(elem) #select the element where to paste text
actions.key_down(Keys.META)
actions.send_keys('v')
actions.key_up(Keys.META)
actions.perform() 

So in Selenium (Ruby), this would be roughly something like this to select the text in an element, and then copy it to the clipboard.

# double click the element to select all it's text
element.double_click 

# copy the selected text to the clipboard using CTRL+INSERT
element.send_keys(:control, :insert)
Community
  • 1
  • 1
Brad Parks
  • 66,836
  • 64
  • 257
  • 336
  • 2
    I can confirm this solution works on a Mac with chromedriver, where the COMMAND + v trick does not work. – Bjinse Nov 22 '17 at 14:06
  • How do I copy multiple words from a paragraph, instead of just one word? In my document, double-clicking only highlights one word – Testilla Mar 09 '18 at 18:34
25

Pretty simple actually:

from selenium.webdriver.common.keys import Keys

elem = find_element_by_name("our_element")
elem.send_keys("bar")
elem.send_keys(Keys.CONTROL, 'a') # highlight all in box
elem.send_keys(Keys.CONTROL, 'c') # copy
elem.send_keys(Keys.CONTROL, 'v') # paste

I imagine this could probably be extended to other commands as well.

nik7
  • 806
  • 3
  • 12
  • 20
Greg
  • 5,422
  • 1
  • 27
  • 32
  • 5
    Thanks Greg, that's way more straightforward to do than I thought. However, I'm using Mac OSX and am attempting to call send_keys() on a p inside a contenteditable div and it doesn't seem to work. Can anyone confirm this? It seems Mac OSX doesn't support native events. – aaronfalloon Aug 01 '12 at 23:08
  • 1
    interesting, worked with the google input box on an ubuntu 12.04 machine, please edit your post for html – Greg Aug 01 '12 at 23:39
  • 5
    Has anyone tried the equivalent with Chrome and OSX (Keys.COMMAND or Keys.META) and gotten it to work? I've been trying this via wd (https://github.com/admc/wd/) and it does nothing, but I can send other special-ish keys like backspace to a contenteditable and those work just fine. – Le Roux Bodenstein Jun 29 '15 at 15:43
  • 2
    @LeRouxBodenstein Did you ever discover how to do this using the COMMAND key? – chopper draw lion4 Mar 28 '16 at 21:45
  • 2
    Another [answer on this page](https://stackoverflow.com/a/41046276/26510) addresses how to do this on a Mac – Brad Parks Oct 25 '17 at 11:54
8
elem.send_keys(Keys.SHIFT, Keys.INSERT)

It works FINE on macOS Catalina when you try to paste something.

LiuTao
  • 81
  • 1
  • 1
7

Rather than using the actual keyboard shortcut i would make the webdriver get the text. You can do this by finding the inner text of the element.

WebElement element1 = wd.findElement(By.locatorType(locator));
String text = element1.getText();

This way your test project can actually access the text. This is beneficial for logging purposes, or maybe just to make sure the text says what you want it to say.

from here you can manipulate the element's text as one string so you have full control of what you enter into the element that you're pasting into. Now just

 element2.clear();
 element2.sendKeys(text);

where element2 is the element to paste the text into

user2387855
  • 314
  • 4
  • 9
5

I cannot try this on OSX at the moment, but it definitely works on FF and Ubuntu:

import os
import time

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

with open('test.html', 'w') as fp:
    fp.write("""\
<html>
<body>
  <form>
    <input type="text" name="intext" value="ABC">
    <br>
    <input type="text" name="outtext">
  </form>
</body>
</html>
""")

driver = webdriver.Firefox()
driver.get('file:///{}/test.html'.format(os.getcwd()))
element1 = driver.find_element_by_name('intext')
element2 = driver.find_element_by_name('outtext')
time.sleep(1)
element1.send_keys(Keys.CONTROL, 'a')
time.sleep(1)
element1.send_keys(Keys.CONTROL, 'c')
time.sleep(1)
element2.send_keys(Keys.CONTROL, 'v')

The sleep() statements are just there to be able to see the steps, they are of course not necessary for the program to function.

The ActionChain send_key just switches to the selected element and does a send_keys on it.

Anthon
  • 69,918
  • 32
  • 186
  • 246
4

The solutions involving sending keys do not work in headless mode. This is because the clipboard is a feature of the host OS and that is not available when running headless.

However all is not lost because you can simulate a paste event in JavaScript and run it in the page with execute_script.

const text = 'pasted text';
const dataTransfer = new DataTransfer();
dataTransfer.setData('text', text);
const event = new ClipboardEvent('paste', {
  clipboardData: dataTransfer,
  bubbles: true
});
const element = document.querySelector('input');
element.dispatchEvent(event)
Tamlyn
  • 22,122
  • 12
  • 111
  • 127
3

Solution for both Linux and MacOS (for Chrome driver, not tested on FF)

The answer from @BradParks almost worked for me for MacOS, except for the copy/cut part. So, after some research I came up with a solution that works on both Linux and MacOS (code is in ruby). It's a bit dirty, as it uses the same input to pre-paste the text, which can have some side-effects. If it was a problem for me, I'd try using different input, possibly creating one with execute_script.

  def paste_into_input(input_selector, value)
    input = find(input_selector)
    # set input value skipping onChange callbacks
    execute_script('arguments[0].focus(); arguments[0].value = arguments[1]', input, value)
    value.size.times do
      # select the text using shift + left arrow
      input.send_keys [:shift, :left]
    end
    execute_script('document.execCommand("copy")') # copy on mac
    input.send_keys [:control, 'c'] # copy on linux

    input.send_keys [:shift, :insert] # paste on mac and linux
  end
yefrem
  • 666
  • 7
  • 20
1

If you want to copy a cell text from the table and paste in search box,

Actions Class : For handling keyboard and mouse events selenium provided Actions Class

///

/// This Function is used to double click and select a cell text , then its used ctrl+c

/// then click on search box then ctrl+v also verify

/// </summary>

/// <param name="text"></param>

public void SelectAndCopyPasteCellText(string text)

{

  var cellText = driver.FindElement(By.Id("CellTextID"));

  if (cellText!= null)

  {

    Actions action = new Actions(driver);

    action.MoveToElement(cellText).DoubleClick().Perform(); // used for Double click and select the text

    action = new Actions(driver);

    action.KeyDown(Keys.Control);

    action.SendKeys("c");

    action.KeyUp(Keys.Control);

    action.Build().Perform(); // copy is performed

    var searchBox = driver.FindElement(By.Id("SearchBoxID"));

    searchBox.Click(); // clicked on search box

    action = new Actions(driver);

    action.KeyDown(Keys.Control);

    action.SendKeys("v");

    action.KeyUp(Keys.Control);

    action.Build().Perform(); // paste is performed

    var value = searchBox.GetAttribute("value"); // fetch the value search box

    Assert.AreEqual(text, value, "Selection and copy paste is not working");

  }

}

KeyDown(): This method simulates a keyboard action when a specific keyboard key needs to press.

KeyUp(): The keyboard key which presses using the KeyDown() method, doesn’t get released automatically, so keyUp() method is used to release the key explicitly.

SendKeys(): This method sends a series of keystrokes to a given web element.

AmitKS
  • 132
  • 4
0

If you are using Serenity Framework then use following snippet:

            withAction().moveToElement(yourWebElement.doubleClick().perform();
            withAction().keyDown(Keys.CONTROL).sendKeys("a");
            withAction().keyUp(Keys.CONTROL);
            withAction().build().perform();

            withAction().keyDown(Keys.CONTROL).sendKeys("c");
            withAction().keyUp(Keys.CONTROL);
            withAction().build().perform();

            withAction().keyDown(Keys.CONTROL).sendKeys("v");
            withAction().keyUp(Keys.CONTROL);
            withAction().build().perform();

            String value = yourWebElement.getAttribute("value");
            System.out.println("Value copied: "+value);

Then send this value wherever you want to send:

destinationWebElement.sendKeys(value);
            
Bayram Binbir
  • 1,531
  • 11
  • 11