Skip to content

Instantly share code, notes, and snippets.

@vojtajina
Created February 15, 2012 23:41
Show Gist options
  • Save vojtajina/1840093 to your computer and use it in GitHub Desktop.
Save vojtajina/1840093 to your computer and use it in GitHub Desktop.
Angular: Scenario runner explanation
// simple dsl just wrapping angular's dsl, just providing higher abstraction
angular.scenario.dsl('submitMessage', function() {
return function(message) {
// these dsl already register futures (add fn into the queue),
// so you don't wrap them into addFutureAction
input('modelValue').enter(message);
element('button.submit').click();
};
});
// a dsl returning a future
angular.scenario.dsl('parseMessageId', function() {
return function(selector) {
// this.dsl.using('div.message', 'Message div - caption for runner');
// here you don't have access to the app, it's not loaded yet,
// this happens during the first - RECORD phase
// this adds a fn into the queue,
// whitout calling addFutureAction, it would have no effect during the test (REPLAY phase)
// @param {DOMWindow} appWindow The window object of the iframe (the application)
// @param {jQuery} $document jQuery wrapped document of the application
// @param {function(error, value)} done Callback that should be called when done
// (will basically call the next item in the queuue)
return this.addFutureAction('Parsing an id from message', function(appWindow, $document, done) {
// here, you can access the app,
// this happens during the second phase
var msg = $document.find(selector || 'div.message').text();
// parse the id from the message
var id = parseInt(msg.match(/ID:\s(\d*)/)[1]);
// call the next step of the tests - continue
// first argument is an error - spec will fail with this message
// second argument is a value
done(null, id);
})
};
});
// dsl that can read future argument
angular.scenario.dsl('goToMessage', function() {
return function(futureId) {
var application = this.application;
this.addFutureAction('Navigating to a message', function(appWindow, $document, done) {
// reading the resolved value from a future
var url = '/tmp/e2e-under-test.html?' + futureId.value;
application.navigateTo(url, function() {
done(null, url);
}, done);
})
};
});
// expecting element exists
angular.scenario.matcher('toExist', function() {
return this.actual.length > 0;
});
// unfortunately, current "element()" dsl is not easy to extend, so we have to define our own
angular.scenario.dsl('elm', function() {
return function(selector, label) {
return this.addFutureAction('element ' + (label || selector), function(appWindow, $document, done) {
done(null, $document.find(selector));
});
};
});
// USAGE
describe('test', function() {
beforeEach(function() {
browser().navigateTo('e2e-under-test.html');
});
it('should whatever', function() {
pause();
input('modelValue').enter('SomeText');
pause();
expect(input('modelValue').val()).toBe('SomeText');
});
it('should exist', function() {
expect(elm('div', 'Any div')).toExist();
expect(elm('div.message')).toExist();
// expect(elm('textarea')).toExist();
});
it('should pass', function() {
submitMessage('123 some text');
// parseMessageId() immediately returns an object (that can be passed around)
// later (during second phase), future.value will contain the id
var futureId = parseMessageId();
// expect knows how to treat futures
expect(futureId).toBe(123);
// goToMessage knows how to treat futures
goToMessage(futureId);
});
});
<!DOCTYPE html>
<html ng:app>
<head>
<script type="text/javascript" src="http://ci.angularjs.org/job/angular.js-angular-master/206/artifact/build/pkg/0.10.7-3173d860/angular-0.10.7-3173d860.min.js"></script>
<script type="text/javascript">
function Ctrl($scope) {
$scope.submit = function() {
console.log($scope.modelValue);
};
}
</script>
<title>App under the test</title>
</head>
<body ng:controller="Ctrl">
<div id="test">some</div>
<input ng:model="modelValue" name="alias" class="some" />
<button ng:click="submit()" class="submit">SUBMIT IT</button>
<div class="message">ID: {{modelValue}}</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://ci.angularjs.org/job/angular.js-angular-master/206/artifact/build/pkg/0.10.7-3173d860/angular-scenario-0.10.7-3173d860.js" ng:autotest></script>
<script type="text/javascript" src="e2e-tests.js"></script>
<title>AngularJS: Scenario Testing</title>
</head>
<body>
</body>
</html>
// first phase - RECORDING
var future = this.addFutureAction('label', function(win, doc, done) {
done(error, 'VALUE');
});
future.value === undefined;
// second phase - REPLAY, executing fns from the queue
future.value === 'VALUE';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment