aboutsummaryrefslogtreecommitdiffstats
path: root/test/scenario/DSLSpec.js
diff options
context:
space:
mode:
Diffstat (limited to 'test/scenario/DSLSpec.js')
-rw-r--r--test/scenario/DSLSpec.js369
1 files changed, 210 insertions, 159 deletions
diff --git a/test/scenario/DSLSpec.js b/test/scenario/DSLSpec.js
index 7a8e2e3b..9b011847 100644
--- a/test/scenario/DSLSpec.js
+++ b/test/scenario/DSLSpec.js
@@ -1,181 +1,232 @@
-describe("DSL", function() {
+/**
+ * Very basic Mock of angular.
+ */
+function AngularMock() {
+ this.reset();
+ this.service = this;
+}
- var lastDocument, executeFuture, Expect;
+AngularMock.prototype.reset = function() {
+ this.log = [];
+};
- beforeEach(function() {
- setUpContext();
- executeFuture = function(future, html, callback) {
- lastDocument = _jQuery('<div>' + html + '</div>');
- lastFrame = _jQuery('<iframe>' + lastDocument + '</iframe>');
- _jQuery(document.body).append(lastDocument);
- var specThis = {
- testWindow: window,
- testDocument: lastDocument,
- testFrame: lastFrame,
- jQuery: _jQuery
- };
- future.behavior.call(specThis, callback || noop);
- };
- Expect = _window.expect;
- });
-
- describe("input", function() {
+AngularMock.prototype.element = function(node) {
+ this.log.push('element(' + node.nodeName.toLowerCase() + ')');
+ return this;
+};
- var input = angular.scenario.dsl.input;
+AngularMock.prototype.trigger = function(value) {
+ this.log.push('element().trigger(' + value + ')');
+};
- it('should enter', function() {
- var future = input('name').enter('John');
- expect(future.name).toEqual("input 'name' enter 'John'");
- executeFuture(future, '<input type="text" name="name" />');
- expect(lastDocument.find('input').val()).toEqual('John');
- });
+AngularMock.prototype.$browser = function() {
+ this.log.push('$brower()');
+ return this;
+};
- it('should select', function() {
- var future = input('gender').select('female');
- expect(future.name).toEqual("input 'gender' select 'female'");
- executeFuture(future,
- '<input type="radio" name="0@gender" value="male" checked/>' +
- '<input type="radio" name="0@gender" value="female"/>');
- expect(lastDocument.find(':radio:checked').length).toEqual(1);
- expect(lastDocument.find(':radio:checked').val()).toEqual('female');
- });
- });
+AngularMock.prototype.poll = function() {
+ this.log.push('$brower.poll()');
+ return this;
+};
- describe('browser', function() {
- var browser = angular.scenario.dsl.browser;
- it('shoud return true if location with empty hash provided is same ' +
- 'as location of the page', function() {
- browser.location.href = "http://server";
- expect(browser.location.toEqual("http://server")).toEqual(true);
- });
- it('shoud return true if location with hash provided is same ' +
- 'as location of the page', function() {
- browser.location.href = "http://server";
- browser.location.hash = "hashPath";
- expect(browser.location.toEqual("http://server/#/hashPath")).toEqual(true);
- });
- it('should return true if the location provided is the same as which ' +
- 'browser navigated to', function() {
- var future = browser.navigateTo("http://server/#/hashPath");
- expect(future.name).toEqual("Navigate to: http://server/#/hashPath");
- executeFuture(future, '<input type="text" name="name" />');
- expect(browser.location.toEqual("http://server/#/hashPath")).toEqual(true);
- expect(browser.location.toEqual("http://server/")).toEqual(false);
+AngularMock.prototype.notifyWhenNoOutstandingRequests = function(fn) {
+ this.log.push('$brower.notifyWhenNoOutstandingRequests()');
+ fn();
+};
- future = browser.navigateTo("http://server/");
- expect(future.name).toEqual("Navigate to: http://server/");
- executeFuture(future, '<input type="text" name="name" />');
- expect(browser.location.toEqual("http://server/")).toEqual(true);
- });
+describe("angular.scenario.dsl", function() {
+ var $window;
+ var $root;
+ var application;
+
+ beforeEach(function() {
+ $window = {
+ document: _jQuery("<div></div>"),
+ angular: new AngularMock()
+ };
+ $root = angular.scope({}, angular.service);
+ $root.futures = [];
+ $root.addFuture = function(name, fn) {
+ this.futures.push(name);
+ fn.call(this, function(error, result) {
+ $root.futureError = error;
+ $root.futureResult = result;
+ });
+ };
+ $root.application = new angular.scenario.Application($window.document);
+ $root.application.getWindow = function() {
+ return $window;
+ };
+ $root.application.navigateTo = function(url, callback) {
+ $window.location = url;
+ callback();
+ };
+ // Just use the real one since it delegates to this.addFuture
+ $root.addFutureAction = angular.scenario.
+ SpecRunner.prototype.addFutureAction;
});
-
- describe('repeater', function() {
-
- var repeater = angular.scenario.dsl.repeater;
- var html;
+
+ describe('Pause', function() {
beforeEach(function() {
- html = "<table>" +
- "<tr class='epic'>" +
- "<td class='hero-name'>" +
- "<span ng:bind='hero'>John Marston</span>" +
- "</td>" +
- "<td class='game-name'>" +
- "<span ng:bind='game'>Red Dead Redemption</span>" +
- "</td>" +
- "</tr>" +
- "<tr class='epic'>" +
- "<td class='hero-name'>" +
- "<span ng:bind='hero'>Nathan Drake</span>" +
- "</td>" +
- "<td class='game-name'>" +
- "<span ng:bind='game'>Uncharted</span>" +
- "</td>" +
- "</tr>" +
- "</table>";
+ $root.setTimeout = function(fn, value) {
+ $root.timerValue = value;
+ fn();
+ };
});
- it('should count', function() {
- var future = repeater('.repeater-row').count();
- expect(future.name).toEqual("repeater '.repeater-row' count");
- executeFuture(future,
- "<div class='repeater-row'>a</div>" +
- "<div class='repeater-row'>b</div>",
- function(value) {
- future.fulfill(value);
- });
- expect(future.fulfilled).toBeTruthy();
- expect(future.value).toEqual(2);
+
+ it('should pause for specified seconds', function() {
+ angular.scenario.dsl.pause.call($root).call($root, 10);
+ expect($root.timerValue).toEqual(10000);
+ expect($root.futureResult).toEqual(10000);
+ });
+ });
+
+ describe('Expect', function() {
+ it('should chain and execute matcher', function() {
+ var future = {value: 10};
+ var result = angular.scenario.dsl.expect.call($root).call($root, future);
+ result.toEqual(10);
+ expect($root.futureError).toBeUndefined();
+ expect($root.futureResult).toBeUndefined();
+ var result = angular.scenario.dsl.expect.call($root).call($root, future);
+ result.toEqual(20);
+ expect($root.futureError).toBeDefined();
});
-
- function assertFutureState(future, expectedName, expectedValue) {
- expect(future.name).toEqual(expectedName);
- executeFuture(future, html, function(value) {
- future.fulfill(value);
- });
- expect(future.fulfilled).toBeTruthy();
- expect(future.value).toEqual(expectedValue);
- }
- it('should collect bindings', function() {
- assertFutureState(repeater('.epic').collect('{{hero}}'),
- "repeater '.epic' collect '{{hero}}'",
- ['John Marston', 'Nathan Drake']);
- assertFutureState(repeater('.epic').collect('{{game}}'),
- "repeater '.epic' collect '{{game}}'",
- ['Red Dead Redemption', 'Uncharted']);
+ });
+
+ describe('NavigateTo', function() {
+ it('should allow a string url', function() {
+ angular.scenario.dsl.navigateTo.call($root).call($root, 'http://myurl');
+ expect($window.location).toEqual('http://myurl');
+ expect($root.futureResult).toEqual('http://myurl');
+ });
+
+ it('should allow a future url', function() {
+ var future = {name: 'future name', value: 'http://myurl'};
+ angular.scenario.dsl.navigateTo.call($root).call($root, future);
+ expect($window.location).toEqual('http://myurl');
+ expect($root.futureResult).toEqual('http://myurl');
});
- it('should collect normal selectors', function() {
- assertFutureState(repeater('.epic').collect('.hero-name'),
- "repeater '.epic' collect '.hero-name'",
- ['John Marston', 'Nathan Drake']);
- assertFutureState(repeater('.epic').collect('.game-name'),
- "repeater '.epic' collect '.game-name'",
- ['Red Dead Redemption', 'Uncharted']);
+
+ it('should complete if angular is missing from app frame', function() {
+ delete $window.angular;
+ angular.scenario.dsl.navigateTo.call($root).call($root, 'http://myurl');
+ expect($window.location).toEqual('http://myurl');
+ expect($root.futureResult).toEqual('http://myurl');
});
- it('should collect normal attributes', function() {
- //TODO(shyamseshadri) : Left as an exercise to the user
+
+ it('should wait for angular notify when no requests pending', function() {
+ angular.scenario.dsl.navigateTo.call($root).call($root, 'url');
+ expect($window.angular.log).toContain('$brower.poll()');
+ expect($window.angular.log)
+ .toContain('$brower.notifyWhenNoOutstandingRequests()');
});
});
-
- describe('element', function() {
- var element = angular.scenario.dsl.element;
- var html;
+
+ describe('Element Finding', function() {
+ var doc;
+ //TODO(esprehn): Work around a bug in jQuery where attribute selectors
+ // only work if they are executed on a real document, not an element.
+ //
+ // ex. jQuery('#foo').find('[name="bar"]') // fails
+ // ex. jQuery('#foo [name="bar"]') // works, wtf?
+ //
beforeEach(function() {
- html = '<div class="container">' +
- '<div class="reports-detail">' +
- '<span class="desc">Description : ' +
- '<span ng:bind="report.description">Details...</span>' +
- '</span>' +
- '<span>Date created: ' +
- '<span ng:bind="report.creationDate">01/01/01</span>' +
- '</span>' +
- '</div>' +
- '</div>';
+ doc = _jQuery('<div id="angular-scenario-binding"></div>');
+ _jQuery(document.body).append(doc);
+ $window.document = window.document;
});
- function timeTravel(future) {
- executeFuture(future, html, function(value) { future.fulfill(value); });
- expect(future.fulfilled).toBeTruthy();
- }
- it('should find elements on the page and provide jquery api', function() {
- var future = element('.reports-detail').text();
- expect(future.name).toEqual("Element '.reports-detail'.text()");
- timeTravel(future);
- expect(future.value).
- toEqual('Description : Details...Date created: 01/01/01');
-// expect(future.value.find('.desc').text()).
-// toEqual('Description : Details...');
+
+ afterEach(function() {
+ _jQuery(document.body)
+ .find('#angular-scenario-binding')
+ .remove();
});
- it('should find elements with angular syntax', function() {
- var future = element('{{report.description}}').text();
- expect(future.name).toEqual("Element '{{report.description}}'.text()");
- timeTravel(future);
- expect(future.value).toEqual('Details...');
-// expect(future.value.attr('ng:bind')).toEqual('report.description');
+
+ describe('Binding', function() {
+ it('should select binding by name', function() {
+ doc.append('<span ng:bind="foo.bar">some value</span>');
+ angular.scenario.dsl.binding.call($root).call($root, 'foo.bar');
+ expect($root.futureResult).toEqual('some value');
+ });
+
+ it('should return error if no binding exists', function() {
+ angular.scenario.dsl.binding.call($root).call($root, 'foo.bar');
+ expect($root.futureError).toMatch(/does not exist/);
+ });
});
- it('should be able to click elements', function(){
- var future = element('.link-class').click();
- expect(future.name).toEqual("Element '.link-class'.click()");
- executeFuture(future, html, function(value) { future.fulfill(value); });
- expect(future.fulfilled).toBeTruthy();
- // TODO(rajat): look for some side effect from click happening?
+
+ describe('Input', function() {
+ it('should change value in text input', function() {
+ doc.append('<input name="test.input" value="something">');
+ var chain = angular.scenario.dsl.input
+ .call($root).call($root, 'test.input');
+ chain.enter('foo');
+ expect($window.angular.log).toContain('element(input)');
+ expect($window.angular.log).toContain('element().trigger(change)');
+ expect(_jQuery('input[name="test.input"]').val()).toEqual('foo');
+ });
+
+ it('should return error if no input exists', function() {
+ var chain = angular.scenario.dsl.input
+ .call($root).call($root, 'test.input');
+ chain.enter('foo');
+ expect($root.futureError).toMatch(/does not exist/);
+ });
+
+ it('should toggle checkbox state', function() {
+ doc.append('<input type="checkbox" name="test.input" checked>');
+ expect(_jQuery('input[name="test.input"]')
+ .attr('checked')).toBeTruthy();
+ var chain = angular.scenario.dsl.input
+ .call($root).call($root, 'test.input');
+ chain.check();
+ expect($window.angular.log).toContain('element(input)');
+ expect($window.angular.log).toContain('element().trigger(click)');
+ expect(_jQuery('input[name="test.input"]')
+ .attr('checked')).toBeFalsy();
+ $window.angular.reset();
+ chain.check();
+ expect($window.angular.log).toContain('element(input)');
+ expect($window.angular.log).toContain('element().trigger(click)');
+ expect(_jQuery('input[name="test.input"]')
+ .attr('checked')).toBeTruthy();
+ });
+
+ it('should return error if checkbox does not exist', function() {
+ var chain = angular.scenario.dsl.input
+ .call($root).call($root, 'test.input');
+ chain.check();
+ expect($root.futureError).toMatch(/does not exist/);
+ });
+
+ it('should select option from radio group', function() {
+ doc.append(
+ '<input type="radio" name="0@test.input" value="foo">' +
+ '<input type="radio" name="0@test.input" value="bar" checked>'
+ );
+ expect(_jQuery('input[name="0@test.input"][value="bar"]')
+ .attr('checked')).toBeTruthy();
+ expect(_jQuery('input[name="0@test.input"][value="foo"]')
+ .attr('checked')).toBeFalsy();
+ var chain = angular.scenario.dsl.input
+ .call($root).call($root, 'test.input');
+ chain.select('foo');
+ expect($window.angular.log).toContain('element(input)');
+ expect($window.angular.log).toContain('element().trigger(click)');
+ expect(_jQuery('input[name="0@test.input"][value="bar"]')
+ .attr('checked')).toBeFalsy();
+ expect(_jQuery('input[name="0@test.input"][value="foo"]')
+ .attr('checked')).toBeTruthy();
+ });
+
+ it('should return error if radio button does not exist', function() {
+ var chain = angular.scenario.dsl.input
+ .call($root).call($root, 'test.input');
+ chain.select('foo');
+ expect($root.futureError).toMatch(/does not exist/);
+ });
});
});
+
});