Cannot read property 'click' of undefined while using Java Script Executor in Selenium

心不动则不痛 提交于 2021-02-09 01:47:55

问题


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();");

回答1:


This error message...

Cannot read property 'click' of undefined

...implies that the click() method can't be executed as the WebElement haven't completely 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 completely 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.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    



回答2:


This is the wrong way to pass element into the JSExecutor, you need to combine 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);



回答3:


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();");




回答4:


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();");



回答5:


Why do you use js executor? Try

WebElement element = driver.findElement(By.className(CLASS_NAME));
element.click();


来源:https://stackoverflow.com/questions/53514947/cannot-read-property-click-of-undefined-while-using-java-script-executor-in-se

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!