This repository has been archived by the owner. It is now read-only.

API for checking for JavaScript errors on the page #148

Open
lukeis opened this Issue Mar 2, 2016 · 50 comments

Comments

Projects
None yet
1 participant
@lukeis
Member

lukeis commented Mar 2, 2016

Originally reported on Google Code with ID 148

Sometimes a test passes but a browser reports an error on the page.
From a developer's perspective the code is broken because the error
shouldn't have appeared. 

I would like to be able to check if the browser indicates that an error
occured when processing JavaScript.

Reported by adam.dziendziel on 2009-02-07 13:10:18

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Can you please provide more information with a simple example? Thanks!

Reported by dharani@google.com on 2011-01-20 23:24:35

  • Labels added: Type-Enhancement
  • Labels removed: Type-Defect
@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

It would be really useful to have a method to check if there were any javascript errors
when loading a page.  It would still be useful even if this was available in only one
of the supported browsers.

Reported by scytacki@concord.org on 2011-04-01 16:55:22

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

+1 for this feature. Would be nice to have a annotation like @FailOnJSError or somthing
like that. 

As a workaround, you can define a custom error handler (window.onerror) which pushes
the errors to a global array. In your tests, you can use the javascript execution functions
to check that array for errors.

Reported by christoph.neuroth on 2011-05-03 08:31:02

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

+1 for this. Of course it is possible to execute window.onerror but in any case have
this feature build-in Webdriver API will be great.

Reported by slava.markovski on 2011-07-06 22:04:48

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

I also have same requirent as mentioned in this issue .As mentioned , I added 

((JavascriptExecutor)driver).executeScript("window.onerror=function(msg, url, linenumber){
   var logerror='Error message: ' + msg + '. Url: ' + url + 'Line Number: ' + linenumber
;   alert(logerror);  return true; }");

into my Selenium script , But I dont get any alert , instead app page hangs due to
JS error ! 

Can you please let me know if my approach is correct ? 

-Anjali

Reported by juhi08 on 2011-07-08 10:55:14

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

I used such simple workaround with Firefox 5.0 and Selenium 2.0rc3 and it worked just
fine:

    public static Object execJavaScript(String code) {
        JavascriptExecutor js = (JavascriptExecutor) driver;
        Object result =  js.executeScript(code);
        return result;
    };

In beforeClass:

execJavaScript("window.onerror=function(msg){window.err=msg};");

public void afterMethod(Method m){
    String method_name = m.getName();
    Object result = execJavaScript("var tmp = window.err;window.err=''; return tmp;");
    if (result != null) {
        String res = result.toString(); 
        if (res.length()>0)
            Assert.fail("JS Error in " + method_name + "(): " + res);
    }
};

Buf after upgrading to Firefox 6.0 and Selenium 2.4 it stopped working though it still
works with IE8. Now I cannot find any way to check for JS script errors and it makes
a lot of tests useless. It would be very nice if API could have methods to check JS
errors. Also if you know some workaround for Firefox 6.0 please let me know. 

Thank you. Andrey.


Reported by anikolaev@productengine.com on 2011-08-30 14:59:57

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Injecting window.onerror is not the solution: it allows to capture some errors but not
all (it is difficult to inject it in each window and it can't be done early enough).

I've written a small Firefox extension that registers the JavaScript errors and make
them available in each window what allows to easily retrieve them from WebDriver. It's
open source and available at [1]. I've blogged about it too [2].

@WebDriver Members
are you interested in adding such a feature to WebDriver? I'm open to contribute what
I've done so far and I think that it wouldn't be difficult to add the same support
for HtmlUnit and Chrome. No idea what concerns the other browsers. If yes, it would
be interesting to start a discussion concerning the needed API.

[1] https://github.com/mguillem/JSErrorCollector
[2] http://mguillem.wordpress.com/2011/10/11/webdriver-capture-js-errors-while-running-tests/

Reported by mguillemot@yahoo.fr on 2011-10-11 09:17:34

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Marc: Can you send an email to selenium-developers with your proposed API, what capabilities
it adds, what it requires from the browser, and its limitations? That would be a good
forum to have this discussion :)

Reported by dawagner on 2011-10-11 10:45:03

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

@Daniel: done but my post is probably waiting for moderator's approval

Reported by mguillemot@yahoo.fr on 2011-10-12 07:26:16

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Reported by barancev on 2011-10-12 18:06:56

  • Labels added: Component-WebDriver
@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Hi, 
any updates?
any news regarding API ?

Thanks,
Tim

Reported by TSuhachev on 2012-01-31 09:58:29

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Hi,

Read this post: http://mguillem.wordpress.com/2011/10/11/webdriver-capture-js-errors-while-running-tests/

Reported by marimuthugceb on 2012-02-02 11:05:33

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Hey,
yes, I read it before ... 
though none of two options fits :( 
I cannot add custom code to the page header, and when it comes to extension , as I
understood, I have to use JSCollector which is written in Java
I use C# , so don't really want to port it to C#

so wondering if that was integrated somehow to webdriver and it seems that it didn't
what I actually expect to have is some array, that would contain js errors collection
with some pure error details as value
I consider such an array to be reinitialized on each significant event like: navigate
to, click, Action event members, custom js execution etc

however, if someone knows the way to read firebug's (or any other ext) js log I would
appreciate to have an explanation

Reported by sti@ciklum.com on 2012-02-02 13:49:30

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

The JSCollector is a Firefox extension and is therefore not written in Java. It can
be used with WebDriver from any language. You only need to configure it in the Firefox
profile when starting Firefox and to perform a JS call each time you want to check
for JS errors.

Here is an example how it is used in Cucumber+Capybara+Webdriver tests
https://gist.github.com/1371962

Reported by mguillemot@yahoo.fr on 2012-02-03 07:53:39

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

thanks for link, however , it supposes that I have got an extension

but how can encounter it?
as I understand I should have deployed maven to build the project from JSErrorCollector
repository to get it, shouldn't I ?

Reported by TSuhachev on 2012-02-06 07:25:32

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

The XPI file was available in the jar file but I agree that it was not easy to get it.
I've now made it directly available:
https://github.com/mguillem/JSErrorCollector/raw/master/dist/JSErrorCollector.xpi

Reported by mguillemot@yahoo.fr on 2012-02-09 07:51:50

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

thanks! trying it out

Reported by TSuhachev on 2012-02-09 08:43:55

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

As much as people would like to have a global API for this, I believe it to be impossible
to craft a solution that will work with all browsers. As far as I know, it's impossible
to create such a solution that will work in IE.

Reported by james.h.evans.jr on 2012-02-09 15:51:15

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Thank you very much for your hard work, the tool is a masterpiece. 
Have you ever encountered an error like this when trying to extract the data from FF
to Webdriver ?
Permission denied to access property 'toString' [:0]

Reported by vladislavkasirski on 2012-02-09 16:48:21

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Never seen that. This being said, this issue is probably not the best place to discuss
problems JSErrorCollector.

Reported by mguillemot@yahoo.fr on 2012-02-10 09:55:05

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

I hesitated to post it here, but it's related.
I get it when my program gets to 
"List jsErrors = JavaScriptError.readErrors(driver);"
Instead of a list of errors I get a list of lines that contain:
"Permission denied to access property 'toString' [:0]"

Reported by vladislavkasirski on 2012-02-10 11:15:08

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Is it possible that these are the errors that you really have and that you would see
in Firefox's JavaScript Console as well?

Reported by mguillemot@yahoo.fr on 2012-02-10 11:32:09

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

I get this error when navigating to a page which asks for a "pageIsLoad" variable to
be true before allowing interaction with some active elements.

Reported by vladislavkasirski on 2012-02-10 12:01:04

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Firefox's JavaScript Console does not show any errors on this page.

Reported by vladislavkasirski on 2012-02-10 12:43:19

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

I have a very simple use case, I want to be able to get proper feedback whenever a script
gets executed in following way:

public static Object execJavaScript(String code) {
        JavascriptExecutor js = (JavascriptExecutor) driver;
        Object result =  js.executeScript(code);
        return result;
    };

When my code is: "asasdada();", I would expect a JS error message, that function is
not defined. Instead, selenium tells me, a JS error occurred on server. No further
details. In firebug I would see the desired message.

I tried the approach with window.onerror, and the approach with JSErrorCollector. Both
methods do however not catch the error reason. I stay blind.
How can I retrieve the reason of this error properly?

I am using selenium 2.24.1, and firefox 13.0.1.

Regards, Jan Kester.

Reported by jan.c.kester on 2012-07-20 09:09:50

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

The purpose of my JSErrorCollector was to capture JS errors in the page. I can imagine
that WebDriver executes scripts in a kind of sandbox and therefore that errors occuring
here will be catched by WebDriver and won't be detected by JSErrorCollector or window.onerror.

Reported by mguillemot@yahoo.fr on 2012-07-20 09:28:49

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

probably you can wrap the failing code with try/catch and return the error message at
the catch block , yet never tried it :) 

Reported by TSuhachev on 2012-07-20 09:30:20

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Try/catch will not help. I already get the exception, but it does not contain the root
JS exception.

So the question is then how the WebDriver Sandbox can throw on the root exceptions
to the client. I would also be happy already when I could get a log from the WebDriver
sandbox that gives me the root exception. But so far I failed getting proper webdriver
logs (http://code.google.com/p/selenium/issues/detail?id=4286).

Regards, Jan Kester.

Reported by jan.c.kester on 2012-07-20 12:23:27

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

@Jan:
I don't understand your last comment. If you can use a try/catch, then what about returning
the information from the exception, that is interesting for you?

Reported by mguillemot@yahoo.fr on 2012-07-20 12:32:20

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

I am not seeing the reason for the JS failure.

I try following code:
import org.openqa.selenium.JavascriptExecutor;

try {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript('asdd()');
}
catch (Exception e) {
    println "Exception from webdriver=\n\n$e"
    def errorlist = net.jsourcerer.webdriver.jserrorcollector.JavaScriptError.readErrors(driver);
    println "\n\nSize of errors in error collector= ${errorlist.size()}"
}

The output I get here is:
Exception from webdriver=

org.openqa.selenium.WebDriverException: null (WARNING: The server did not provide any
stacktrace information)
Command duration or timeout: 11 milliseconds
Build info: version: '2.24.1', revision: '17205', time: '2012-06-19 15:28:49'
System info: os.name: 'Windows 7', os.arch: 'x86', os.version: '6.1', java.version:
'1.6.0_25'
Driver info: driver.version: RemoteWebDriver
Session ID: 97b76d12-8c9b-42ef-be23-5d1d661f74a8


Size of errors in error collector= 0




When I run the same statement in firebug, I get an error:
ReferenceError: asdd is not defined

Do you know a way how I can see this error message with selenium?

Regards, Jan.

Reported by jan.c.kester on 2012-07-20 13:19:50

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

what about following: 

String result = (String) js.executeScript("try { asdd(); return 'ok'; } catch (e) {
return 'failed: ' + e.message; }")

Reported by mguillemot@yahoo.fr on 2012-07-20 14:20:06

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Yes, this is a very nice idea. Thanks!

I changed it slightly, into following:
    public void executeJSWithErrorHandling(String statement) {
        JavascriptExecutor js = (JavascriptExecutor) driver;
        def wrapScript = "try { $statement } catch(e) {  \$('body').attr('JSError',e.message);
throw e; }"
        logger.debug("Executing script: $wrapScript")
        js.executeScript(wrapScript);
    }

So this is a combination of your suggestion and windows.onerror. I am also registering
the error in body element, and then throw on the error. That has the advantage that
the logic of error handling in your framework does not change.

Once the error occurs, it will through my usual empty exception, but afterwards I can
read the value of body@JSError. I think this solution will also work for returning
statements.

Regards, Jan Kester.

Reported by jan.c.kester on 2012-07-23 14:30:08

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

I have some questions on comment #32,

That looks like Java code, or is that C#? In either case, what's the "def" by wrapScript
mean? What data type is that? Isn't it normally "String" for Java or "string" for C#?

And for registering error into body element, I'm assuming there's a supposed way to
do it with pure javascript DOM rather than jQuery? In case jQuery isn't available,
so it'll work on any site, any browser. Perhaps something like:

document.getElementsByTagName("BODY")[0].setAttribute("JSError",e.message);

Reported by mangaroo on 2012-07-24 05:20:39

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

About "def": that is groovy. I am using groovy inside my JVM, as I can create new statements
(driver.findElement) at runtime, so no need to restart my JVM if my test script has
an error inside. Instead of def you can write String as well. The $ inside the "" is
evaluated in groovy. For java you would have to write:
String wrapScript = "try { " + statement + "} catch(e) {  $('body').attr('JSError',e.message);
throw e; }"

Your version with document instead of jQuery is more robust: no dependency on jQuery.
This is almost something that could be added to Selenium API. Very useful to get the
error registered.

An improved version could even add the latest JSError as a child element, instead of
overwriting an attribute. In that way you could collect all your JS Errors inside your
dom, instead of only having the latest.

Regards, Jan.

Reported by jan.c.kester on 2012-07-24 08:22:14

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Hi All,
Anyone found the solution for checking JS Error with Chrome and IE. I need to use IE
and Chrome, not FF.

Thanks.
Vikas

Reported by vikasthange on 2013-06-20 12:15:58

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Hi , Is there any progress on this issues for capturing JS ERROR within Chrome and IE??

Thx,
Jane

Reported by Tyingrong on 2013-07-09 13:07:55

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Hello. Agree with previous question. Is there any progress?

Thanks.
Oleg.

Reported by Richomail on 2013-07-10 14:55:01

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Hi, any generic solution to capture JS Error for all browsers?

Reported by sonam.agarwal@iiitb.net on 2013-08-23 11:21:17

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Now we have the same plug-in for Google Chrome. It’s here – https://github.com/dharrya/ChromeJSErrorCollector

It is very similar to JSErrorCollector.

Reported by Richomail on 2013-08-23 11:28:50

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

On comment #38, I believe the blog posts mentioned in this thread work across browsers,
the only problem is they won't catch page load errors since the error capturing is
injected after page load. So the page load case is what requires the browser extensions
to work.

On comment #39, would be interesting to see if the Chrome plugin will work for Opera
15+, which now uses Chrome engine, for use in tandem with OperaDriver.

Reported by mangaroo on 2013-08-23 22:09:28

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Fail to catch jQuery error in firefox using the approach with window.onerror, and the
approach with JSErrorCollector. see the detail. 
https://groups.google.com/forum/#!topic/webdriver/LCPdubYO4pg/discussion

Reported by jwxiao on 2013-08-27 16:03:23

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

If your page works fine without WebDriver and fails with it, then the root cause of
the problem is in WebDriver and trying to catch JS errors in the page won't help. Perhaps
do you simply use a too old version of Firefox?

Reported by mguillemot@yahoo.fr on 2013-08-28 06:03:03

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Thanks a lot for helping around. Most of the errors I expect will be on load event and
hence wanted the browsers extension.  

Reported by sonam.agarwal@iiitb.net on 2013-08-28 09:46:29

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Both Firefox 17.0.6 on Linux and Firefox 23.0.1 on Windows were tried. Still cannot
catch jQuery error. I tried to set preference not to use native event for firefox driver.
No help. 

Reported by jwxiao on 2013-08-28 15:21:03

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

I use the system property `webdriver.log.file` in java code to dump javascript console
errors into a file like this:

java -jar selenium-server-standalone-2.41.0.jar -Dwebdriver.log.file=/tmp/firefox-js-console.log

see https://code.google.com/p/selenium/wiki/FirefoxDriver

Reported by davidzhu.4.2 on 2014-04-12 20:38:44

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

I've tried this and you seem to be able to do this for Firefox and Chrome using LoggingPreferences
and DesiredCapabilities for the 'BROWSER' LogType.

The following Java code then retrieves the logs:
Logs logs = driver.manage().logs();
LogEntries logEntries = logs.get(LogType.BROWSER);

See this SO answer for full example code:
http://stackoverflow.com/a/23513245/184325

This can then be used to assert in the test:
assertEquals("There should be no JS errors in the console log", 0, logEntries.getAll().size());

This also seems to work using a RemoteWebDriver too.

Note that logs() method and LogEntries are marked as @Beta in the javadocs: http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/WebDriver.Options.html#logs()
http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/logging/LogEntries.html

I've not found much information about the checking in this way even though it seems
to solve the problem of checking the console log for JS errors on the page that many
people seem to require. Maybe this is fairly new in the api?

Here's a few bits I have found on it:
https://code.google.com/p/selenium/issues/detail?id=7318
http://stackoverflow.com/questions/18261338/get-chromes-console-log



Alternatively the WebDriver Wire Protocol is another option that seems to work in Firefox
and Chrome although isn't as easy to use in a test as the above method.
See https://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/log

Send a post request to the url in the documentation and include the following in the
body to get back a json object with the browser logs:
{
    type: browser
}

Reported by chris.reynolds@orchard-systems.co.uk on 2014-08-13 16:34:27

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

On #46, no option for IE and Safari at present I guess?

Reported by mangaroo on 2014-08-13 22:59:01

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

No IE doesn't seem to support this so the logs.get(LogType.BROWSER) call throws a WebDriverException.
I haven't tried Safari.

Reported by chris.reynolds@orchard-systems.co.uk on 2014-08-14 07:17:38

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Based on the above discussion, should I conclude that Java script functions cannot be
run on IE through Webdriver.
Because I also ran my script which involves javascript functions due to which the script
gets hanged on IE.
But when I run the same script on Firefox, It runs fine.
Please suggest.

Reported by tarun.cs55 on 2014-09-18 09:13:18

@lukeis

This comment has been minimized.

Member

lukeis commented Mar 2, 2016

Reported by luke.semerau on 2015-09-17 17:44:23

  • Labels added: Restrict-AddIssueComment-Commit

@SeleniumHQ SeleniumHQ locked and limited conversation to collaborators Mar 3, 2016

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.