Selenium-Java-geckodriver: Test execution stops with JavaScript error because "document.getElementById (...) is null"

I ran into this problem for a while now. Looked through many threads on SO and other forums but still clueless.

While automating a simple flow on a web application with Selenium 3.4.0, geckodriver v0.16.1 and Mozilla Firefox 53.0 in the Eclipse Neon v2 IDE, I occasionally get an error on the console:

JavaScript error: https://www.url.com/my, line 1715: TypeError: document.getElementById(...) is null

      

Although using chromedriver v2.29 / Google Chrome 58.0, or using Python, I don't face such a problem.

As soon as this error appears, the test execution stops and finally shows TimeoutException

as follows:

Exception in thread "main" org.openqa.selenium.TimeoutException: Timeout loading page after 300000ms

      

Website URL: https://www.shareinvestor.com/my

HTML DOM:

<div id="sic_sitemap">
  <div id="sic_container">
    <div id="sic_header">
      <h1 id="sic_siteTitle">
        <div id="sic_headerMembershipLink">
          <a id="sic_mobileEdition" href="/mobile">
            <div id="sic_loginContainer" class="sic_logIn" style="">
              <div class="sic_login-wrap">
                <div class="sic_logIn-subscribe">
                  <div class="sic_logIn-bg">
                    <a href="/user/login.html">
                  </div>
                </div>
              </div>
            </div>
            <div id="sic_subHeader">
              <div id="sic_mainNav" class="sic_withRightCorner">
                <div id="sic_sideBar" class="sic_expanded { selected_market_suffix: 'MY'}">
                  <div class="sic_superBanner sic_superBannerTop">
                    <div id="sic_content" class="sic_collapsed">
                      <div id="sic_footer" class="si_fixed">
                      </div>
      

Run codeHide result


So far I've tried the following options but to no avail:

  • Java Click
  • JavascriptExecutor Click
  • Actions Press

Here is my code:

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;

public class 78644072022 {

public static void main(String[] args) {

    System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
    DesiredCapabilities dc = DesiredCapabilities.firefox();
    dc.setCapability("marionette", true);
    WebDriver driver =  new FirefoxDriver(dc);
    driver.manage().window().maximize();
    driver.get("https://www.shareinvestor.com/my");
    WebElement login_button = driver.findElement(By.xpath("//div[@id='sic_loginContainer']/div/div[@class='sic_logIn-bg']/a"));

    //Java Click
    login_button.click();

    //JavascriptExecutor Click
    /*JavascriptExecutor jse = (JavascriptExecutor)driver;
    jse.executeScript("arguments[0].click();", login_button);*/

    //Actions Click
    /*Actions act = new Actions(driver);
    act.moveToElement(login_button).click().build().perform();*/

    driver.findElement(By.xpath("//input[@id='sic_login_header_username']")).sendKeys("debanjan");
    driver.findElement(By.xpath("//input[@id='sic_login_header_password']")).sendKeys("5786");
    driver.findElement(By.xpath("//input[@id='sic_login_submit']")).click();
}
}

      

I am looking for a Java solution with geckodriver to overcome the error JavaScript error:TypeError: document.getElementById(...) is null

On one of the SO threads I saw a solution like this:

You need to do null validation in updateHTML like this:

function updateHTML(elmId, value) {
  var elem = document.getElementById(elmId);
  if(typeof elem !== 'undefined' && elem !== null) {
    document.getElementById(elmId).innerHTML = value;
  }
}

      

Can this be done? Any suggestions and pointers would be helpful.

+3


source to share


5 answers


I think I managed to find what is causing this noise in your script. I have checked your HTML and it seems that the javascript method function showRemaining()

is causing this problem; because it showRemaining()

contains this operator

    document.getElementById('countdown').innerHTML = '';

      

where it tries to set the innerHTML attribute for the element with id from countdown

to '.

But the countdown doesn't exist anywhere on your webpage, hence the error.

TypeError: document.getElementById(...) is null



and somehow selenium can't get past this error. So I think a patch from the developers should help you.

UPDATE:

Basically you need to wait for all elements to load using an implicit wait, once all elements are loaded, then your Javascript error will be resolved and ultimately interacting with the web page won't be hampered by this javascript error:

        driver.get("https://www.shareinvestor.com/my");

        driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
        driver.manage().window().maximize();

        /*String script = "function updateHTML(countdown, value) {" +
                "var elem = document.getElementById('countdown');"+
                "if(typeof elem !== 'undefined' && elem !== null) {"+
                " document.getElementById('countdown').innerHTML = value;"+
                "}"+
                "}";

        ((JavascriptExecutor) driver).executeScript(script);*/

        WebElement login_button = driver.findElement(By.xpath("//div[@id='sic_loginContainer']/div/div[@class='sic_logIn-bg']/a"));

        login_button.click();

        driver.findElement(By.xpath("//input[@id='sic_login_header_username']")).sendKeys("debanjan");
        driver.findElement(By.xpath("//input[@id='sic_login_header_password']")).sendKeys("5786");
        driver.findElement(By.xpath("//input[@id='sic_login_submit']")).click();

      

0


source


I am looking for a Java solution with geckodriver to resolve JavaScript error: TypeError: document.getElementById (...) null

To answer your question, I don't believe there is anything you can do to "fix" this via Java / Selenium. This is a JavaScript error that is coming from the website you are trying to access. You might want to consider contacting your support team, perhaps one of their developers might consider this issue.




Instead of hitting the login button, perhaps go directly to the login page?

driver.get("https://www.shareinvestor.com/user/login.html");

      

+1


source


First . These javascript errors won't run due to some selenium code. Of course, the timeout was caused by selenium (more on that later).

You will get this javascript error regardless of whatever browser you run the url from. But in the case of gecko, you will be notified in the eclipse console, but not in the case of Chrome. If you need to see a java script error in chrome, just run the url in chrome and go to devtools / console (F12). You can also see the same in the firefox console.

  • Chrome Img:

The error is displayed in the Chrome console

Secondly . We are getting a timeout exception because the site is actually taking too long to load. I was waiting for 7 minutes and the page is still loading even now. Selenium will not execute its script unless the page has been fully launched. As a result, we get a timeout exception (not sure about the default page start time). I was thinking about going directly to the login page (" https://www.shareinvestor.com/user/login.html ") and also not delaying the end time entirely.

Intepolation . These java script errors are not a problem for automation. But these page loads really are. This site doesn't seem like a good candidate for automation with this problem.

Update1: otherwise we can also stop the page from loading through another thread, for example by sending the "esc" key sequence using the Action class.

Update2: I tried the same code today and it works great. Below is the piece of code I tried (no change at all)

 public static void main(String[] args) throws InterruptedException 
{
    System.setProperty("webdriver.gecko.driver", "F:\\Softwares\\Selenium\\Webdriver\\geckodriver.exe");
    WebDriver driver = new FirefoxDriver();
    driver.manage().window().maximize();
    driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
    driver.get("https://www.shareinvestor.com/my");
    WebElement login_button = driver.findElement(By.xpath("//div[@id='sic_loginContainer']/div/div[@class='sic_logIn-bg']/a"));

    //Java Click
    login_button.click();
    System.out.println("In Login PAge");

    driver.findElement(By.xpath("//input[@id='sic_login_header_username']")).sendKeys("debanjan");
    driver.findElement(By.xpath("//input[@id='sic_login_header_password']")).sendKeys("5786");
    System.out.println("Entered password");
    driver.findElement(By.xpath("//input[@id='sic_login_submit']")).click();
}

      

Selenium version - 3.4.0

Gecko driver - v0.16.1 (mine 32 bit)

Mozilla - 51.0.1 (Update => It works from 53.02 too)

Hope this helps you. Thank.

+1


source


Looks like XPath is login_button

wrong for :

By.xpath("//div[@id='sic_loginContainer']/div/div[@class='sic_logIn-bg']/a");

      

Should be:

By.xpath("//div[@id='sic_loginContainer']/div/div/div[@class='sic_logIn-bg']/a");

      


This might explain TimeoutException

, since Selenium cannot find a nonexistent item.
EDIT: My mistake, you should see NoSuchElementException

if the item cannot be found.

Regarding the JavaScript error, if you haven't tried using Selenium to access a web element that JavaScript code can handle (element id='countdown'

), Selenium should just ignore the error. Otherwise, there is the possibility of other Selenium bugs such as StaleElementReferenceException

, but this does not seem to be the case.

0


source


This is related to your application HTML page using async javascript and uses some variable reference which is not available at runtime. we had the same problem and asked the developer to follow some best practices for javascript in HTML, like putting the script tag at the end of the page. I have checked the source of the site's HTML page and contains many script tags in between the code. This will block rendering of the DOM. Better ask the developer to follow some guidelines to include the script tag in HTML. you are linking to a link Where should I put the <script> tags in the HTML markup? for best practices.

0


source







All Articles