Reputation: 751
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 :)
Upvotes: 1
Views: 6573
Reputation: 193058
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:
click()
even before the element is visible/clickableclick()
was invoked.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()
Upvotes: 4
Reputation: 5214
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.
Upvotes: 2
Reputation: 52665
Instead of
browser.execute_script(navMenu.click())
try
browser.execute_script('arguments[0].click();', navMenu)
or
navMenu.click()
Upvotes: 2