TransWikia.com

Fixing an asynchronous JavaScript timeout out issue with Selenium in C#

Software Quality Assurance & Testing Asked by Dodzi Dzakuma on October 25, 2021

Background

I am running the following JavaScript code using the C# bindings for Selenium:

async function addTableCellClassInjector(row, tableIndex, rowIndex) {
    for (let columnIndex = 0; column = row.cells[columnIndex]; columnIndex++) {
        column.classList.add('agtelc-' + tableIndex + '-' + rowIndex + '-' + columnIndex);
    }
}

async function addTableRowClassInjector(table, tableIndex) {
    for (let rowIndex = 0; row = table.rows[rowIndex]; rowIndex++) {
        row.classList.add('agtelr-' + tableIndex + '-' + rowIndex);
        addTableCellClassInjector(row, tableIndex, rowIndex);
    }
}

async function addTableClassInjector(tables) {
    for (let tableIndex = 0; tableIndex < tables.length; tableIndex++) {
        tables[tableIndex].classList.add('agtelt-' + tableIndex);
        addTableRowClassInjector(tables[tableIndex], tableIndex);
    }
}

setTimeout(addTableRowClassInjector(document.querySelectorAll('table')), 200);

Using the following C# code:

public bool ExecuteJavaScript(string script, params string[] parameters)
{
    var previousTimeOut = _driver.Manage().Timeouts().AsynchronousJavaScript;
    try
    {
        _driver.Manage().Timeouts().AsynchronousJavaScript = TimeSpan.FromMinutes(3);
        ((IJavaScriptExecutor) _driver).ExecuteAsyncScript(script, parameters);
        return true;
    }
    catch (Exception anomaly)
    {
        ExceptionLogger.LogException(anomaly);
        return false;
    }
    finally
    {
        _driver.Manage().Timeouts().AsynchronousJavaScript = previousTimeOut;
    }
}

I’m using this to add CSS classes to all parts of a table on the page so that I can pinpoint a cell, table, or row on the page. I’m working with what I’ve got, and having the development team add classes for this is not an option (legacy code).

Please note that I’m only using chrome. The use of other browsers is out of the scope of this question.

On the test page I ran this on to test to make sure that this class injection works, I’ve had no issues, but when I run it against actual application code to run my automation Selenium throws a timeout error after 60 seconds.

Here is the error even though I have set a longer timeout:

The HTTP request to the remote WebDriver server for URL http://localhost:55033/session/c7e3574dac653228f9d62c37c1fd3cf2/execute/async timed out after 60 seconds.

As you can see from my code C# code I have attempted to increase the timeout for this to run to 3 minutes, but I’m still getting a timeout error after 60 seconds.

It also seems like despite my best efforts to run the JavaScript code entirely asynchronously, Selenium appears to be waiting for the JavaScript operation to finish. If I can kick off this JavaScript entirely asynchronously and ensure Selenium doesn’t wait for the JavaScript to finish, but just kicks it into the JavaScript execution loop, I have methods I can use to wait and confirm that the JavaScript call is finished (so assume this is possible as how I am waiting to confirm that is out of the scope of this question).

Questions

  1. Why isn’t Selenium kicking off my JavaScript asynchronously?
  2. Why isn’t Selenium respecting the timeout I specified?

Ultimately, this issue here is it will take more than 60 seconds for my script to run in a number of situations, but Selenium is timing out at 60 seconds. Anything to optimize to be less than 60 seconds or achieve the goals of the script within my restrictions helps.

2 Answers

If you are using a RemoteWebDriver then you also need to set the 3rd parameter commandTimeout like this:

Driver = new RemoteWebDriver(new Uri(""), browserOptions.ToCapabilities(),TimeSpan.FromSeconds(120));

Answered by Nikolay Advolodkin on October 25, 2021

The ExecuteAsyncScript is a means to use a callback in your JavaScript code, which you are not. It does not make the C# code async. See the documentation.

If you want the C# code to be Async put the call in a background worker.

Answered by Niels van Reijmersdal on October 25, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP