I am getting an error:
Cannot read property 'click' of undefined
while trying to click a button using java script executor. I have tried many different approach to click the button using action classes, webdriverwait etc but none seems to work.Java Script is working in console but when i am using in my code i am unable to click the button and getting the mentioned error
The html dom looks as below:
<div>
<a class="button button--new-resource" href="/admin/certificate_types/new">
<img src="/assets/icon-add-user-e2a98953aa1855b15304eb16415b536ee92e579ce89f429bcdd062faa855e261.svg" alt="Icon add user"> New Certificate Type
</a>
</div>
My selenium script is as below
JavascriptExecutor js=(JavascriptExecutor) driver;
js.executeScript("var x= document.getElementsByClassName('button button--new-resource')[0];"+"x.click();");
I am getting an error:
Cannot read property 'click' of undefined
while trying to click a button using java script executor. I have tried many different approach to click the button using action classes, webdriverwait etc but none seems to work.Java Script is working in console but when i am using in my code i am unable to click the button and getting the mentioned error
The html dom looks as below:
<div>
<a class="button button--new-resource" href="/admin/certificate_types/new">
<img src="/assets/icon-add-user-e2a98953aa1855b15304eb16415b536ee92e579ce89f429bcdd062faa855e261.svg" alt="Icon add user"> New Certificate Type
</a>
</div>
My selenium script is as below
JavascriptExecutor js=(JavascriptExecutor) driver;
js.executeScript("var x= document.getElementsByClassName('button button--new-resource')[0];"+"x.click();");
Share
Improve this question
edited Nov 28, 2020 at 21:18
undetected Selenium
194k44 gold badges303 silver badges381 bronze badges
asked Nov 28, 2018 at 8:18
B.MishraB.Mishra
1171 gold badge3 silver badges9 bronze badges
1
- 1 Why are you using a javascript executor instead of findElements and the click() method? – DMart Commented Dec 2, 2020 at 4:20
5 Answers
Reset to default 2This error message...
Cannot read property 'click' of undefined
...implies that the click()
method can't be executed as the WebElement haven't pletely rendered within the DOM Tree and the element is still in undefined state.
Details
As you mentioned that the "Java Script is working in console" that implies the JavaScript is perfecto. The main issue is the element haven't rendered pletely within the HTML DOM.
Solution
As a solution, you need to induce you need to induce WebDriverWait for the visibilityOfAllElementsLocatedBy()
and you can use either of the following Locator Strategies:
Using
cssSelector
:new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector(".button.button--new-resource"))); ((JavascriptExecutor) driver).executeScript("var x= document.getElementsByClassName('button button--new-resource')[0];"+"x.click();");
Using
xpath
:new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//*[@class='button button--new-resource']"))); ((JavascriptExecutor) driver).executeScript("var x= document.getElementsByClassName('button button--new-resource')[0];"+"x.click();");
Best practices
However, as per best practices to click on the element you need to induce WebDriverWait for the element_to_be_clickable()
and you can use either of the following Locator Strategies:
Using
CSS_SELECTOR
:WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.button.button--new-resource[href='/admin/certificate_types/new']>img[alt='Icon add user']"))).click()
Using
XPATH
:WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@class='button button--new-resource' and @href='/admin/certificate_types/new']/img[@alt='Icon add user']"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.mon.by import By from selenium.webdriver.support import expected_conditions as EC
This is the wrong way to pass element into the JSExecutor, you need to bine it with FindElement call. In your case, the script might be executed before the element can be found, resulting 'undefined' error.
// find the element
var element = new WebDriverWait(driver, 20).until(ExpectedConditions.ElementToBeClickable(By.xpath("//*[@class='button button--new-resource']")));
// execute the click on the element you have found
((JavascriptExecutor)driver).ExecuteScript("arguments[0].click();", element);
the problem is in quotation marks
js.executeScript("document.getElementsByClassName('button button--new-resource')[0].click();");
should do the job
if there is only one button
<a class="button button--new-resource" href="/admin/certificate_types/new">
use document.getElementByClassName
and do not use index:
js.executeScript("document.getElementByClassName('button button--new-resource').click();");
your locator is wrong , its a multi class element use '.' instead of space
js.executeScript("var x= document.getElementsByClassName('button.button--new-resource')[0];"+"x.click();");
Why do you use js executor? Try
WebElement element = driver.findElement(By.className(CLASS_NAME));
element.click();