Search code examples
pythonseleniumclipboardbookmarklet

Python selenium not executing bookmarklet properly


I have a bookmarklet that executes successfully from the browser:

javascript:!function(a){var b=document.createElement("textarea"),c=document.getSelection();b.textContent= a,document.body.appendChild(b),c.removeAllRanges(),b.select(),document.execCommand("copy"),c.removeAllRanges(),document.body.removeChild(b);}(<text here>);

When I try to execute this through the Selenium webdriver using Python it is returning None. Any thoughts on how to get this to copy the text to the clipboard like the bookmarklet? Full code is below:

from selenium import webdriver

chromeOptions = webdriver.ChromeOptions()
chromeOptions.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=chromeOptions, desired_capabilities=chromeOptions.to_capabilities())
driver.implicitly_wait(5)

driver.get("websitehere")

js = """javascript:!function(a){var b=document.createElement("textarea"),c=document.getSelection();b.textContent= a,document.body.appendChild(b),c.removeAllRanges(),b.select(),document.execCommand("copy"),c.removeAllRanges(),document.body.removeChild(b);}(<texthere>);
"""

print(driver.execute_script(js))

Solution

  • After some reading online it looks this type of work flow is blocked due to security concerns. I was seeing this error in the console chrome document.execCommand(‘cut’/‘copy’) was denied because it was not called from inside a short running user-generated event handler.

    Note that below did not work on Firefox only Chrome may start failing on Chrome in the next couple versions.

    from selenium import webdriver
    import time
    import pyperclip
    import pyautogui
    
    
    driver = webdriver.Chrome(executable_path=r'C:\\Path\\To\\chromedriver.exe')
    driver.get("https://www.google.com")
    time.sleep(2)
    pyautogui.hotkey('ctrl', 'shift', 'j')
    time.sleep(2)
    
    js2 = """
    var testCopy = function(a) {
    var b=document.createElement("textarea"), c=document.getSelection();
    b.textContent = a,
    document.body.appendChild(b)
    c.removeAllRanges()
    b.setAttribute("id", "testid")
    b.select()
    document.execCommand("copy")
    console.log('copy success', document.execCommand('copy'));
    c.removeAllRanges();
    }
    
    testCopy("ThisText")
    
    """
    
    driver.execute_script(js2)
    time.sleep(1)
    a = pyperclip.paste()
    print(a)