0

Java

JavascriptExecutor js = (JavascriptExecutor) driver;
Boolean ready = (Boolean)js.executeScript("the below JavaScript");

JavaScript

var ready = false;
window.onload = function() {
    ready = true;
}
window.sleep = function() {
    return new Promise(resolve => setTimeout(resolve, 2000));
}
for(var i = 0; i < 30; i++) {
    if(ready) {
           return true;
    }
    await sleep();
 }
 return false;

UPDATE: Sorry about the previous syntax error "funtion" in my post. That was a typo not in my actual code. All syntax errors should be gone, but I still get "SyntaxError: Unexpected identifier".

What this code is trying to do is wait for a maximum amount of time for the page to be loaded. I typically return document.readyState to check for that condition but in unique circumstances Chrome will suddenly stop loading the page and document.readyState hangs for 5+ minutes. This is killing my code so I am attempting to develop single-threaded code to kind of mimic a typically multi-threaded process.

Since JavaScript is single threaded (such a disappointing feature for a cool language like JavaScript), we have to be creative.

This code works in the browser console if you replace return true; with console.log('true'); and return false; with console.log('false'); so I don't see what the problem is.

1 Answer 1

1

Indeed there are some mistakes in your JavaScript code.

The first mistake is, in third line window.sleep = funtion() { return new Promise(resolve => setTimeout(resolve, 2000)); }, the function spelling is wrong.

The second mistake is you should not use await when there is no async in your function definition. Here is the thing, async ensures that the function returns a promise, and wraps non-promises in it. The keyword await makes JavaScript wait until that promise settles and returns its result. await works only inside async functions. So you can avoid using these completely or you need to format it accordingly.

The third mistake is, you are trying to do return true; from the for loop of the if condition which is not allowed basically because it is not wrapped inside the function.

The fourth mistake is, you are not calling the window.onload function - as the result, it is always returns false even though the page is loaded.

The fifth thing is, I don't know what incomplete resolve is doing in window.sleep function.

The sixth thing is, you are returning return false; at the end without any reference which is completely meaningless.

I have modified the code and avoided the above mistakes, please look into it.

Below is the modified JavaScript code:

var status = false;
window.sleep = function() { 
    return setTimeout(() => {
        console.log("=> Waited for 2 seconds...");
    }, 2000);
}
var getStatus = function() {
    for(var i = 0; i < 30; i++) {
        if(window.onload = function() {
            return true;
            }) {
            status = true;
            console.log(i+"). Loaded ? "+status);
            break;
        } else {
            console.log(i+"). Loaded ? "+status);
            sleep();
        }
    }
    return status;
}
getStatus();

Try the below Java code which prints true after the page loads :

System.setProperty("webdriver.chrome.driver", "C:\\NotBackedUp\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://www.google.com");
JavascriptExecutor js = (JavascriptExecutor) driver;
Boolean result = (Boolean) js.executeScript("var status = false;\r\n" + 
        "window.sleep = function() { \r\n" + 
        "   return setTimeout(() => {\r\n" + 
        "       console.log(\"=> Waited for 2 seconds...\");\r\n" + 
        "   }, 2000);\r\n" + 
        "}\r\n" + 
        "var getStatus = function() {\r\n" + 
        "   for(var i = 0; i < 30; i++) {\r\n" + 
        "       if(window.onload = function() {\r\n" + 
        "           return true;\r\n" + 
        "           }) {\r\n" + 
        "           status = true;\r\n" + 
        "           console.log(i+\"). Loaded ? \"+status);\r\n" + 
        "           break;\r\n" + 
        "       } else {\r\n" + 
        "           console.log(i+\"). Loaded ? \"+status);\r\n" + 
        "           sleep();\r\n" + 
        "       }\r\n" + 
        "   }\r\n" + 
        "   return status;\r\n" + 
        "}\r\n" + 
        "return getStatus();");
System.out.println(result);

I hope it helps...

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the help with the typo. That wasn't it though. I think your logic is a little different than what I was going for. I simplified my post to be easier to read. It was kind of a mess. Are you saying I need to call executeAsyncScript()? I'll have to give that a go in the morning. Unless you're talking about the sleep() method. In that case sleep() would be asynchronous because of the promise in the function so you would use await sleep().
I think you are getting SyntaxError: await is only valid in async function error not the one that you have mentioned above, can you check once again?
I'm not saying that you need to call executeAsyncScript() but you need to include async for the promise function corresponding to await
Can you share the stack trace if possible so that it will be easy to trace the cause

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.