From 39c6c5975bedf6e1610f7328a088acda9ab3406a Mon Sep 17 00:00:00 2001
From: Adam Abrons
Date: Mon, 15 Mar 2010 17:02:54 -0700
Subject: get scenarios running again - open Runner.html in a browser to run
them
---
src/scenario/Runner.js | 171 +++++++++++++++++++++++++++++++++++++++++++++
src/scenario/Steps.js | 57 +++++++++++++++
src/scenario/_namespace.js | 6 ++
src/scenario/bootstrap.js | 47 +++++++++++++
4 files changed, 281 insertions(+)
create mode 100644 src/scenario/Runner.js
create mode 100644 src/scenario/Steps.js
create mode 100644 src/scenario/_namespace.js
create mode 100644 src/scenario/bootstrap.js
(limited to 'src/scenario')
diff --git a/src/scenario/Runner.js b/src/scenario/Runner.js
new file mode 100644
index 00000000..7caddc98
--- /dev/null
+++ b/src/scenario/Runner.js
@@ -0,0 +1,171 @@
+var scenario = angular.scenario;
+scenario.SuiteRunner = function(scenarios, body) {
+ this.scenarios = scenarios;
+ this.body = body;
+};
+
+scenario.SuiteRunner.prototype = {
+ run:function(){
+ this.setUpUI();
+ this.runScenarios();
+ },
+
+
+ setUpUI:function(){
+ this.body.html(
+ '
' +
+ '
. ' +
+ '
. ' +
+ '
. ' +
+ '').find(".run");
+ current.log = current.scenario.append('
').find(".log");
+ current.run.find(".name").text(name);
+ this.tests.push(current);
+ this.console.append(current.scenario);
+ },
+ end:function(name){
+ var current = this.current;
+ var run = current.run;
+ this.current = null;
+ current.end = new Date().getTime();
+ current.time = current.end - current.start;
+ run.find(".time").text(current.time);
+ run.find(".state").text(current.error ? "FAIL" : "PASS");
+ run.addClass(current.error ? "fail" : "pass");
+ if (current.error)
+ run.find(".run").append('
').text(current.error);
+ current.scenario.find(".log").hide();
+ },
+ log:function(level) {
+ var buf = [];
+ for ( var i = 1; i < arguments.length; i++) {
+ var arg = arguments[i];
+ buf.push(typeof arg == "string" ?arg:toJson(arg));
+ }
+ var log = jQuery('
');
+ log.text(buf.join(" "));
+ this.current.log.append(log);
+ this.console.scrollTop(this.console[0].scrollHeight);
+ if (level == "error")
+ this.current.error = buf.join(" ");
+ }
+};
+
+scenario.Scenario = function(name, scenario){
+ this.name = name;
+ this.scenario = scenario;
+};
+scenario.Scenario.prototype = {
+ run:function(runner, callback) {
+ var self = this;
+ _.stepper(this.scenario, function(next, steps, name){
+ if (name.charAt(0) == '$') {
+ next();
+ } else {
+ runner.start(self.name + "::" + name);
+ var allSteps = (self.scenario.$before||[]).concat(steps);
+ _.stepper(allSteps, function(next, step){
+ self.executeStep(runner, step, next);
+ }, function(){
+ runner.end();
+ next();
+ });
+ }
+ }, callback);
+ },
+
+
+ verb:function(step){
+ var fn = null;
+ if (!step) fn = function (){ throw "Step is null!"; };
+ else if (step.Given) fn = scenario.GIVEN[step.Given];
+ else if (step.When) fn = scenario.WHEN[step.When];
+ else if (step.Then) fn = scenario.THEN[step.Then];
+ return fn || function (){
+ throw "ERROR: Need Given/When/Then got: " + toJson(step);
+ };
+ },
+
+
+ context: function(runner) {
+ var frame = runner.frame;
+ var window = frame[0].contentWindow;
+ var document;
+ if (window.jQuery)
+ document = window.jQuery(window.document);
+ var context = {
+ frame:frame,
+ window:window,
+ log:_.bind(runner.log, runner, "info"),
+ document:document,
+ assert:function(element, path){
+ if (element.size() != 1) {
+ throw "Expected to find '1' found '"+
+ element.size()+"' for '"+path+"'.";
+ }
+ return element;
+ },
+ element:function(path){
+ var exp = path.replace("{{","[ng-bind=").replace("}}", "]");
+ var element = document.find(exp);
+ return context.assert(element, path);
+ }
+ };
+ return context;
+ },
+
+
+ executeStep:function(runner, step, callback) {
+ if (!step) {
+ callback();
+ return;
+ }
+ runner.log("info", toJson(step));
+ var fn = this.verb(step);
+ var context = this.context(runner);
+ _.extend(context, step);
+ try {
+ (fn.call(context)||function(c){c();})(callback);
+ } catch (e) {
+ runner.log("error", "ERROR: " + toJson(e));
+ }
+ }
+};
diff --git a/src/scenario/Steps.js b/src/scenario/Steps.js
new file mode 100644
index 00000000..f8ac173f
--- /dev/null
+++ b/src/scenario/Steps.js
@@ -0,0 +1,57 @@
+angular.scenario.GIVEN = {
+ browser:function(){
+ var self = this;
+ if (jQuery.browser.safari && this.frame.attr('src') == this.at) {
+ this.window.location.reload();
+ } else {
+ this.frame.attr('src', this.at);
+ }
+ return function(done){
+ self.frame.load(function(){
+ self.frame.unbind();
+ done();
+ });
+ };
+ },
+ dataset:function(){
+ this.frame.name="$DATASET:" + toJson({dataset:this.dataset});
+ }
+};
+angular.scenario.WHEN = {
+ enter:function(){
+ var element = this.element(this.at);
+ element.attr('value', this.text);
+ element.change();
+ },
+ click:function(){
+ var element = this.element(this.at);
+ var input = element[0];
+ // emulate the browser behavior which causes it
+ // to be overridden at the end.
+ var checked = input.checked = !input.checked;
+ element.click();
+ input.checked = checked;
+ },
+ select:function(){
+ var element = this.element(this.at);
+ var path = "option[value=" + this.option + "]";
+ var option = this.assert(element.find(path));
+ option[0].selected = !option[0].selected;
+ element.change();
+ }
+};
+angular.scenario.THEN = {
+ text:function(){
+ var element = this.element(this.at);
+ if (typeof this.should_be != undefined ) {
+ var should_be = this.should_be;
+ if (_.isArray(this.should_be))
+ should_be = JSON.stringify(should_be);
+ if (element.text() != should_be)
+ throw "Expected " + should_be +
+ " but was " + element.text() + ".";
+ }
+ },
+ drainRequestQueue:function(){
+ }
+};
diff --git a/src/scenario/_namespace.js b/src/scenario/_namespace.js
new file mode 100644
index 00000000..7da3a5d8
--- /dev/null
+++ b/src/scenario/_namespace.js
@@ -0,0 +1,6 @@
+if (!angular) var angular = window['angular'] = {};
+if (!angular['scenario']) var angularScenario = angular['scenario'] = {};
+if (!angular['scenarioDef']) var scenarioDef = angular['scenarioDef'] = {};
+if (!angular['scenario']['GIVEN']) angularScenario['GIVEN'] = {};
+if (!angular['scenario']['WHEN']) angularScenario['WHEN'] = {};
+if (!angular['scenario']['THEN']) angularScenario['THEN'] = {};
diff --git a/src/scenario/bootstrap.js b/src/scenario/bootstrap.js
new file mode 100644
index 00000000..1d40b9d0
--- /dev/null
+++ b/src/scenario/bootstrap.js
@@ -0,0 +1,47 @@
+(function(onLoadDelegate){
+ var prefix = (function(){
+ var filename = /(.*\/)bootstrap.js(#(.*))?/;
+ var scripts = document.getElementsByTagName("script");
+ for(var j = 0; j < scripts.length; j++) {
+ var src = scripts[j].src;
+ if (src && src.match(filename)) {
+ var parts = src.match(filename);
+ return parts[1];
+ }
+ }
+ })();
+ function addScript(path) {
+ document.write('');
+ };
+ function addCSS(path) {
+ document.write('
');
+ };
+ window.onload = function(){
+ if (!_.stepper) {
+ _.stepper = function(collection, iterator, done){
+ var keys = _.keys(collection);
+ function next() {
+ if (keys.length) {
+ var key = keys.shift();
+ iterator(next, collection[key], key);
+ } else {
+ (done||_.identity)();
+ }
+ }
+ next();
+ };
+ }
+ _.defer(function(){
+ new angular.scenario.SuiteRunner(angular.scenarioDef, jQuery(document.body)).run();
+ });
+ (onLoadDelegate||function(){})();
+ };
+ addCSS("../../css/angular-scenario.css");
+ addScript("../../lib/underscore/underscore.js");
+ addScript("../../lib/jquery/jquery-1.3.2.js");
+ addScript("../angular-bootstrap.js");
+ addScript("_namespace.js");
+ addScript("Steps.js");
+ addScript("Runner.js");
+})(window.onload);
+
--
cgit v1.2.3
From 1b976dc27d022c681d764d51a70a1af6a7e35dd6 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Tue, 23 Mar 2010 15:16:44 -0700
Subject: tweeter demo script
---
src/scenario/bootstrap.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'src/scenario')
diff --git a/src/scenario/bootstrap.js b/src/scenario/bootstrap.js
index 1d40b9d0..b49530df 100644
--- a/src/scenario/bootstrap.js
+++ b/src/scenario/bootstrap.js
@@ -8,7 +8,7 @@
var parts = src.match(filename);
return parts[1];
}
- }
+ }
})();
function addScript(path) {
document.write('');
@@ -17,7 +17,7 @@
document.write('
');
};
window.onload = function(){
- if (!_.stepper) {
+ if (!_.stepper) {
_.stepper = function(collection, iterator, done){
var keys = _.keys(collection);
function next() {
@@ -38,7 +38,7 @@
};
addCSS("../../css/angular-scenario.css");
addScript("../../lib/underscore/underscore.js");
- addScript("../../lib/jquery/jquery-1.3.2.js");
+ addScript("../../lib/jquery/jquery-1.4.2.js");
addScript("../angular-bootstrap.js");
addScript("_namespace.js");
addScript("Steps.js");
--
cgit v1.2.3
From 9f9bdcf3d16de651f85ccfe9e079cb57baca9eb7 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Mon, 19 Apr 2010 14:41:36 -0700
Subject: lint
---
src/scenario/bootstrap.js | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
(limited to 'src/scenario')
diff --git a/src/scenario/bootstrap.js b/src/scenario/bootstrap.js
index b49530df..169f1860 100644
--- a/src/scenario/bootstrap.js
+++ b/src/scenario/bootstrap.js
@@ -12,10 +12,12 @@
})();
function addScript(path) {
document.write('');
- };
+ }
+
function addCSS(path) {
document.write('
');
- };
+ }
+
window.onload = function(){
if (!_.stepper) {
_.stepper = function(collection, iterator, done){
--
cgit v1.2.3
From 22d93e0a3bc2a6dc0f64c63c68bc8f8489ea9068 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Tue, 20 Apr 2010 18:14:13 -0700
Subject: fixes to enable ie
---
src/scenario/Steps.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'src/scenario')
diff --git a/src/scenario/Steps.js b/src/scenario/Steps.js
index f8ac173f..ffe75933 100644
--- a/src/scenario/Steps.js
+++ b/src/scenario/Steps.js
@@ -29,14 +29,14 @@ angular.scenario.WHEN = {
// emulate the browser behavior which causes it
// to be overridden at the end.
var checked = input.checked = !input.checked;
- element.click();
+ element.trigger('click');
input.checked = checked;
},
select:function(){
var element = this.element(this.at);
var path = "option[value=" + this.option + "]";
var option = this.assert(element.find(path));
- option[0].selected = !option[0].selected;
+ option[0].selected = !option[0].selected;
element.change();
}
};
@@ -48,7 +48,7 @@ angular.scenario.THEN = {
if (_.isArray(this.should_be))
should_be = JSON.stringify(should_be);
if (element.text() != should_be)
- throw "Expected " + should_be +
+ throw "Expected " + should_be +
" but was " + element.text() + ".";
}
},
--
cgit v1.2.3
From 5215e2095cfd42a0363eb02eded34e03fa2b0cd3 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Thu, 20 May 2010 15:55:41 -0700
Subject: basic end to end runner
---
src/scenario/Runner.js | 250 +++++++++++++++++----------------------------
src/scenario/Steps.js | 57 -----------
src/scenario/_namespace.js | 6 --
src/scenario/bootstrap.js | 19 +---
4 files changed, 96 insertions(+), 236 deletions(-)
delete mode 100644 src/scenario/Steps.js
delete mode 100644 src/scenario/_namespace.js
(limited to 'src/scenario')
diff --git a/src/scenario/Runner.js b/src/scenario/Runner.js
index 7caddc98..eeb4330d 100644
--- a/src/scenario/Runner.js
+++ b/src/scenario/Runner.js
@@ -1,171 +1,109 @@
-var scenario = angular.scenario;
-scenario.SuiteRunner = function(scenarios, body) {
- this.scenarios = scenarios;
- this.body = body;
-};
+angular['scenario'] = (angular['scenario'] = {});
-scenario.SuiteRunner.prototype = {
- run:function(){
- this.setUpUI();
- this.runScenarios();
- },
+angular.scenario.Runner = function(scope){
+ var self = scope.$scenario = this;
+ this.scope = scope;
+ var specs = this.specs = {};
+ var path = [];
+ this.scope.describe = function describe(name, body){
+ path.push(name);
+ body();
+ path.pop();
+ };
+ this.scope.it = function it(name, body) {
+ var specName = path.join(' ') + ': it ' + name;
+ self.currentSpec = specs[specName] = {
+ name: specName,
+ steps:[]
+ };
+ body();
+ self.currentSpec = null;
+ };
+ this.beginSpec = function returnNoop(){
+ return returnNoop;
+ };
+};
- setUpUI:function(){
- this.body.html(
+angular.scenario.Runner.prototype = {
+ run: function(body){
+ body.append(
'
' +
'
' +
'' +
'
');
- this.console = this.body.find(".console");
- this.testFrame = this.body.find("iframe");
- this.console.find(".run").live("click", function(){
- jQuery(this).parent().find('.log').toggle();
- });
- },
-
-
- runScenarios:function(){
- var runner = new scenario.Runner(this.console, this.testFrame);
- _.stepper(this.scenarios, function(next, scenarioObj, name){
- new scenario.Scenario(name, scenarioObj).run(runner, next);
- }, function(){
- }
- );
- }
-};
-
-scenario.Runner = function(console, frame){
- this.console = console;
- this.current = null;
- this.tests = [];
- this.frame = frame;
-};
-scenario.Runner.prototype = {
- start:function(name){
- var current = this.current = {
- name:name,
- start:new Date().getTime(),
- scenario:jQuery('
')
+ var console = body.find('#runner .console');
+ this.testFrame = body.find('#testView iframe');
+ this.testWindow = this.testFrame[0].contentWindow;
+ this.beginSpec = function(name){
+ var specElement = jQuery('
');
+ var stepContainer = jQuery('
');
+ console.append(specElement);
+ specElement.text(name);
+ specElement.append(stepContainer);
+ return function(name){
+ var stepElement = jQuery('
');
+ var logContainer = jQuery('
');
+ stepContainer.append(stepElement);
+ stepElement.text(name);
+ stepElement.append(logContainer);
+ return function(message) {
+ var logElement = jQuery('
');
+ logContainer.append(logElement);
+ logElement.text(message);
+ };
+ };
};
- current.run = current.scenario.append(
- '
' +
- '
. ' +
- '
. ' +
- '
. ' +
- '').find(".run");
- current.log = current.scenario.append('
').find(".log");
- current.run.find(".name").text(name);
- this.tests.push(current);
- this.console.append(current.scenario);
- },
- end:function(name){
- var current = this.current;
- var run = current.run;
- this.current = null;
- current.end = new Date().getTime();
- current.time = current.end - current.start;
- run.find(".time").text(current.time);
- run.find(".state").text(current.error ? "FAIL" : "PASS");
- run.addClass(current.error ? "fail" : "pass");
- if (current.error)
- run.find(".run").append('
').text(current.error);
- current.scenario.find(".log").hide();
+ this.execute("widgets: it should verify that basic widgets work");
},
- log:function(level) {
- var buf = [];
- for ( var i = 1; i < arguments.length; i++) {
- var arg = arguments[i];
- buf.push(typeof arg == "string" ?arg:toJson(arg));
- }
- var log = jQuery('
');
- log.text(buf.join(" "));
- this.current.log.append(log);
- this.console.scrollTop(this.console[0].scrollHeight);
- if (level == "error")
- this.current.error = buf.join(" ");
- }
-};
-scenario.Scenario = function(name, scenario){
- this.name = name;
- this.scenario = scenario;
-};
-scenario.Scenario.prototype = {
- run:function(runner, callback) {
- var self = this;
- _.stepper(this.scenario, function(next, steps, name){
- if (name.charAt(0) == '$') {
- next();
- } else {
- runner.start(self.name + "::" + name);
- var allSteps = (self.scenario.$before||[]).concat(steps);
- _.stepper(allSteps, function(next, step){
- self.executeStep(runner, step, next);
- }, function(){
- runner.end();
- next();
- });
- }
- }, callback);
+ addStep: function(name, step) {
+ this.currentSpec.steps.push({name:name, fn:step});
},
-
- verb:function(step){
- var fn = null;
- if (!step) fn = function (){ throw "Step is null!"; };
- else if (step.Given) fn = scenario.GIVEN[step.Given];
- else if (step.When) fn = scenario.WHEN[step.When];
- else if (step.Then) fn = scenario.THEN[step.Then];
- return fn || function (){
- throw "ERROR: Need Given/When/Then got: " + toJson(step);
+ execute: function(name, callback) {
+ var spec = this.specs[name],
+ result = {
+ passed: false,
+ failed: false,
+ finished: false,
+ fail: function(error) {
+ result.passed = false;
+ result.failed = true;
+ result.error = error;
+ result.log(angular.isString(error) ? error : angular.toJson(error));
+ }
+ };
+ specThis = {
+ result: result,
+ testWindow: this.testWindow,
+ testFrame: this.testFrame
};
- },
-
-
- context: function(runner) {
- var frame = runner.frame;
- var window = frame[0].contentWindow;
- var document;
- if (window.jQuery)
- document = window.jQuery(window.document);
- var context = {
- frame:frame,
- window:window,
- log:_.bind(runner.log, runner, "info"),
- document:document,
- assert:function(element, path){
- if (element.size() != 1) {
- throw "Expected to find '1' found '"+
- element.size()+"' for '"+path+"'.";
- }
- return element;
- },
- element:function(path){
- var exp = path.replace("{{","[ng-bind=").replace("}}", "]");
- var element = document.find(exp);
- return context.assert(element, path);
- }
- };
- return context;
- },
-
-
- executeStep:function(runner, step, callback) {
- if (!step) {
- callback();
- return;
- }
- runner.log("info", toJson(step));
- var fn = this.verb(step);
- var context = this.context(runner);
- _.extend(context, step);
- try {
- (fn.call(context)||function(c){c();})(callback);
- } catch (e) {
- runner.log("error", "ERROR: " + toJson(e));
- }
+ var beginStep = this.beginSpec(name);
+ spec.nextStepIndex = 0;
+ function done() {
+ result.finished = true;
+ (callback||angular.noop).call(specThis);
+ }
+ function next(){
+ var step = spec.steps[spec.nextStepIndex];
+ if (step) {
+ spec.nextStepIndex ++;
+ result.log = beginStep(step.name);
+ try {
+ step.fn.call(specThis, next);
+ } catch (e) {
+ result.fail(e);
+ done();
+ }
+ } else {
+ result.passed = !result.failed;
+ done();
+ }
+ };
+ next();
+ return specThis;
}
-};
+};
\ No newline at end of file
diff --git a/src/scenario/Steps.js b/src/scenario/Steps.js
deleted file mode 100644
index ffe75933..00000000
--- a/src/scenario/Steps.js
+++ /dev/null
@@ -1,57 +0,0 @@
-angular.scenario.GIVEN = {
- browser:function(){
- var self = this;
- if (jQuery.browser.safari && this.frame.attr('src') == this.at) {
- this.window.location.reload();
- } else {
- this.frame.attr('src', this.at);
- }
- return function(done){
- self.frame.load(function(){
- self.frame.unbind();
- done();
- });
- };
- },
- dataset:function(){
- this.frame.name="$DATASET:" + toJson({dataset:this.dataset});
- }
-};
-angular.scenario.WHEN = {
- enter:function(){
- var element = this.element(this.at);
- element.attr('value', this.text);
- element.change();
- },
- click:function(){
- var element = this.element(this.at);
- var input = element[0];
- // emulate the browser behavior which causes it
- // to be overridden at the end.
- var checked = input.checked = !input.checked;
- element.trigger('click');
- input.checked = checked;
- },
- select:function(){
- var element = this.element(this.at);
- var path = "option[value=" + this.option + "]";
- var option = this.assert(element.find(path));
- option[0].selected = !option[0].selected;
- element.change();
- }
-};
-angular.scenario.THEN = {
- text:function(){
- var element = this.element(this.at);
- if (typeof this.should_be != undefined ) {
- var should_be = this.should_be;
- if (_.isArray(this.should_be))
- should_be = JSON.stringify(should_be);
- if (element.text() != should_be)
- throw "Expected " + should_be +
- " but was " + element.text() + ".";
- }
- },
- drainRequestQueue:function(){
- }
-};
diff --git a/src/scenario/_namespace.js b/src/scenario/_namespace.js
deleted file mode 100644
index 7da3a5d8..00000000
--- a/src/scenario/_namespace.js
+++ /dev/null
@@ -1,6 +0,0 @@
-if (!angular) var angular = window['angular'] = {};
-if (!angular['scenario']) var angularScenario = angular['scenario'] = {};
-if (!angular['scenarioDef']) var scenarioDef = angular['scenarioDef'] = {};
-if (!angular['scenario']['GIVEN']) angularScenario['GIVEN'] = {};
-if (!angular['scenario']['WHEN']) angularScenario['WHEN'] = {};
-if (!angular['scenario']['THEN']) angularScenario['THEN'] = {};
diff --git a/src/scenario/bootstrap.js b/src/scenario/bootstrap.js
index 169f1860..81272bdd 100644
--- a/src/scenario/bootstrap.js
+++ b/src/scenario/bootstrap.js
@@ -19,22 +19,8 @@
}
window.onload = function(){
- if (!_.stepper) {
- _.stepper = function(collection, iterator, done){
- var keys = _.keys(collection);
- function next() {
- if (keys.length) {
- var key = keys.shift();
- iterator(next, collection[key], key);
- } else {
- (done||_.identity)();
- }
- }
- next();
- };
- }
_.defer(function(){
- new angular.scenario.SuiteRunner(angular.scenarioDef, jQuery(document.body)).run();
+ $scenarioRunner.run(jQuery(document.body));
});
(onLoadDelegate||function(){})();
};
@@ -42,8 +28,7 @@
addScript("../../lib/underscore/underscore.js");
addScript("../../lib/jquery/jquery-1.4.2.js");
addScript("../angular-bootstrap.js");
- addScript("_namespace.js");
- addScript("Steps.js");
addScript("Runner.js");
+ document.write('');
})(window.onload);
--
cgit v1.2.3
From e3368e12a6207706d8a08b18f9958db3b86ca4e5 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Thu, 20 May 2010 16:55:47 -0700
Subject: semi working state
---
src/scenario/Runner.js | 63 +++++++++++++++++++++++++++++++-------------------
1 file changed, 39 insertions(+), 24 deletions(-)
(limited to 'src/scenario')
diff --git a/src/scenario/Runner.js b/src/scenario/Runner.js
index eeb4330d..970d0c66 100644
--- a/src/scenario/Runner.js
+++ b/src/scenario/Runner.js
@@ -20,8 +20,8 @@ angular.scenario.Runner = function(scope){
body();
self.currentSpec = null;
};
- this.beginSpec = function returnNoop(){
- return returnNoop;
+ this.logger = function returnNoop(){
+ return angular.extend(returnNoop, {close:angular.noop, fail:angular.noop});;
};
};
@@ -29,33 +29,45 @@ angular.scenario.Runner.prototype = {
run: function(body){
body.append(
'
' +
'
' +
'' +
'
');
var console = body.find('#runner .console');
+ console.find('li').live('click', function(){
+ jQuery(this).toggleClass('collapsed');
+ });
this.testFrame = body.find('#testView iframe');
this.testWindow = this.testFrame[0].contentWindow;
- this.beginSpec = function(name){
- var specElement = jQuery('
');
- var stepContainer = jQuery('
');
- console.append(specElement);
- specElement.text(name);
- specElement.append(stepContainer);
- return function(name){
- var stepElement = jQuery('
');
- var logContainer = jQuery('
');
- stepContainer.append(stepElement);
- stepElement.text(name);
- stepElement.append(logContainer);
- return function(message) {
- var logElement = jQuery('
');
- logContainer.append(logElement);
- logElement.text(message);
- };
+ function logger(parent) {
+ var container;
+ return function(type, text) {
+ if (!container) {
+ container = jQuery('
');
+ parent.append(container);
+ }
+ var element = jQuery('
');
+ element.find('span').text(text);
+ container.append(element);
+ return angular.extend(logger(element), {
+ close: function(){
+ element.removeClass('running');
+ },
+ fail: function(){
+ element.removeClass('running');
+ var current = element;
+ while (current[0] != console[0]) {
+ if (current.is('li'))
+ current.addClass('fail');
+ current.removeClass('collapsed');
+ current = current.parent();
+ }
+ }
+ });;
};
- };
+ }
+ this.logger = logger(console);
this.execute("widgets: it should verify that basic widgets work");
},
@@ -73,7 +85,7 @@ angular.scenario.Runner.prototype = {
result.passed = false;
result.failed = true;
result.error = error;
- result.log(angular.isString(error) ? error : angular.toJson(error));
+ result.log('fail', angular.isString(error) ? error : angular.toJson(error)).fail();
}
};
specThis = {
@@ -81,17 +93,20 @@ angular.scenario.Runner.prototype = {
testWindow: this.testWindow,
testFrame: this.testFrame
};
- var beginStep = this.beginSpec(name);
+ var stepLogger = this.logger('spec', name);
spec.nextStepIndex = 0;
function done() {
result.finished = true;
+ stepLogger.close();
(callback||angular.noop).call(specThis);
}
function next(){
var step = spec.steps[spec.nextStepIndex];
+ (result.log || {close:angular.noop}).close();
+ result.log = null;
if (step) {
spec.nextStepIndex ++;
- result.log = beginStep(step.name);
+ result.log = stepLogger('step', step.name);
try {
step.fn.call(specThis, next);
} catch (e) {
--
cgit v1.2.3
From f6c67e28c94033edf6a16eb6508de54679cb49db Mon Sep 17 00:00:00 2001
From: Andres Ornelas Mesta
Date: Mon, 24 May 2010 13:54:32 -0700
Subject: happy
---
src/scenario/Runner.js | 44 +++++++++++++++++++++++++++++---------------
src/scenario/bootstrap.js | 6 ++++--
2 files changed, 33 insertions(+), 17 deletions(-)
(limited to 'src/scenario')
diff --git a/src/scenario/Runner.js b/src/scenario/Runner.js
index 970d0c66..9e20d394 100644
--- a/src/scenario/Runner.js
+++ b/src/scenario/Runner.js
@@ -1,8 +1,9 @@
angular['scenario'] = (angular['scenario'] = {});
-angular.scenario.Runner = function(scope){
+angular.scenario.Runner = function(scope, jQuery){
var self = scope.$scenario = this;
this.scope = scope;
+ this.jQuery = jQuery;
var specs = this.specs = {};
var path = [];
@@ -27,6 +28,7 @@ angular.scenario.Runner = function(scope){
angular.scenario.Runner.prototype = {
run: function(body){
+ var jQuery = this.jQuery;
body.append(
'
' +
'
' +
@@ -68,7 +70,19 @@ angular.scenario.Runner.prototype = {
};
}
this.logger = logger(console);
- this.execute("widgets: it should verify that basic widgets work");
+ var specNames = [];
+ angular.foreach(this.specs, function(spec, name){
+ specNames.push(name);
+ }, this);
+ specNames.sort();
+ var self = this;
+ function callback(){
+ var next = specNames.shift();
+ if(next) {
+ self.execute(next, callback);
+ }
+ };
+ callback();
},
addStep: function(name, step) {
@@ -102,21 +116,21 @@ angular.scenario.Runner.prototype = {
}
function next(){
var step = spec.steps[spec.nextStepIndex];
- (result.log || {close:angular.noop}).close();
- result.log = null;
- if (step) {
- spec.nextStepIndex ++;
- result.log = stepLogger('step', step.name);
- try {
- step.fn.call(specThis, next);
- } catch (e) {
- result.fail(e);
- done();
- }
- } else {
- result.passed = !result.failed;
+ (result.log || {close:angular.noop}).close();
+ result.log = null;
+ if (step) {
+ spec.nextStepIndex ++;
+ result.log = stepLogger('step', step.name);
+ try {
+ step.fn.call(specThis, next);
+ } catch (e) {
+ result.fail(e);
done();
}
+ } else {
+ result.passed = !result.failed;
+ done();
+ }
};
next();
return specThis;
diff --git a/src/scenario/bootstrap.js b/src/scenario/bootstrap.js
index 81272bdd..51d24c38 100644
--- a/src/scenario/bootstrap.js
+++ b/src/scenario/bootstrap.js
@@ -20,7 +20,7 @@
window.onload = function(){
_.defer(function(){
- $scenarioRunner.run(jQuery(document.body));
+ $scenarioRunner.run(jQuery(window.document.body));
});
(onLoadDelegate||function(){})();
};
@@ -29,6 +29,8 @@
addScript("../../lib/jquery/jquery-1.4.2.js");
addScript("../angular-bootstrap.js");
addScript("Runner.js");
- document.write('');
+ document.write('');
})(window.onload);
--
cgit v1.2.3
From 3fab5d9879272b9f991a67c8135754f00c055834 Mon Sep 17 00:00:00 2001
From: Andres Ornelas
Date: Mon, 24 May 2010 15:25:30 -0700
Subject: added error handling on scenario definition
---
src/scenario/DSL.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++
src/scenario/Runner.js | 15 ++++++++++++---
src/scenario/bootstrap.js | 1 +
3 files changed, 60 insertions(+), 3 deletions(-)
create mode 100644 src/scenario/DSL.js
(limited to 'src/scenario')
diff --git a/src/scenario/DSL.js b/src/scenario/DSL.js
new file mode 100644
index 00000000..4bc21d6c
--- /dev/null
+++ b/src/scenario/DSL.js
@@ -0,0 +1,47 @@
+angular.scenario.dsl.browser = {
+ navigateTo: function(url){
+ $scenario.addStep('Navigate to: ' + url, function(done){
+ var self = this;
+ self.testFrame.load(function(){
+ self.testFrame.unbind();
+ self.testDocument = jQuery(self.testWindow.document);
+ done();
+ });
+ if (this.testFrame.attr('src') == url) {
+ this.testWindow.location.reload();
+ } else {
+ this.testFrame.attr('src', url);
+ }
+ });
+ }
+};
+
+angular.scenario.dsl.input = function(selector) {
+ return {
+ enter: function(value){
+ $scenario.addStep("Set input text of '" + selector + "' to value '" +
+ value + "'", function(done){
+ var input = this.testDocument.find('input[name=' + selector + ']');
+ input.val(value);
+ input.trigger('change');
+ this.testWindow.angular.element(input[0]).trigger('change');
+ done();
+ });
+ }
+ };
+};
+
+angular.scenario.dsl.expect = function(selector) {
+ return {
+ toEqual: function(expected) {
+ $scenario.addStep("Expect that " + selector + " equals '" + expected + "'", function(done){
+ var attrName = selector.substring(2, selector.length - 2);
+ var binding = this.testDocument.find('span[ng-bind=' + attrName + ']');
+ if (binding.text() != expected) {
+ this.result.fail("Expected '" + expected + "' but was '" + binding.text() + "'");
+ }
+ done();
+ });
+ }
+ };
+};
diff --git a/src/scenario/Runner.js b/src/scenario/Runner.js
index 9e20d394..003ce487 100644
--- a/src/scenario/Runner.js
+++ b/src/scenario/Runner.js
@@ -1,9 +1,11 @@
-angular['scenario'] = (angular['scenario'] = {});
+angular['scenario'] = (angular['scenario'] = {});
+angular.scenario['dsl'] = (angular.scenario['dsl'] = {});
angular.scenario.Runner = function(scope, jQuery){
var self = scope.$scenario = this;
this.scope = scope;
this.jQuery = jQuery;
+ angular.extend(scope, angular.scenario.dsl);
var specs = this.specs = {};
var path = [];
@@ -18,7 +20,13 @@ angular.scenario.Runner = function(scope, jQuery){
name: specName,
steps:[]
};
- body();
+ try {
+ body();
+ } catch(err) {
+ self.addStep(err.message || 'ERROR', function(){
+ throw err;
+ });
+ }
self.currentSpec = null;
};
this.logger = function returnNoop(){
@@ -55,6 +63,7 @@ angular.scenario.Runner.prototype = {
return angular.extend(logger(element), {
close: function(){
element.removeClass('running');
+ console.scrollTop(console[0].scrollHeight);
},
fail: function(){
element.removeClass('running');
@@ -66,7 +75,7 @@ angular.scenario.Runner.prototype = {
current = current.parent();
}
}
- });;
+ });
};
}
this.logger = logger(console);
diff --git a/src/scenario/bootstrap.js b/src/scenario/bootstrap.js
index 51d24c38..4c9cdc8d 100644
--- a/src/scenario/bootstrap.js
+++ b/src/scenario/bootstrap.js
@@ -29,6 +29,7 @@
addScript("../../lib/jquery/jquery-1.4.2.js");
addScript("../angular-bootstrap.js");
addScript("Runner.js");
+ addScript("DSL.js");
document.write('');
--
cgit v1.2.3
From 55c0767f16e60e77e9d1b4d46698ddbf343ed8b1 Mon Sep 17 00:00:00 2001
From: Andres Ornelas
Date: Mon, 24 May 2010 17:48:17 -0700
Subject: added dsl tests and select method
---
src/scenario/DSL.js | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
(limited to 'src/scenario')
diff --git a/src/scenario/DSL.js b/src/scenario/DSL.js
index 4bc21d6c..842f7c7a 100644
--- a/src/scenario/DSL.js
+++ b/src/scenario/DSL.js
@@ -19,14 +19,24 @@ angular.scenario.dsl.browser = {
angular.scenario.dsl.input = function(selector) {
return {
enter: function(value){
- $scenario.addStep("Set input text of '" + selector + "' to value '" +
+ $scenario.addStep("Set input text of '" + selector + "' to '" +
value + "'", function(done){
var input = this.testDocument.find('input[name=' + selector + ']');
input.val(value);
- input.trigger('change');
this.testWindow.angular.element(input[0]).trigger('change');
done();
});
+ },
+ select: function(value){
+ $scenario.addStep("Select radio '" + selector + "' to '" +
+ value + "'", function(done){
+ var input = this.testDocument.
+ find(':radio[name$=@' + selector + '][value=' + value + ']');
+ var event = this.testWindow.document.createEvent('MouseEvent');
+ event.initMouseEvent('click', true, true, this.testWindow, 0,0,0,0,0, false, false, false, false, 0, null);
+ input[0].dispatchEvent(event);
+ done();
+ });
}
};
};
--
cgit v1.2.3
From 2cce1ffc15ae6483da9cf354f7a5d2d26317427e Mon Sep 17 00:00:00 2001
From: Andres Ornelas
Date: Tue, 25 May 2010 13:05:23 -0700
Subject: fixed collapsed issue
---
src/scenario/Runner.js | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
(limited to 'src/scenario')
diff --git a/src/scenario/Runner.js b/src/scenario/Runner.js
index 003ce487..8669f56b 100644
--- a/src/scenario/Runner.js
+++ b/src/scenario/Runner.js
@@ -57,12 +57,14 @@ angular.scenario.Runner.prototype = {
container = jQuery('
');
parent.append(container);
}
- var element = jQuery('
');
+ var element = jQuery('
');
element.find('span').text(text);
container.append(element);
return angular.extend(logger(element), {
close: function(){
element.removeClass('running');
+ if(!element.hasClass('fail'))
+ element.addClass('collapsed');
console.scrollTop(console[0].scrollHeight);
},
fail: function(){
@@ -71,7 +73,6 @@ angular.scenario.Runner.prototype = {
while (current[0] != console[0]) {
if (current.is('li'))
current.addClass('fail');
- current.removeClass('collapsed');
current = current.parent();
}
}
--
cgit v1.2.3
From 5992e81b2e302c3b3375567e347227f6a9496585 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Tue, 25 May 2010 14:23:52 -0700
Subject: added rake task to create a single file for scenario runner
---
src/scenario/DSL.js | 1 +
src/scenario/Runner.js | 18 +++++++++---------
src/scenario/angular.prefix | 30 ++++++++++++++++++++++++++++++
src/scenario/angular.suffix | 11 +++++++++++
src/scenario/bootstrap.js | 9 ++++++++-
5 files changed, 59 insertions(+), 10 deletions(-)
create mode 100644 src/scenario/angular.prefix
create mode 100644 src/scenario/angular.suffix
(limited to 'src/scenario')
diff --git a/src/scenario/DSL.js b/src/scenario/DSL.js
index 842f7c7a..8cbb256d 100644
--- a/src/scenario/DSL.js
+++ b/src/scenario/DSL.js
@@ -5,6 +5,7 @@ angular.scenario.dsl.browser = {
self.testFrame.load(function(){
self.testFrame.unbind();
self.testDocument = jQuery(self.testWindow.document);
+ self.testWindow = self.testFrame[0].contentWindow;
done();
});
if (this.testFrame.attr('src') == url) {
diff --git a/src/scenario/Runner.js b/src/scenario/Runner.js
index 8669f56b..01e16e79 100644
--- a/src/scenario/Runner.js
+++ b/src/scenario/Runner.js
@@ -1,11 +1,10 @@
-angular['scenario'] = (angular['scenario'] = {});
-angular.scenario['dsl'] = (angular.scenario['dsl'] = {});
+angular['scenario'] = angular['scenario'] || (angular['scenario'] = {});
+angular.scenario['dsl'] = angular.scenario['dsl'] || (angular.scenario['dsl'] = {});
angular.scenario.Runner = function(scope, jQuery){
var self = scope.$scenario = this;
this.scope = scope;
this.jQuery = jQuery;
- angular.extend(scope, angular.scenario.dsl);
var specs = this.specs = {};
var path = [];
@@ -30,7 +29,7 @@ angular.scenario.Runner = function(scope, jQuery){
self.currentSpec = null;
};
this.logger = function returnNoop(){
- return angular.extend(returnNoop, {close:angular.noop, fail:angular.noop});;
+ return _(returnNoop).extend({close:_.identity, fail:_.identity});;
};
};
@@ -60,7 +59,7 @@ angular.scenario.Runner.prototype = {
var element = jQuery('
');
element.find('span').text(text);
container.append(element);
- return angular.extend(logger(element), {
+ return _(logger(element)).extend({
close: function(){
element.removeClass('running');
if(!element.hasClass('fail'))
@@ -81,7 +80,7 @@ angular.scenario.Runner.prototype = {
}
this.logger = logger(console);
var specNames = [];
- angular.foreach(this.specs, function(spec, name){
+ _(this.specs).each(function(spec, name){
specNames.push(name);
}, this);
specNames.sort();
@@ -109,7 +108,7 @@ angular.scenario.Runner.prototype = {
result.passed = false;
result.failed = true;
result.error = error;
- result.log('fail', angular.isString(error) ? error : angular.toJson(error)).fail();
+ result.log('fail', _(error).isString() ? error : toJson(error)).fail();
}
};
specThis = {
@@ -122,11 +121,11 @@ angular.scenario.Runner.prototype = {
function done() {
result.finished = true;
stepLogger.close();
- (callback||angular.noop).call(specThis);
+ (callback||_.identity).call(specThis);
}
function next(){
var step = spec.steps[spec.nextStepIndex];
- (result.log || {close:angular.noop}).close();
+ (result.log || {close:_.identity}).close();
result.log = null;
if (step) {
spec.nextStepIndex ++;
@@ -134,6 +133,7 @@ angular.scenario.Runner.prototype = {
try {
step.fn.call(specThis, next);
} catch (e) {
+ console.error(e);
result.fail(e);
done();
}
diff --git a/src/scenario/angular.prefix b/src/scenario/angular.prefix
new file mode 100644
index 00000000..5b44e17c
--- /dev/null
+++ b/src/scenario/angular.prefix
@@ -0,0 +1,30 @@
+/**
+ * The MIT License
+ *
+ * Copyright (c) 2010 Adam Abrons and Misko Hevery http://getangular.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+(function(window, document, previousOnLoad){
+ window.angular = {
+ scenario: {
+ dsl: window
+ }
+ };
+
diff --git a/src/scenario/angular.suffix b/src/scenario/angular.suffix
new file mode 100644
index 00000000..fc861cbf
--- /dev/null
+++ b/src/scenario/angular.suffix
@@ -0,0 +1,11 @@
+
+ var $scenarioRunner = new angular.scenario.Runner(window, jQuery);
+
+ window.onload = function(){
+ try {
+ if (previousOnLoad) previousOnLoad();
+ } catch(e) {}
+ $scenarioRunner.run(jQuery(window.document.body));
+ };
+
+})(window, document, window.onload);
diff --git a/src/scenario/bootstrap.js b/src/scenario/bootstrap.js
index 4c9cdc8d..694d0e97 100644
--- a/src/scenario/bootstrap.js
+++ b/src/scenario/bootstrap.js
@@ -18,6 +18,12 @@
document.write('
');
}
+ window.angular = {
+ scenario: {
+ dsl: window
+ }
+ };
+
window.onload = function(){
_.defer(function(){
$scenarioRunner.run(jQuery(window.document.body));
@@ -27,8 +33,9 @@
addCSS("../../css/angular-scenario.css");
addScript("../../lib/underscore/underscore.js");
addScript("../../lib/jquery/jquery-1.4.2.js");
- addScript("../angular-bootstrap.js");
addScript("Runner.js");
+ addScript("../Angular.js");
+ addScript("../JSON.js");
addScript("DSL.js");
document.write('