aboutsummaryrefslogtreecommitdiffstats
path: root/test/ngScenario/dslSpec.js
diff options
context:
space:
mode:
authorMisko Hevery2012-03-23 14:03:24 -0700
committerMisko Hevery2012-03-28 11:16:35 -0700
commit2430f52bb97fa9d682e5f028c977c5bf94c5ec38 (patch)
treee7529b741d70199f36d52090b430510bad07f233 /test/ngScenario/dslSpec.js
parent944098a4e0f753f06b40c73ca3e79991cec6c2e2 (diff)
downloadangular.js-2430f52bb97fa9d682e5f028c977c5bf94c5ec38.tar.bz2
chore(module): move files around in preparation for more modules
Diffstat (limited to 'test/ngScenario/dslSpec.js')
-rw-r--r--test/ngScenario/dslSpec.js629
1 files changed, 629 insertions, 0 deletions
diff --git a/test/ngScenario/dslSpec.js b/test/ngScenario/dslSpec.js
new file mode 100644
index 00000000..0a8ab762
--- /dev/null
+++ b/test/ngScenario/dslSpec.js
@@ -0,0 +1,629 @@
+'use strict';
+
+describe("angular.scenario.dsl", function() {
+ var element;
+ var $window, $root;
+ var eventLog;
+
+ afterEach(function() {
+ dealoc(element);
+ });
+
+ beforeEach(inject(function($injector) {
+ eventLog = [];
+ $window = {
+ document: window.document.body,
+ angular: new angular.scenario.testing.MockAngular()
+ };
+ jqLite($window.document).data('$injector', $injector).attr('ng-app', '').addClass('html');
+ $root = $injector.get('$rootScope');
+ $root.emit = function(eventName) {
+ eventLog.push(eventName);
+ };
+ $root.on = function(eventName) {
+ eventLog.push('Listener Added for ' + eventName);
+ };
+ $root.futures = [];
+ $root.futureLog = [];
+ $root.$window = $window;
+ $root.addFuture = function(name, fn) {
+ this.futures.push(name);
+ fn.call(this, function(error, result) {
+ $root.futureError = error;
+ $root.futureResult = result;
+ $root.futureLog.push(name);
+ });
+ };
+ $root.dsl = {};
+ angular.forEach(angular.scenario.dsl, function(fn, name) {
+ $root.dsl[name] = function() {
+ return fn.call($root).apply($root, arguments);
+ };
+ });
+ $root.application = new angular.scenario.Application(jqLite($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;
+ jqLite($window.document).html('');
+ }));
+
+ afterEach(function(){
+ jqLite($window.document).removeData('$injector');
+ });
+
+ describe('Pause', function() {
+ it('should pause until resume to complete', function() {
+ expect($window.resume).toBeUndefined();
+ $root.dsl.pause();
+ expect(angular.isFunction($window.resume)).toBeTruthy();
+ expect($root.futureLog).toEqual([]);
+ $window.resume();
+ expect($root.futureLog).
+ toEqual(['pausing for you to resume']);
+ expect(eventLog).toContain('InteractivePause');
+ });
+ });
+
+ describe('Sleep', function() {
+ beforeEach(function() {
+ $root.$window.setTimeout = function(fn, value) {
+ $root.timerValue = value;
+ fn();
+ };
+ });
+
+ it('should sleep for specified seconds', function() {
+ $root.dsl.sleep(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 = $root.dsl.expect(future);
+ result.toEqual(10);
+ expect($root.futureError).toBeUndefined();
+ expect($root.futureResult).toBeUndefined();
+ result = $root.dsl.expect(future);
+ result.toEqual(20);
+ expect($root.futureError).toBeDefined();
+ });
+ });
+
+ describe('Browser', function() {
+ describe('Reload', function() {
+ it('should navigateTo', function() {
+ $window.location = {
+ href: '#foo'
+ };
+ $root.dsl.browser().reload();
+ expect($root.futureResult).toEqual('#foo');
+ expect($window.location).toEqual('#foo');
+ });
+ });
+
+ describe('NavigateTo', function() {
+ it('should allow a string url', function() {
+ $root.dsl.browser().navigateTo('http://myurl');
+ expect($window.location).toEqual('http://myurl');
+ expect($root.futureResult).toEqual('http://myurl');
+ });
+
+ it('should allow a future url', function() {
+ $root.dsl.browser().navigateTo('http://myurl', function() {
+ return 'http://futureUrl/';
+ });
+ expect($window.location).toEqual('http://futureUrl/');
+ expect($root.futureResult).toEqual('http://futureUrl/');
+ });
+
+ it('should complete if angular is missing from app frame', function() {
+ delete $window.angular;
+ $root.dsl.browser().navigateTo('http://myurl');
+ expect($window.location).toEqual('http://myurl');
+ expect($root.futureResult).toEqual('http://myurl');
+ });
+ });
+
+ describe('window', function() {
+ beforeEach(function() {
+ $window.location = {
+ href: 'http://myurl/some/path?foo=10#/bar?x=2',
+ pathname: '/some/path',
+ search: '?foo=10',
+ hash: '#bar?x=2'
+ };
+ });
+
+ it('should return full URL for href', function() {
+ $root.dsl.browser().window().href();
+ expect($root.futureResult).toEqual($window.location.href);
+ });
+
+ it('should return the pathname', function() {
+ $root.dsl.browser().window().path();
+ expect($root.futureResult).toEqual($window.location.pathname);
+ });
+
+ it('should return the search part', function() {
+ $root.dsl.browser().window().search();
+ expect($root.futureResult).toEqual($window.location.search);
+ });
+
+ it('should return the hash without the #', function() {
+ $root.dsl.browser().window().hash();
+ expect($root.futureResult).toEqual('bar?x=2');
+ });
+ });
+
+ describe('location', function() {
+ beforeEach(function() {
+ $window.angular.injector = function() {
+ return {
+ get: function(serviceId) {
+ if (serviceId == '$location') {
+ return {
+ url: function() {return '/path?search=a#hhh';},
+ path: function() {return '/path';},
+ search: function() {return {search: 'a'};},
+ hash: function() {return 'hhh';}
+ };
+ }
+ throw new Error('unknown service id ' + serviceId);
+ }
+ };
+ };
+ });
+
+ it('should return full url', function() {
+ $root.dsl.browser().location().url();
+ expect($root.futureResult).toEqual('/path?search=a#hhh');
+ });
+
+ it('should return the pathname', function() {
+ $root.dsl.browser().location().path();
+ expect($root.futureResult).toEqual('/path');
+ });
+
+ it('should return the query string as an object', function() {
+ $root.dsl.browser().location().search();
+ expect($root.futureResult).toEqual({search: 'a'});
+ });
+
+ it('should return the hash without the #', function() {
+ $root.dsl.browser().location().hash();
+ expect($root.futureResult).toEqual('hhh');
+ });
+ });
+ });
+
+ describe('Element Finding', function() {
+ var doc;
+ beforeEach(inject(function($injector) {
+ doc = _jQuery($window.document).append('<div class="body"></div>').find('.body');
+ }));
+
+ describe('Select', function() {
+ it('should select single option', function() {
+ doc.append(
+ '<select ng-model="test">' +
+ ' <option value=A>one</option>' +
+ ' <option value=B selected>two</option>' +
+ '</select>'
+ );
+ $root.dsl.select('test').option('A');
+ expect(doc.find('[ng-model="test"]').val()).toEqual('A');
+ });
+
+ it('should select option by name', function() {
+ doc.append(
+ '<select ng-model="test">' +
+ ' <option value=A>one</option>' +
+ ' <option value=B selected>two</option>' +
+ '</select>'
+ );
+ $root.dsl.select('test').option('one');
+ expect(doc.find('[ng-model="test"]').val()).toEqual('A');
+ });
+
+ it('should select multiple options', function() {
+ doc.append(
+ '<select ng-model="test" multiple>' +
+ ' <option>A</option>' +
+ ' <option selected>B</option>' +
+ ' <option>C</option>' +
+ '</select>'
+ );
+ $root.dsl.select('test').options('A', 'B');
+ expect(doc.find('[ng-model="test"]').val()).toEqual(['A','B']);
+ });
+
+ it('should fail to select multiple options on non-multiple select', function() {
+ doc.append('<select ng-model="test"></select>');
+ $root.dsl.select('test').options('A', 'B');
+ expect($root.futureError).toMatch(/did not match/);
+ });
+ });
+
+ describe('Element', function() {
+ it('should execute click', function() {
+ var clicked;
+ // Hash is important, otherwise we actually
+ // go to a different page and break the runner
+ doc.append('<a href="#"></a>');
+ doc.find('a').click(function() {
+ clicked = true;
+ });
+ $root.dsl.element('a').click();
+ });
+
+ it('should navigate page if click on anchor', function() {
+ expect($window.location).not.toEqual('#foo');
+ doc.append('<a href="#foo"></a>');
+ $root.dsl.element('a').click();
+ expect($window.location).toMatch(/#foo$/);
+ });
+
+ it('should not navigate if click event was cancelled', function() {
+ var initLocation = $window.location,
+ elm = jqLite('<a href="#foo"></a>');
+
+ doc.append(elm);
+ elm.bind('click', function(event) {
+ event.preventDefault();
+ });
+
+ $root.dsl.element('a').click();
+ expect($window.location).toBe(initLocation);
+ dealoc(elm);
+ });
+
+ it('should count matching elements', function() {
+ doc.append('<span></span><span></span>');
+ $root.dsl.element('span').count();
+ expect($root.futureResult).toEqual(2);
+ });
+
+ it('should return count of 0 if no matching elements', function() {
+ $root.dsl.element('span').count();
+ expect($root.futureResult).toEqual(0);
+ });
+
+ it('should get attribute', function() {
+ doc.append('<div id="test" class="foo"></div>');
+ $root.dsl.element('#test').attr('class');
+ expect($root.futureResult).toEqual('foo');
+ });
+
+ it('should set attribute', function() {
+ doc.append('<div id="test" class="foo"></div>');
+ $root.dsl.element('#test').attr('class', 'bam');
+ expect(doc.find('#test').attr('class')).toEqual('bam');
+ });
+
+ it('should get property', function() {
+ doc.append('<div id="test" class="foo"></div>');
+ $root.dsl.element('#test').prop('className');
+ expect($root.futureResult).toEqual('foo');
+ });
+
+ it('should set property', function() {
+ doc.append('<div id="test" class="foo"></div>');
+ $root.dsl.element('#test').prop('className', 'bam');
+ expect(doc.find('#test').prop('className')).toEqual('bam');
+ });
+
+ it('should get css', function() {
+ doc.append('<div id="test" style="height: 30px"></div>');
+ $root.dsl.element('#test').css('height');
+ expect($root.futureResult).toMatch(/30px/);
+ });
+
+ it('should set css', function() {
+ doc.append('<div id="test" style="height: 10px"></div>');
+ $root.dsl.element('#test').css('height', '20px');
+ expect(doc.find('#test').css('height')).toEqual('20px');
+ });
+
+ it('should add all jQuery key/value methods', function() {
+ var METHODS = ['css', 'attr'];
+ var chain = $root.dsl.element('input');
+ angular.forEach(METHODS, function(name) {
+ expect(angular.isFunction(chain[name])).toBeTruthy();
+ });
+ });
+
+ it('should get val', function() {
+ doc.append('<input value="bar">');
+ $root.dsl.element('input').val();
+ expect($root.futureResult).toEqual('bar');
+ });
+
+ it('should set val', function() {
+ doc.append('<input value="bar">');
+ $root.dsl.element('input').val('baz');
+ expect(doc.find('input').val()).toEqual('baz');
+ });
+
+ it('should use correct future name for generated set methods', function() {
+ doc.append('<input value="bar">');
+ $root.dsl.element('input').val(false);
+ expect($root.futures.pop()).toMatch(/element 'input' set val/);
+ });
+
+ it('should use correct future name for generated get methods', function() {
+ doc.append('<input value="bar">');
+ $root.dsl.element('input').val();
+ expect($root.futures.pop()).toMatch(/element 'input' val/);
+ });
+
+ it('should add all jQuery property methods', function() {
+ var METHODS = [
+ 'val', 'text', 'html', 'height', 'innerHeight', 'outerHeight', 'width',
+ 'innerWidth', 'outerWidth', 'position', 'scrollLeft', 'scrollTop', 'offset'
+ ];
+ var chain = $root.dsl.element('input');
+ angular.forEach(METHODS, function(name) {
+ expect(angular.isFunction(chain[name])).toBeTruthy();
+ });
+ });
+
+ it('should execute custom query', function() {
+ doc.append('<a id="test" href="http://example.com/myUrl"></a>');
+ $root.dsl.element('#test').query(function(elements, done) {
+ done(null, elements.attr('href'));
+ });
+ expect($root.futureResult).toEqual('http://example.com/myUrl');
+ });
+
+ it('should use the selector as label if none is given', function() {
+ $root.dsl.element('mySelector');
+ expect($root.label).toEqual('mySelector');
+ });
+
+ it('should include the selector in paren when a label is given', function() {
+ $root.dsl.element('mySelector', 'myLabel');
+ expect($root.label).toEqual('myLabel ( mySelector )');
+ });
+ });
+
+ describe('Repeater', function() {
+ var chain;
+ beforeEach(inject(function($compile, $rootScope) {
+ element = $compile(
+ '<ul><li ng-repeat="i in items">{{i.name}} {{i.gender}}</li></ul>')($rootScope);
+ $rootScope.items = [{name:'misko', gender:'male'}, {name:'felisa', gender:'female'}];
+ $rootScope.$apply();
+ doc.append(element);
+ chain = $root.dsl.repeater('ul li');
+ }));
+
+ it('should get the row count', function() {
+ chain.count();
+ expect($root.futureResult).toEqual(2);
+ });
+
+ it('should return 0 if repeater doesnt match', inject(function($rootScope) {
+ $rootScope.items = [];
+ $rootScope.$apply();
+ chain.count();
+ expect($root.futureResult).toEqual(0);
+ }));
+
+ it('should get a row of bindings', function() {
+ chain.row(1);
+ expect($root.futureResult).toEqual(['felisa', 'female']);
+ });
+
+ it('should get a column of bindings', function() {
+ chain.column('i.gender');
+ expect($root.futureResult).toEqual(['male', 'female']);
+ });
+
+ it('should use the selector as label if none is given', function() {
+ expect($root.label).toEqual('ul li');
+ });
+
+ it('should include the selector in paren when a label is given', function() {
+ $root.dsl.repeater('mySelector', 'myLabel');
+ expect($root.label).toEqual('myLabel ( ul li mySelector )');
+ });
+ });
+
+ describe('Binding', function() {
+ var compile;
+
+ beforeEach(inject(function($compile, $rootScope) {
+ compile = function(html, value) {
+ element = $compile(html)($rootScope);
+ doc.append(element);
+ $rootScope.foo = {bar: value || 'some value'};
+ $rootScope.$apply();
+ };
+ }));
+
+
+ it('should select binding in interpolation', function() {
+ compile('<span>{{ foo.bar }}</span>');
+ $root.dsl.binding('foo.bar');
+ expect($root.futureResult).toEqual('some value');
+ });
+
+ it('should select binding in multiple interpolations', function() {
+ compile('<span>{{ foo.bar }}<hr/> {{ true }}</span>');
+ $root.dsl.binding('foo.bar');
+ expect($root.futureResult).toEqual('some value');
+
+ $root.dsl.binding('true');
+ expect($root.futureResult).toEqual('true');
+ });
+
+ it('should select binding by name', function() {
+ compile('<span ng-bind=" foo.bar "></span>');
+ $root.dsl.binding('foo.bar');
+ expect($root.futureResult).toEqual('some value');
+ });
+
+ it('should select binding by regexp', function() {
+ compile('<span ng-bind="foo.bar">some value</span>');
+ $root.dsl.binding(/^foo\..+/);
+ expect($root.futureResult).toEqual('some value');
+ });
+
+ it('should return innerHTML for all the other elements', function() {
+ compile('<div ng-bind-html="foo.bar"></div>', 'some <b>value</b>');
+ $root.dsl.binding('foo.bar');
+ expect($root.futureResult.toLowerCase()).toEqual('some <b>value</b>');
+ });
+
+ it('should select binding in template by name', function() {
+ compile('<pre ng-bind-template="foo {{foo.bar}} baz"></pre>', 'bar');
+ $root.dsl.binding('foo.bar');
+ expect($root.futureResult).toEqual('bar');
+ });
+
+ it('should match bindings by substring match', function() {
+ compile('<pre ng-bind="foo.bar | filter"></pre>', 'binding value');
+ $root.dsl.binding('foo . bar');
+ expect($root.futureResult).toEqual('binding value');
+ });
+
+ it('should return error if no bindings in document', function() {
+ $root.dsl.binding('foo.bar');
+ expect($root.futureError).toMatch(/did not match/);
+ });
+
+ it('should return error if no binding matches', function() {
+ compile('<span ng-bind="foo">some value</span>');
+ $root.dsl.binding('foo.bar');
+ expect($root.futureError).toMatch(/did not match/);
+ });
+ });
+
+ describe('Using', function() {
+ it('should prefix selector in $document.elements()', function() {
+ var chain;
+ doc.append(
+ '<div id="test1"><input ng-model="test.input" value="something"></div>' +
+ '<div id="test2"><input ng-model="test.input" value="something"></div>'
+ );
+ chain = $root.dsl.using('div#test2');
+ chain.input('test.input').enter('foo');
+ var inputs = _jQuery('input[ng-model="test.input"]');
+ expect(inputs.first().val()).toEqual('something');
+ expect(inputs.last().val()).toEqual('foo');
+ });
+
+ it('should use the selector as label if none is given', function() {
+ $root.dsl.using('mySelector');
+ expect($root.label).toEqual('mySelector');
+ });
+
+ it('should include the selector in paren when a label is given', function() {
+ $root.dsl.using('mySelector', 'myLabel');
+ expect($root.label).toEqual('myLabel ( mySelector )');
+ });
+
+ });
+
+ describe('Input', function() {
+ it('should change value in text input', function() {
+ doc.append('<input ng-model="test.input" value="something">');
+ var chain = $root.dsl.input('test.input');
+ chain.enter('foo');
+ expect(_jQuery('input[ng-model="test.input"]').val()).toEqual('foo');
+ });
+
+ it('should change value in text input in dash form', function() {
+ doc.append('<input ng-model="test.input" value="something">');
+ var chain = $root.dsl.input('test.input');
+ chain.enter('foo');
+ expect(_jQuery('input[ng-model="test.input"]').val()).toEqual('foo');
+ });
+
+ it('should return error if no input exists', function() {
+ var chain = $root.dsl.input('test.input');
+ chain.enter('foo');
+ expect($root.futureError).toMatch(/did not match/);
+ });
+
+ it('should toggle checkbox state', function() {
+ doc.append('<input type="checkbox" ng-model="test.input" checked>');
+ expect(_jQuery('input[ng-model="test.input"]').
+ prop('checked')).toBe(true);
+ var chain = $root.dsl.input('test.input');
+ chain.check();
+ expect(_jQuery('input[ng-model="test.input"]').
+ prop('checked')).toBe(false);
+ $window.angular.reset();
+ chain.check();
+ expect(_jQuery('input[ng-model="test.input"]').
+ prop('checked')).toBe(true);
+ });
+
+ it('should return error if checkbox did not match', function() {
+ var chain = $root.dsl.input('test.input');
+ chain.check();
+ expect($root.futureError).toMatch(/did not match/);
+ });
+
+ it('should select option from radio group', function() {
+ doc.append(
+ '<input type="radio" name="r" ng:model="test.input" value="foo">' +
+ '<input type="radio" name="r" ng:model="test.input" value="bar" checked="checked">'
+ );
+ // HACK! We don't know why this is sometimes false on chrome
+ _jQuery('input[ng\\:model="test.input"][value="bar"]').prop('checked', true);
+ expect(_jQuery('input[ng\\:model="test.input"][value="bar"]').
+ prop('checked')).toBe(true);
+ expect(_jQuery('input[ng\\:model="test.input"][value="foo"]').
+ prop('checked')).toBe(false);
+ var chain = $root.dsl.input('test.input');
+ chain.select('foo');
+ expect(_jQuery('input[ng\\:model="test.input"][value="bar"]').
+ prop('checked')).toBe(false);
+ expect(_jQuery('input[ng\\:model="test.input"][value="foo"]').
+ prop('checked')).toBe(true);
+ });
+
+ it('should return error if radio button did not match', function() {
+ var chain = $root.dsl.input('test.input');
+ chain.select('foo');
+ expect($root.futureError).toMatch(/did not match/);
+ });
+
+ describe('val', function() {
+ it('should return value in text input', function() {
+ doc.append('<input ng-model="test.input" value="something">');
+ $root.dsl.input('test.input').val();
+ expect($root.futureResult).toEqual("something");
+ });
+ });
+ });
+
+ describe('Textarea', function() {
+
+ it('should change value in textarea', function() {
+ doc.append('<textarea ng-model="test.textarea">something</textarea>');
+ var chain = $root.dsl.input('test.textarea');
+ chain.enter('foo');
+ expect(_jQuery('textarea[ng-model="test.textarea"]').val()).toEqual('foo');
+ });
+
+ it('should return error if no textarea exists', function() {
+ var chain = $root.dsl.input('test.textarea');
+ chain.enter('foo');
+ expect($root.futureError).toMatch(/did not match/);
+ });
+ });
+ });
+});