Ashvitha
Ashvitha

Reputation: 5966

How to paste text from clipboard through selenium-webdriver and Java?

I want have a text that is copied to the clipboard and would want to paste that into a text field.

Can someone please let me know how to do that

for ex:-

driver.get("https://mail.google.com/");
  
driver.get("https://www.guerrillamail.com/");
driver.manage().window().maximize();
driver.findElement(By.id("copy_to_clip")).click(); -->copied to clipboard
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.findElement(By.id("nav-item-compose")).click(); 
  
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.findElement(By.name("to")).???;//i have to paste my text here that is copied from above

Upvotes: 10

Views: 60325

Answers (9)

optimistic_creeper
optimistic_creeper

Reputation: 2799

If clicking in the button with id 'copy_to_clip' really copies the content to clipboard then you may use keyboard shortcut option. I think, you might have not tried with simulating CTRL + v combination. Activate your destination text field by clicking on it and then use your shortcut. This may help.

Code Snippets:

driver.findElement(By.name("to")).click(); // Set focus on target element by clicking on it
   
// now paste your content from clipboard
Actions actions = new Actions(driver);
actions.sendKeys(Keys.chord(Keys.LEFT_CONTROL, "v")).build().perform();

Upvotes: 6

Charlie
Charlie

Reputation: 9118

I came up with this to test pasting using the clipboard API. A big part of the problem was permissions that as of 12/2020 need to be kinda hacked in:

    // Setup web driver
    ChromeOptions options = new ChromeOptions();
    
    Map<String, Object> prefs = new HashMap<>();
    Map<String, Object> profile = new HashMap<>();
    Map<String, Object> contentSettings = new HashMap<>();
    Map<String, Object> exceptions = new HashMap<>();
    Map<String, Object> clipboard = new HashMap<>();
    Map<String, Object> domain = new HashMap<>();
    
    // Enable clipboard permissions
    domain.put("expiration", 0);
    domain.put("last_modified", System.currentTimeMillis());
    domain.put("model", 0);
    domain.put("setting", 1);
    clipboard.put("https://google.com,*", domain);      //   <- Replace with test domain
    exceptions.put("clipboard", clipboard);
    contentSettings.put("exceptions", exceptions);
    profile.put("content_settings", contentSettings);
    prefs.put("profile", profile);
    options.setExperimentalOption("prefs", prefs);
    
    // [...]
    driver.executeScript("navigator.clipboard.writeText('sample text');");
    
    pasteButton.click();

Javascript in running in browser:

    // Button handler
    navigator.clipboard.readText().then(t-> console.log("pasted text: " + t));

Though if you ever spawn another window or that window loses focus, you'll get a practically-silent JavaScript error:

// JS console in browser
"DOMException: Document is not focused."

// error thrown in promise
{name: "NotAllowedError", message: "Document is not focused."}

So we need to figure out some way to bring the window into focus. We also need to prevent any other test code from interfeering with the clipboard while we are using it, so I created a Reentrant Lock.

I'm using this code to update the clipboard:

Test code:

    try {
        Browser.clipboardLock.lock();
        b.updateClipboard("Sample text");
        b.sendPaste();
    }finally {
        Browser.clipboardLock.unlock();
    }

Browser Class:

    public static ReentrantLock clipboardLock = new ReentrantLock();
    
    public void updateClipboard(String newClipboardValue) throws InterruptedException {
        if (!clipboardLock.isHeldByCurrentThread())
            throw new IllegalStateException("Must own clipboardLock to update clipboard");
        
        for (int i = 0; i < 20; i++) {
            webDriver.executeScript("" +
                    "window.clipboardWritten = null;" +
                    "window.clipboardWrittenError = null;" +
                    "window.textToWrite=`" + newClipboardValue + "`;" +
                    "navigator.clipboard.writeText(window.textToWrite)" +
                    "   .then(()=>window.clipboardWritten=window.textToWrite)" +
                    "   .catch(r=>window.clipboardWrittenError=r)" +
                    ";"
            );
            
            while (!newClipboardValue.equals(webDriver.executeScript("return window.clipboardWritten;"))) {
                Object error = webDriver.executeScript("return window.clipboardWrittenError;");
                if (error != null) {
                    String message = error.toString();
                    try {
                        message = ((Map) error).get("name") + ": " + ((Map) error).get("message");
                    } catch (Exception ex) {
                        log.debug("Could not get JS error string", ex);
                    }
                    if (message.equals("NotAllowedError: Document is not focused.")) {
                        webDriver.switchTo().window(webDriver.getWindowHandle());
                        break;
                    } else {
                        throw new IllegalStateException("Clipboard could not be written: " + message);
                    }
                }
                Thread.sleep(50);
            }
        }
    }
    ````

Upvotes: 2

undetected Selenium
undetected Selenium

Reputation: 193308

As per your question as you are already having some text within the clipboard to paste that into a text field you can use the getDefaultToolkit() method and you can use the following solution:

//required imports
    import java.awt.HeadlessException;
    import java.awt.Toolkit;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.UnsupportedFlavorException;
    import java.io.IOException;
    //other lines of code
    
    driver.findElement(By.id("copy_to_clip")).click(); //text copied to clipboard
    
    String myText = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor); // extracting the text that was copied to the clipboard
    
    driver.findElement(By.name("to")).sendKeys(myText);//passing the extracted text to the text field
    

Upvotes: 6

Franco DeAmicis
Franco DeAmicis

Reputation: 21

Thank you for posting the code below to set the clipboard permissions. It allowed me to copy and paste using the clipboard api in chromeheadless mode for Selenium Webdriver. There is one caveat. It worked perfectly in Windows. When I tried using the same code with Selenium WebDriver/Chromeheadless on my MacBook, my script failed at the point where I was pasting. This means the clipboard permissions aren't setting properly in the MacBook. Are there any tweeks I can add to the permissions code below to get it to work on the MacBook for chromeheadless. Thank you in advance for any help

// Setup web driver
ChromeOptions options = new ChromeOptions();

 Map<String, Object> prefs = new HashMap<>();
 Map<String, Object> profile = new HashMap<>();
 Map<String, Object> contentSettings = new HashMap<>();
 Map<String, Object> exceptions = new HashMap<>();
 Map<String, Object> clipboard = new HashMap<>();
 Map<String, Object> domain = new HashMap<>();

// Enable clipboard permissions
domain.put("expiration", 0);
domain.put("last_modified", System.currentTimeMillis());
domain.put("model", 0);
domain.put("setting", 1);
clipboard.put("https://google.com,*", domain);      //   <- Replace with test 
domain
exceptions.put("clipboard", clipboard);
contentSettings.put("exceptions", exceptions);
profile.put("content_settings", contentSettings);
prefs.put("profile", profile);
options.setExperimentalOption("prefs", prefs);

Upvotes: 0

Stanislav Pankevich
Stanislav Pankevich

Reputation: 11388

I have found this SO question while looking for a solution using SeleniumBase but could not find it. After some research, this is what has worked for me in Python:

In my test subclass of the BaseCase, I have added this method:

class E2ECase(BaseCase):
    def paste_text(self) -> str:
        self.driver.set_permissions("clipboard-read", "granted")
        pasted_text = self.execute_script("const text = await navigator.clipboard.readText(); return text;")
        return pasted_text

The pasted value can then be filled in to a text field.

Upvotes: 0

Sam
Sam

Reputation: 1

using System.Text; using System.Text.RegularExpressions;

Negut: TextCopy

public string GetClipboardText()
{
    var text = new TextCopy.Clipboard().GetText();
    return text;
}

Upvotes: 0

Sameera De Silva
Sameera De Silva

Reputation: 2000

The easiest way to do this using below code I derived from http://www.avajava.com/tutorials/lessons/how-do-i-get-a-string-from-the-clipboard.html

  private void copiedTextVerification() throws IOException, UnsupportedFlavorException {

        //Verify that text is copied when clicked on lnk_Copy_Permalink and stays on clipboard and not empty.
        driver.findElement(By.id("button_To_copy_Text")).click();
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Clipboard clipboard = toolkit.getSystemClipboard();
        String actualCopedText = (String) clipboard.getData(DataFlavor.stringFlavor);
        System.out.println("String from Clipboard:" + actualCopedText);
        //Assert the copied text contains the expected text.
        Assert.assertTrue(actualCopedText.startsWith("Expected Copied Text"));
        //Send the copied text to an element.
        driver.findElement(By.id("button_To_send_Text")).sendKeys(actualCopedText);

    }

Upvotes: 0

JackhammersForWeeks
JackhammersForWeeks

Reputation: 967

This worked well for me when pasting emoji into a text box

    import java.awt.Toolkit;
    import java.awt.datatransfer.Clipboard;
    import java.awt.datatransfer.StringSelection;

    String emoji="β˜ΊοΈπŸ˜©πŸ˜β€οΈπŸ˜’πŸ˜ŠπŸ˜˜πŸ˜³πŸ‘ŒπŸ½πŸ˜πŸ˜πŸ˜­πŸ˜”πŸ’•πŸ‘Œ";
    StringSelection stringSelection = new StringSelection(emoji);
    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    clipboard.setContents(stringSelection, null);
    WebElement input = your_driver.findElementByXPath(your_xpath);
    input.sendKeys(Keys.SHIFT, Keys.INSERT);

Upvotes: 0

kashgo
kashgo

Reputation: 159

Pyperclip works great for getting text copied to the clipboard - https://pypi.org/project/pyperclip/

Once you have some text copied to the clipboard, use pyperclip.paste() to retrieve it.

Upvotes: 0

Related Questions