Make JavaScript Errors available to test cases
Motivation:
It is currently not possible to know whether a web application under test:
- Caused JavaScript compilation errors
- Caused JavaScript runtime errors
- Caused the JavaScript on a page to call alert()
There is a check for alert() called when a Form submission has timed out, but this
is no longer sufficient. Many web apps out there are using JavaScript heavily and
the inability to retrieve such messages is making itself felt in TestPlan.
Note: Even Selenium does not give the ability to get JavaScript compilation / runtime
errors, so the problem is not specific to TestPlan itself
Proposal: Extend ResponseState with the following method, to be implemented for each
type of ResponseState (although Selenium is our current priority, and we're willing
to contribute the code for it).
-------
Selenium implementation Suggestion
-------
public interface ResponseState {
...
/**
* Consumes all the messages from the underlying implementation of
* this {@code ResponseState}, resetting messages as it does so.
* That is, calling consumeMessages() never returns the same logical
* message more than once. The caller is responsible for handling
* messages and reacting to them by failing the test case, logging
* the messages to a log file, etc...
*
* @see https:/
* which inspires the design of messages.
* @return Collection of {@code testplan.
* each containing more information about the severity and body
* of the message.
*/
public Collection<Message> consumeMessages();
/**
* Message wrapper interface
*/
public interface Message {
/**
* @return message attributes keyed by name
*/
Map<String,
/**
* @return text of the message
*/
String getText();
}
...
}
-------
public class BrowserState implements ResponseState {
...
@Override
public Collection<Message> consumeMessages() {
LinkedList<
if ( browser.
final String alert = browser.getAlert();
messages.add(new Message() {
@Override
public String getText() {
return alert;
}
@Override
public Map<String, Object> getAttributes() {
return Collections.
}
});
}
for ( final String scriptError : browser.
messages.add(new Message() {
@Override
public String getText() {
return scriptError;
}
@Override
public Map<String, Object> getAttributes() {
return Collections.
}
});
}
return messages;
}
...
}
-------
public final class AutoSelenium implements Selenium, ModeInstance {
...
Iterable<String> usrExtConsumeSc
final String scriptErrorString = this.commandPro
// TODO: get a JSON-Stringified string back and deserialize 1-n errors into a collection?
return Collections.
}
...
}
-------
Blueprint information
- Status:
- Not started
- Approver:
- edA-qa
- Priority:
- Undefined
- Drafter:
- Stephane Mikaty (eCircle AG)
- Direction:
- Needs approval
- Assignee:
- None
- Definition:
- New
- Series goal:
- None
- Implementation:
- Unknown
- Milestone target:
- None
- Started by
- Completed by
Related branches
Related bugs
Sprints
Whiteboard
=== modified file 'src/share/
--- src/share/
+++ src/share/
@@ -430,4 +430,9 @@
return this.resp.
}
+ @Override
+ public String getJavaScriptEr
+ return null;
+ }
+
}
=== modified file 'src/share/
--- src/share/
+++ src/share/
@@ -215,4 +215,9 @@
* Stick to simple numbers, strings and bool.
*/
public Object evaluateJavaScript( String code ) throws Exception;
+
+ /**
+ * @return error console content for the currently active window.
+ */
+ public String getJavaScriptEr
}
=== modified file 'src/share/
--- src/share/
+++ src/share/
@@ -220,5 +220,10 @@
public void invoke( UIAction action ) throws Exception {
unsupported();
}
+
+ }
+ @Override
+ public String getJavaScriptEr
+ return null;
}
}
=== modified file 'src/share/
--- src/share/
+++ src/share/
@@ -203,5 +203,9 @@
unsupported();
}
}
+ @Override
+ public String getJavaScriptEr
+ return null;
+ }
}
=== modified file 'src/share/
--- src/share/
+++ src/share/
@@ -625,4 +625,10 @@
testplan.
}
}
+
+ @Override
+ public String getJavaScriptEr
+ return null;
+ }
+
}
=== modified file 'src/share/
--- src/share/
+++ src/share/
@@ -407,7 +407,19 @@
public String getName() {
return "selenium";
}
+
+ String usrExtBeginJsEr
+ return this.commandPro
+ }
+
+ String usrExtEndJsErro
+ return this.commandPro
+ }
+ String usrExtGetJSErrors() {
+ return this.commandPro
+ }
+
///////////////// START OF CUSTOMIZED SELENIUM METHODS
public void click( String locator ) {
@@ -450,6 +462,7 @@
clearError
}
}
+ this.usrExtBegi
delegate.
}
=== modified file 'src/share/
--- src/share/
+++ src/share/
@@ -1238,4 +1238,9 @@
return browser.getEval( jsEvalOnElement( createFormLocat
}
}
+
+ @Override
+ public String getJavaScriptEr
+ return browser.
+ }
}
=== modified file 'src/share/
--- src/share/
+++ src/share/
@@ -564,4 +564,9 @@
return buffer.toString();
}
}
+
+ @Override
+ public String getJavaScriptEr
+ return null;
+ }
}
=== added file 'user-extension
--- user-extensions.js 1970-01-01 00:00:00 +0000
+++ user-extensions.js 2010-10-27 08:55:33 +0000
@@ -0,0 +1,83 @@
+// =======
+// Report Javascript Errors using Selenium Exceptions
+// =======
+// Courtesy of Jerry Qian (http://
+// http://
+// http://
+//
+// Adapted to work outside of the Selenium IDE:
+//
+// https:/
+// https:/
+// https:/
+
+if (browserVersion
+ var JSErrors = new Array();
+ var theConsoleListener = {
+ observe:function( aMessage ){//async!
+ if(aMessage instanceof Components.
+ JSErrors.
+ }
+ },
+ QueryInterface: function (iid) {
+ if (!iid.equals(
+ !iid.equals(
+ throw Components.
+ }
+ return this;
+ }
+ };
+}
+
+// =======
+// Make it possible to dump the *current* state of
+// the DOM from TestPlan
+// =======
+// Courtesy of
+// https:/
+//
+
+Selenium.
+ var serializer = Components.
+ return serializer.
+};
+
+Selenium.
+
+ var errors = "";
+ if (browserVersion
+ for (var i=0;i<JSErrors.
+ //alert(errors);
+ } else {
+ throw new SeleniumError(
+ }
+ return errors;
+};
+
+Selenium.
+ try {
+ if (browserVersion
+ var aConsoleService = Components.
+ .getService(
+ aConsoleService
+ }else{
+ throw new SeleniumError(
+ }
+ } catch (e) {
+ throw new SeleniumError(
+ }
+};
+
+Selenium.
+ try {
+ if (browserVersion
+ var aConsoleService = Components.
+ .getService(
+ aConsoleService
+ }else{
+ throw new SeleniumError(
+ }
+ } catch (e) {
+ throw new SeleniumError(
+ }
+};