I'm using the following code to capture JavaScript errors when running Selenium tests:
public static void AssertNoJavaScriptErrorsInLog(this RemoteWebDriver driver)
{
var errorStrings = new List<string> { "SyntaxError", "EvalError", "ReferenceError", "RangeError", "TypeError", "URIError" };
var jsErrors = driver.Manage().Logs.GetLog(LogType.Browser).Where(x => errorStrings.Any(e => x.Message.Contains(e))).ToList();
if (jsErrors.Any())
{
Assert.Fail("JavaScript error(s):" + Environment.NewLine + jsErrors.Aggregate("", (s, entry) => s + entry.Message + Environment.NewLine));
}
}
One of my tests intermittently reports an error:
Assert.Fail failed. JavaScript error(s):
TypeError: doc.documentElement is null
TypeError: doc.documentElement is null
Trying to locate the error I look in the console of the FireFox browser which just ran the failed tests, but it's empty!
Why can't I see the JavaScript error in the browser console?
You might be experiencing the following fresh selenium issue:
Some new browser logs are not captured
As a workaround, consider downgrading selenium to 2.52.
Also, from time to time there are compatibility issues between selenium and firefox with a wide range of symptoms - play around with firefox versions (you can download older versions here) and see if you still cannot catch the js error on the console.
Related
I remember getting this error a lot a while before. Today I wanted to show it to a friend unfamiliar with Javascript. Chrome and Safari instead gave me something like:
> const o = {};
< undefined
> o.doge()
< TypeError: o.doge is not a function (In 'o.doge()',' 'o.doge' is undefined)
Chrome and Firefox seem to be user-friendly as well.
How can I get an original error, without this helpful message?
You will never get that error in a modern browser; the error comes from js engine itself not the browser; and if there are no others other than that Type Error, modern engines will return a more developer friendly error by applying a (similar) /(w+)/ regex on what ever typed before () and placing it in the error message check out:
v8 (chrome) message templates that will make the error string (line 51, 52):
T(CalledNonCallable, "% is not a function")
and SpiderMoneky (mozilla) message templates (at line 51, 54):
MSG_DEF(JSMSG_NOT_FUNCTION, 1, JSEXN_TYPEERR, "{0} is not a function")
non-callable test case in v8 and a SpiderMokney test case .
So the only way to a undefined is not a function error message in a modern browser is doing undefined() :)
undefined()
you can just try to find and download an older version of the browser which logged the original error. (if that version is still publicly available).
Chrome outputs "Script error." and Firefox outputs "ReferenceError: d is not defined"
Run the following code in both browser's console and notice the difference.
Why is Chrome's message not as descriptive as Firefox's? How can one get a full error message out of chrome?
The code is wrapped in setTimeouts so that they can be ran in the same context for console running and output. The issue also occurs when ran as a script.
// custom global error handler
setTimeout(() => {
window.onerror = function(message) {
console.log("Error message: ", message)
return false
}
})
// create an error
setTimeout(() => {
d;
})
For anyone else that runs into this issue. It is known that webpack can interfere with window.onerror in chrome because of the webpack url scheme. In this case using chrome 69.03 and Webpack 3.12.0.
I could not find a workaround for these versions, but proper errors are reported from onerror when running the app from the build instead of in dev mode.
So I'm trying to run javascript code on website through my WebBrowser in console application but I came across weird bug. This is my code:
object[] mathArgs = { "javascript:setTimeout('__doPostBack(\'someID\',\'\')', 0)" };
mainWebBrowser.Document.InvokeScript("eval", mathArgs);
and after this I receive:
"There was an error in the script on this page:
Line: 1
Char: 1
Expected char ')'
Code: 0"
Funny thing is it works well in WinForms project, there is problem in console app. Am I missing something? Additionally, it's code that works on page I work on.
If your code work without any problem use the "ScriptErrorsSuppressed" property to ignore JS errors :
WebBrowser mainWebBrowser = new WebBrowser {ScriptErrorsSuppressed = true};
// Navigation code gose here
object[] mathArgs = { "javascript:setTimeout('__doPostBack(\'someID\',\'\')', 0)" };
mainWebBrowser?.Document?.InvokeScript("eval", mathArgs);
I get this error in Chrome immediately after reading a JSON file. It works correctly in Safari and Firefox.
console.log ("event -> "+ postcards.nodes[0].node.event); // "tally" in Safari "TypeError: Cannot read property 'node' of undefined" in Chrome.<
Is there a limit to the levels in a nested JSON file? I generate the JSON from a Drupal view. Here here is the start:
{"nodes":[{"node":{"w1":"","w2":"1","w3":"","w4":"", ...<
Here is the Javascript:
d3.json(
"/sites/default/d3_files/json/toronto-wards.json",
function(error,wards) {
d3.json("/postcards-json", function(error, postcards) {
console.log ("event -> "+ postcards.nodes[0].node.event); // tally in Safari
I'm using macOS and my friends using Windows get the same error in Firefox.
As per request here is what I think is the XHR message:
d3.min.js:1 XHR finished loading: GET "http://www.stopplastics.ca/postcards-json".
Does the following work for you?
Promise.all(
d3.json("/sites/default/d3_files/json/toronto-wards.json"),
d3.json("/postcards-json")
)
.then(
function([wards,postcards]) {
console.log ("event -> "+ postcards.nodes[0].node.event); // tally in Safari
Some browsers may not support deconstructing arrays so probably better to try the following for older browsers (non Chrome and Firefox):
Promise.all(
d3.json("/sites/default/d3_files/json/toronto-wards.json"),
d3.json("/postcards-json")
)
.then(
function(results) {
var wards=results[0],postcards=results[1];
console.log ("event -> "+ postcards.nodes[0].node.event);
}
);
According to the comments your drupal end point providing the JSON needs authentication so gives you empty data when you're not loged in.
Error has maybe nothing to do with the browser used but depends if you're loged in or not.
The problem was caused by the Drupal view not being created correctly. Nothing to do with the Chrome browser.
I am trying to write an automated test program for one of my website using Selenium WEbDriver. I am having some problems when doing the test on Internet Explorer. The website that I am trying to test is built in AngularJS. I will explain my problems in detail.
Here, is the code that waits until Angular has finished processing.
private static ExpectedCondition angularHasFinishedProcessing() {
return (ExpectedCondition<Boolean>) driver -> {
String hasAngularFinishedScript = "var callback = arguments[arguments.length - 1];\n" +
"var el = document.querySelector('html');\n" +
"if (!window.angular) {\n" +
" callback('false')\n" +
"}\n" +
"if (angular.getTestability) {\n" +
" angular.getTestability(el).whenStable(function(){callback('true')});\n" +
"} else {\n" +
" if (!angular.element(el).injector()) {\n" +
" callback('false')\n" +
" }\n" +
" var browser = angular.element(el).injector().get('$browser');\n" +
" browser.notifyWhenNoOutstandingRequests(function(){callback('true')});\n" +
"}";
JavascriptExecutor javascriptExecutor = (JavascriptExecutor) driver;
assert javascriptExecutor != null;
String isProcessingFinished = javascriptExecutor.executeAsyncScript(hasAngularFinishedScript).toString();
return Boolean.valueOf(isProcessingFinished);
};
}
private void waitForAngular() {
WebDriverWait wait = new WebDriverWait(driver, 15, 100);
wait.until(angularHasFinishedProcessing());
}
And here is the code that instantiates WebDriver for Internet Explorer.
System.setProperty("webdriver.ie.driver",
new File("H:/libraries/webdrivers/IEDriverServer.exe").getAbsolutePath());
DesiredCapabilities d = DesiredCapabilities.internetExplorer();
// To bypasse the Protected Mode settings of IE
d.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
driver = new InternetExplorerDriver(d);
driver.manage().timeouts().setScriptTimeout(30, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.get("https://arandomangularjsapp.com"); // Let's suppose this
I had to bypass the Protected Mode settings (shown in above code) because I was constantly getting this Exception
Caused by: org.openqa.selenium.WebDriverException: Unexpected error launching Internet
Explorer. Protected Mode must be set to the same value (enabled or disabled) for all
zones. (WARNING: The server did not provide any stacktrace information)
though I made sure that protected mode was enabled and same values were set for all zones.
Now comes the real issue I am having. Look at this block of code,
waitForAngular();
WebElement el = driver.findElement(By.xpath("//div[#class='events-list__event-info' and #id='48040']" +
"//following-sibling::div[#class='events-list__event-buy']/a"));
if(driver.toString().toUpperCase().contains("INTERNETEXPLORER"))
el.sendKeys(Keys.ENTER);
else
el.click();
waitForAngular();
webElement = driver.findElement(By.xpath("(//div[#class='ticket u-cf ng-scope'])[1]//select"));
select = new Select(webElement);
select.selectByIndex(1);
My first question, the way I am trying to wait for Angular app to get ready by calling waitForAngular(), is it a good way? In my program I even had to use Thread.sleep() so many times in order to let elements to properly render before I could invoke actions on them. It would be great if you guys can suggest me a proper way to use Selenium WebDriver along with Angular App.
Now let's talk about my second issue. I had to completely disable Protected Mode from Internet Explorer's options in order to run the program. Otherwise, I would get this exception,
Caused by: org.openqa.selenium.JavascriptException: JavaScript error in async script. (WARNING: The server did not provide any stacktrace information)
I get this exception when trying to execute waitForAngular(). What could be causing this? Is there any way by which I could keep the Protected Mode enabled and still be able to execute that script inside angularHasFinishedProcessing() method?
Finally, my third problem is related to click action not being triggered. Forget about the previous issues for a second. I disabled IE's Protected Mode, so my program starts IE without throwing any exception. The program successfully finds the first element as shown in the code above. But, the click action is not triggered, browser thus doesn't navigate to next page, and the program fails to find the second element. As a workaround I even tried el.sendKeys(Keys.ENTER); but it didn't work.** So, am I having this problem because I bypassed/disabled Protected Mode? Or, is there something else that I am not being able to see?**
I run tests on IE, Opera, Chrome and Firefox and the problem seems to occur only in IE. Any sort of help, suggestions or guidelines are highly appreciated.
Thank You.