0

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.

1
  • 1
    Can you try by (1) also increasing the WebDriver's timeout to 3 minutes (it's a parameter when creating new ChromeDriver object) and (2) add this to ChromeOptions: ´options.AddArgument("no-sandbox");´
    – FDM
    Commented Jul 20, 2020 at 6:07

2 Answers 2

1

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.

4
  • Thanks for your explanation. I may be able to use a background worker to achieve what I want, but that still doesn't resolve the main portion of this question. I'm getting a timeout error when my script goes over 60 seconds even though I have set the asynchronous script timeout to 3 minutes. That should me that it shouldn't timeout until it hits the 3 minute mark, but I get a timeout after 60 seconds no matter what I do. Ultimately, it doesn't matter if the code blocks my C# code or not. That is fine, but I need this to run until completion. Updating my question with relevant details. Commented Jul 19, 2020 at 12:41
  • The code of the timeout looks correct, what error are you getting? Commented Jul 19, 2020 at 14:38
  • 1
    Also better to split questions, instead of asking 4 in one :) Commented Jul 19, 2020 at 14:38
  • I removed the additional questions and added the error message. Commented Jul 19, 2020 at 14:55
0

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.