1

I've got an issue with browser.execute_script while using selenium with python. There is an element that i'd like to click (it's xpath below)

"//*[@id='listFav_FI410_23244709400000_FAGNNURROR_IPOF_APP_P43070_W43070A_CP000A001_40']/table/tbody/tr/td[1]"

I try to do it with:

navMenu = browser.find_element_by_xpath("//*[@id='listFav_FI410_23244709400000_FAGNNURROR_IPOF_APP_P43070_W43070A_CP000A001_40']/table/tbody/tr/td[1]")
time.sleep(3)
browser.execute_script(navMenu.click())

And it works (So it clicks desired element) but right after doing it it throws an error that terminates the script:

selenium.common.exceptions.WebDriverException: Message: unknown error: 'script' must be a string

What am I doing wrong? Is there a way to skip this error? Thx for wasting your time on helping me :)

8
  • You are passing a function call to .execute_script, you need to pass it a string, or just call navMenu.click() Commented Sep 5, 2018 at 14:14
  • just use navMenu.click() Commented Sep 5, 2018 at 14:15
  • @RyanWilson ok, so what is the correct way of doing it? Commented Sep 5, 2018 at 14:16
  • replace browser.execute_script(navMenu.click()) with navMenu.click() Commented Sep 5, 2018 at 14:16
  • @Nihal - it doesn't work- it throws error "element is not visible" Commented Sep 5, 2018 at 14:17

3 Answers 3

4

This error message...

selenium.common.exceptions.WebDriverException: Message: unknown error: 'script' must be a string

...implies that the method execute_script() was invoked with wrong type of parameters.

The execute_script() method is defined as:

execute_script(script, *args)
    Synchronously Executes JavaScript in the current window/frame.

Where:
    script: The JavaScript to execute
    *args: Any applicable arguments for your JavaScript.

In your code trial executeScript() method will take the reference of the element as arguments[0] along with the method to be performed (in this case click()) and the reference should be provided thereafter. So @Andersson's solution should have worked.

navMenu = browser.find_element_by_xpath("//*[@id='listFav_FI410_23244709400000_FAGNNURROR_IPOF_APP_P43070_W43070A_CP000A001_40']/table/tbody/tr/td[1]")
browser.execute_script("arguments[0].click()", navMenu)

You can find a detailed discussion in What does argument [0] and argument [1] mean in javascriptexecutor in Selenium WebDriver?


The hint to your main issue is the error element not visible which implies either of the following cases:

  • You are trying to invoke click() even before the element is visible/clickable
  • Element is not within the Viewport when click() was invoked.

Solution

Two pottential solutions will be as follows:

  • Induce WebDriverWait for the element to be clickable as follows:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    # other lines of code
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[@id='listFav_FI410_23244709400000_FAGNNURROR_IPOF_APP_P43070_W43070A_CP000A001_40']/table/tbody/tr/td[1]"))).click()
    
  • Use executeScript() method to bring the element within the Viewport and then invoke click() as follows:

    navMenu = browser.find_element_by_xpath("//*[@id='listFav_FI410_23244709400000_FAGNNURROR_IPOF_APP_P43070_W43070A_CP000A001_40']/table/tbody/tr/td[1]")
    browser.execute_script("arguments[0].scrollIntoView(true);",navMenu);
    navMenu.click()
    
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much! WebDriverWait for the element to be clickable works perfectly.
2

Instead of

browser.execute_script(navMenu.click())

try

browser.execute_script('arguments[0].click();', navMenu)

or

navMenu.click()

8 Comments

It doesn't cause any errors now, but it doesn't actually click anything. I added simple print('ooo') right after browser.execute_script('arguments[0].click();', navMenu) and I get ooo in the Shell, but nothing happens on the website. I can't use navMenu.click() as webdriver doesn't see the element
Share HTML or/and page URL
sorry but I can't share the link as this website contains condfidential information (you would have to log in and obviously I cannot give you credentials). I think that the root of this problem is that the entire website is generated by couple Java Script scripts. I've noticed that when I use navMenu.click() in shell (while script is running) it works, but first I have to actually click somewhere Is there a way to activate Java Script?
Or maybe there is a way to tell script not to terminate process after receiving error mentioned in my question? Simpy ignore it and go with another task because as I said- it works, script actually clicks desired element- the problem is that it crashes right after it (but the element that I wanted to be loaded is loaded)
browser.execute_script(navMenu.click()) just executes navMenu.click(). It doesn't matter how you call the method. Using as browser.execute_script(navMenu.click()) make no sense. Try to implement proper ExplicitWait
|
2

The correct way to execute a script is to actually write a JavaScript script!.

The click() function of selenium is on the element of the DOM you have located not a script.

As @Andersson suggested try browser.execute_script('arguments[0].click();', navMenu)

I can see you added a sleep for 3 seconds... Using Selenium we generally use WebDriverWait you can learn more about wait's here.

If it's too complicated you can just start with driver.implicitly_wait(3) instead of sleep.

Edit:

If the Element is not displayed yet you can just use navMenu.is_displayed()

Hope this helps you.

6 Comments

It doesn't cause any errors now, but it doesn't actually click anything. I added simple print('ooo') right after browser.execute_script('arguments[0].click();', navMenu) and I get ooo in the Shell, but nothing happens on the website. Thanks for advice (about using WebDriverWait).
my recommendation is to use wait for element!
I did, and somehow it sees it but then cannot click on it as it is not visible: try:#waits until element is prestent element7_present = EC.presence_of_element_located((By.XPATH, "//*[@id='listFav_FI410_23244709400000_FAGNNURROR_IPOF_APP_P43070_W43070A_CP000A001_40']/table/tbody/tr/td[1]"))#web element identification WebDriverWait(browser, 30).until(element7_present)#max sleep time defined except TimeoutException:#error message definition print('Timed out waiting for page to load')
I know that it sounds stupid- there is wait and script sees it as it goes to another action but then cannot perform the click as "element is not visible"
see edit... if it does not help it may be because the site is built in Angular
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.