Sharing: a way to detect JavaScript error through Selenium WebDriver.

5,106 views
Skip to first unread message

Chris.Chen

unread,
Feb 23, 2012, 12:01:41 AM2/23/12
to Selenium Users
In order to detect javascript error, following are the key challenges:
1. How to inject the javascript error detector logic into the page?
2. How to make sure the detector is attached to window.onerror, before
any other script getting executed?
3. How to make this detector working for different browsers?
4. How to collect these javascript error through Selenium?

Here is what we did in our testing environment:
- We instruct the browser go though a proxy to access the test target
site.
- The proxy was built to intercept any response with "content-type:
text/html", and add a <script/> block right after the <head> element.
- The added <script /> block contains the logic to attach a handler to
window.onerror.
- The error handler will log any error encountered as a DOM element in
the page gets tested, e.g., <jserror id="jserror0" url="http://
qa.englishtown.com/online/what-you-learn.aspx"
timestamp="1329973086343" error="'jQuery' is undefined" line="286"/>

Then it only left for the Selenium webdriver to find any element
called <jserror/> in the DOM to detemine if the page gets javascript
errors.

This way works for IE, FF, Chome, Safari, and the proxy we setup is
"fiddler" which allows us to intercept response very easy through its
fildder script.

Wish this is helpful.

Brian Kitchener

unread,
Feb 23, 2012, 10:50:31 AM2/23/12
to Selenium Users
I posted an alternate way to do this here:
http://mrselenium.blogspot.com/2012/02/getting-console-errors-from-browser.html
This injects variables in the page so you don't need to use a proxy,
just check the variables.

Chris.Chen

unread,
Feb 23, 2012, 7:59:38 PM2/23/12
to Selenium Users
hey, thanks for sharing.

Just read your article:
"First we override the Console object with some custom functionality
every time the page loads. We injected this into our Page Object base
class, that all pages inherit from. This causes it to be called every
time the page changes. After we perform some actions on the page we
check our object to see if any console messages have been seen. "

Would you mind share more info on how your page object look like? and
how the Console object gets overridden?

BTW, are you using Selenium 2 and Web Driver?

On Feb 23, 11:50 pm, Brian Kitchener <kitchener.br...@gmail.com>
wrote:
> I posted an alternate way to do this here:http://mrselenium.blogspot.com/2012/02/getting-console-errors-from-br...

Prasad Chintha

unread,
Feb 23, 2012, 8:13:33 PM2/23/12
to seleniu...@googlegroups.com
Hi Chris

Thanks For the Quick reply, Here I am attaching screen shots with more
information, hope this helps in understanding the problem clearly .

> --
> You received this message because you are subscribed to the Google Groups "Selenium Users" group.
> To post to this group, send email to seleniu...@googlegroups.com.
> To unsubscribe from this group, send email to selenium-user...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/selenium-users?hl=en.
>

--
Thanks & Regards

Prasad Chinta

Selnium.docx

Jim Evans

unread,
Feb 24, 2012, 10:03:44 AM2/24/12
to Selenium Users
Brian, thanks for sharing this method, but what happens if JavaScript
in your onload event has a JavaScript error, and it fires before your
custom code is injected into the page?

--Jim

On Feb 23, 10:50 am, Brian Kitchener <kitchener.br...@gmail.com>
wrote:
> I posted an alternate way to do this here:http://mrselenium.blogspot.com/2012/02/getting-console-errors-from-br...

Brian Kitchener

unread,
Mar 1, 2012, 10:20:40 AM3/1/12
to Selenium Users
This is C#: I am using Selenium1 but it works for both with slight
modifications
My PageObjects look like this. They all inherit from a base class.
Our constructor inherits the Base Class's constructor. We do this so
the base constructor has the selenium instance and can perform actions
on each page object, such as injecting the javascript.
public class LoginPage : PageObjectBaseCLass
{
public LoginPage(ISelenium selenium) : base(selenium)
{}
}

There is a window.console JS variable in most browsers. Look in the
function below, we set the console variable like this: win.console =
{logs: win.console.....

This function is executed using GetEval in our base page object
constructor so it will happen every time the page changes state. Not
a perfect solution but it works most of the time:

string function = "var win =
this.browserbot.getUserWindow();win.errors = win.errors ||
[];win.errorsJson = win.errorsJson || \"\";win.originalonerror =
win.originalonerror || win.onerror ||\"none\";win.onerror =
function(errorMsg, url, lineNumber) { win.errors.push({\"errorMsg\":
errorMsg || \"\",\"url\": url || \"\",\"lineNumber\": lineNumber ||
\"\"});if (JSON &&JSON.stringify) win.errorsJson =
JSON.stringify(win.errors); if (win.originalonerror != \"none\")
win.originalonerror(errorMsg, url, lineNumber);};win.console = {logs:
win.console.logs || [],logsJson: win.console.logsJson || \"\",log:
function() {win.console.logs.push(arguments);if (JSON &&
JSON.stringify) win.console.logsJson =
JSON.stringify(win.console.logs);},warns: win.console.warns ||
[],warnsJson: win.console.warnsJson || \"\",warn: function()
{win.console.warns.push(arguments); if (JSON && JSON.stringify)
win.console.warnsJson = JSON.stringify(win.console.warns);},errors:
win.console.errors || [],errorsJson: win.console.errorsJson ||
\"\",error: function() { win.console.errors.push(arguments);if (JSON
&& JSON.stringify) win.console.errorsJson =
JSON.stringify(win.console.errors);}};";
selenium.GetEval(function);



On Feb 23, 5:59 pm, "Chris.Chen" <chrischao.c...@gmail.com> wrote:
> hey, thanks for sharing.
>
> Just read your article:
> "First we override theConsoleobject with some custom functionality
> every time the page loads.  We injected this into our Page Object base
> class, that all pages inherit from. This causes it to be called every
> time the page changes.  After we perform some actions on the page we
> check our object to see if anyconsolemessages have been seen. "
>
> Would you mind share more info on how your page object look like? and
> how theConsoleobject gets overridden?

Brian Kitchener

unread,
Mar 1, 2012, 10:22:38 AM3/1/12
to Selenium Users
In that case then we will not be able to catch the errors. As I said
its not a perfect solution, but it works most of the time. There is a
small window between when the pageLoad event happens and when my code
is injected that can prevent console errors from being seen.

fschwiet

unread,
Apr 29, 2012, 10:22:41 PM4/29/12
to Selenium Users
Brian thanks for sharing the code, I had been doing something
similar. If anyone is using Selenium 2.0 from .NET and they want to
monitor onerror, I've put this utility code on nuget. Its a small
piece of code to write, but its nice to have an implementation I can
reuse that has test coverage.
Anyhow, example usage is in the test:
https://github.com/fschwiet/SizSelCsZzz/blob/master/SizSelCsZzz.Test/Can_read_javascript_errors.cs
The implementation only covers onerror, not console.log/warn/error,
see: https://github.com/fschwiet/SizSelCsZzz/blob/master/SizSelCsZzz/WebDriverExceptionMonitor.cs
SizSelCsZzz can be installed via nuget, from: http://nuget.org/packages/SizSelCsZzz

Shaba K

unread,
Apr 30, 2012, 12:13:13 PM4/30/12
to seleniu...@googlegroups.com
Hi There,

I  havn't been able to catch any JS Errors with the function.
Is there more to it,that i need to do at my end.

It would help if you direct pls.

-Shabana

Raju

unread,
Apr 30, 2012, 1:24:04 PM4/30/12
to Selenium Users
Hi

I tried the code, but i am getting selenium errors here is the high
level code.

private WebDriver driver;
private Selenium selenium;

driver = new FirefoxDriver();
baseUrl = "https://xxxxxxxxxxxxxxxx/";
selenium = new WebDriverBackedSelenium(driver, baseUrl);

.... Here I have some log in to the application code. ( Ignore this )

String function = "var win =
this.browserbot.getUserWindow();win.errors = win.errors ||
[];win.errorsJson = win.errorsJson || \"\";win.originalonerror =
win.originalonerror || win.onerror ||\"none\";win.onerror =
function(errorMsg, url, lineNumber) { win.errors.push({\"errorMsg\":
errorMsg || \"\",\"url\": url || \"\",\"lineNumber\": lineNumber ||
\"\"});if (JSON &&JSON.stringify) win.errorsJson =
JSON.stringify(win.errors); if (win.originalonerror != \"none\")
win.originalonerror(errorMsg, url, lineNumber);};win.console = {logs:
win.console.logs || [],logsJson: win.console.logsJson || \"\",log:
function() {win.console.logs.push(arguments);if (JSON &&
JSON.stringify) win.console.logsJson =
JSON.stringify(win.console.logs);},warns: win.console.warns ||
[],warnsJson: win.console.warnsJson || \"\",warn: function()
{win.console.warns.push(arguments); if (JSON && JSON.stringify)
win.console.warnsJson = JSON.stringify(win.console.warns);},errors:
win.console.errors || [],errorsJson: win.console.errorsJson ||
\"\",error: function() { win.console.errors.push(arguments);if (JSON
&& JSON.stringify) win.console.errorsJson =
JSON.stringify(win.console.errors);}};";

selenium.getEval(function); <----------
Coding failing here. (Below i have attached the failure trace for the
same )

String errorFunction =
"this.browserbot.getUserWindow().console.errorsJson";
String warningsFunction =
"this.browserbot.getUserWindow().console.warnsJson";
String exceptionFunction =
"this.browserbot.getUserWindow().errorsJson";
String logFunction =
"this.browserbot.getUserWindow().console.logsJson";
String errors = selenium.getEval(errorFunction);
String warnings = selenium.getEval(warningsFunction);
String exception = selenium.getEval(exceptionFunction);
String logs = selenium.getEval(logFunction);

System.out.println("+++++++++++++++++++++++++++++++++++++++++");
System.out.println("ERRORS :" +errors);
System.out.println("WARNS :" +warnings);
System.out.println("EXCEP :" +exception);
System.out.println("LOG :" +logs);


Failure Trace -
com.thoughtworks.selenium.SeleniumException: null (WARNING: The server
did not provide any stacktrace information)
Command duration or timeout: 1.12 seconds
Build info: version: '2.20.0', revision: '16008', time: '2012-02-27
19:03:04'
System info: os.name: 'Windows 7', os.arch: 'x86', os.version: '6.1',
java.version: '1.6.0_20'
Driver info: driver.version: RemoteWebDriver
at
org.openqa.selenium.internal.seleniumemulation.SeleneseCommand.apply(SeleneseCommand.java:
42)
at
org.openqa.selenium.internal.seleniumemulation.Timer.run(Timer.java:
39)
at
org.openqa.selenium.WebDriverCommandProcessor.execute(WebDriverCommandProcessor.java:
145)
at
org.openqa.selenium.WebDriverCommandProcessor.getString(WebDriverCommandProcessor.java:
116)
at
com.thoughtworks.selenium.DefaultSelenium.getEval(DefaultSelenium.java:
479)
at
SampleTestsForDemo.EcampusTest1.VerifyLogOutLinkPresence(EcampusTest1.java:
57)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod
$1.runReflectiveCall(FrameworkMethod.java:45)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:
15)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:
42)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:
20)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:
28)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:
30)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:
68)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:
47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:
50)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:
38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:
467)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:
683)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:
390)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:
197)
Caused by: org.openqa.selenium.WebDriverException: null (WARNING: The
server did not provide any stacktrace information)
Command duration or timeout: 1.12 seconds
Build info: version: '2.20.0', revision: '16008', time: '2012-02-27
19:03:04'
System info: os.name: 'Windows 7', os.arch: 'x86', os.version: '6.1',
java.version: '1.6.0_20'
Driver info: driver.version: RemoteWebDriver
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
Method)
at
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:
39)
at
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:
27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at
org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:
170)
at
org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:
123)
at
org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:
438)
at
org.openqa.selenium.remote.RemoteWebDriver.executeScript(RemoteWebDriver.java:
353)
at
org.openqa.selenium.internal.seleniumemulation.GetEval.handleSeleneseCommand(GetEval.java:
40)
at
org.openqa.selenium.internal.seleniumemulation.GetEval.handleSeleneseCommand(GetEval.java:
1)
at
org.openqa.selenium.internal.seleniumemulation.SeleneseCommand.apply(SeleneseCommand.java:
33)
... 30 more


Could you please suggest what might be the issue.

Thanks
Raju


On Apr 30, 9:13 am, Shaba K <shabazi...@gmail.com> wrote:
> Hi There,
>
> I  havn't been able to catch any JS Errors with the function.
> Is there more to it,that i need to do at my end.
>
> It would help if you direct pls.
>
> -Shabana
>
>
>
>
>
>
>
> On Mon, Apr 30, 2012 at 3:22 AM, fschwiet <fschw...@gmail.com> wrote:
> >  Brian thanks for sharing the code, I had been doing something
> > similar.  If anyone is using Selenium 2.0 from .NET and they want to
> > monitor onerror, I've put this utility code on nuget.  Its a small
> > piece of code to write, but its nice to have an implementation I can
> > reuse that has test coverage.
> >  Anyhow, example usage is in the test:
>
> >https://github.com/fschwiet/SizSelCsZzz/blob/master/SizSelCsZzz.Test/...
> >  The implementation only covers onerror, not console.log/warn/error,
> > see:
> >https://github.com/fschwiet/SizSelCsZzz/blob/master/SizSelCsZzz/WebDr...

ANUPAM BHATTACHARJEE

unread,
Jul 2, 2015, 3:07:00 AM7/2/15
to seleniu...@googlegroups.com
Hi Chris,

Can you please post your code, along with the setup you did in fiddler ? Thanks in advance.
Reply all
Reply to author
Forward
0 new messages