From 1abdc097b235366759a889bdcc68359653a9b8a3 Mon Sep 17 00:00:00 2001 From: Vojta Jina Date: Thu, 19 May 2011 17:33:25 +0200 Subject: JSTD adapter for running e2e tests Couple of changes into angular.scenario runner: - add autotest config (runs tests when document ready) - update ObjectModel (forwards events) - use only one ObjectModel instance for all outputters - expose error msg and line number in ObjectModel.Spec and ObjectModel.Step - fix generating spec.ids - fix 'html' output so that it does not mutate ObjectModel Couple of changes into docs / generator: - rename copy -> copyTpl - move docs/static into docs/examples (to avoid conflict with jstd proxy) Running all docs e2e tests: ======================================================== 1/ compile angular-scenario, jstd-scenario-adapter >> rake compile 2/ build docs >> rake docs 3/ start jstd server >> ./server-scenario.sh 4/ capture some browser 5/ run node server to serve static content >> node ../lib/nodeserver/server.js 6/ run tests >> ./test-scenario.sh --- src/jstd-scenario-adapter/Adapter.js | 175 +++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 src/jstd-scenario-adapter/Adapter.js (limited to 'src/jstd-scenario-adapter/Adapter.js') diff --git a/src/jstd-scenario-adapter/Adapter.js b/src/jstd-scenario-adapter/Adapter.js new file mode 100644 index 00000000..fd9674e1 --- /dev/null +++ b/src/jstd-scenario-adapter/Adapter.js @@ -0,0 +1,175 @@ +/** + * JSTestDriver adapter for angular scenario tests + * + * Example of jsTestDriver.conf for running scenario tests with JSTD: +
+    server: http://localhost:9877
+
+    load:
+      - lib/angular-scenario.js
+      - lib/jstd-scenario-adapter-config.js
+      - lib/jstd-scenario-adapter.js
+      # your test files go here #
+
+    proxy:
+     - {matcher: "/your-prefix/*", server: "http://localhost:8000/"}
+  
+ * + * For more information on how to configure jstd proxy, see {@link http://code.google.com/p/js-test-driver/wiki/Proxy} + * Note the order of files - it's important ! + * + * Example of jstd-scenario-adapter-config.js +
+    var jstdScenarioAdapter = {
+      relativeUrlPrefix: '/your-prefix/'
+    };
+  
+ * + * Whenever you use browser().navigateTo('relativeUrl') in your scenario test, the relativeUrlPrefix will be prepended. + * You have to configure this to work together with JSTD proxy. + * + * Let's assume you are using the above configuration (jsTestDriver.conf and jstd-scenario-adapter-config.js): + * Now, when you call browser().navigateTo('index.html') in your scenario test, the browser will open /your-prefix/index.html. + * That matches the proxy, so JSTD will proxy this request to http://localhost:8000/index.html. + */ + +/** + * Custom type of test case + * + * @const + * @see jstestdriver.TestCaseInfo + */ +var SCENARIO_TYPE = 'scenario'; + +/** + * Plugin for JSTestDriver + * Connection point between scenario's jstd output and jstestdriver. + * + * @see jstestdriver.PluginRegistrar + */ +function JstdPlugin() { + var nop = function() {}; + + this.reportResult = nop; + this.reportEnd = nop; + this.runScenario = nop; + + this.name = 'Angular Scenario Adapter'; + + /** + * Called for each JSTD TestCase + * + * Handles only SCENARIO_TYPE test cases. There should be only one fake TestCase. + * Runs all scenario tests (under one fake TestCase) and report all results to JSTD. + * + * @param {jstestdriver.TestRunConfiguration} configuration + * @param {Function} onTestDone + * @param {Function} onAllTestsComplete + * @returns {boolean} True if this type of test is handled by this plugin, false otherwise + */ + this.runTestConfiguration = function(configuration, onTestDone, onAllTestsComplete) { + if (configuration.getTestCaseInfo().getType() != SCENARIO_TYPE) return false; + + this.reportResult = onTestDone; + this.reportEnd = onAllTestsComplete; + this.runScenario(); + + return true; + }; + + this.getTestRunsConfigurationFor = function(testCaseInfos, expressions, testRunsConfiguration) { + testRunsConfiguration.push( + new jstestdriver.TestRunConfiguration( + new jstestdriver.TestCaseInfo( + 'Angular Scenario Tests', function() {}, SCENARIO_TYPE), [])); + + return true; + }; +} + +/** + * Singleton instance of the plugin + * Accessed using closure by: + * - jstd output (reports to this plugin) + * - initScenarioAdapter (register the plugin to jstd) + */ +var plugin = new JstdPlugin(); + +/** + * Initialise scenario jstd-adapter + * (only if jstestdriver is defined) + * + * @param {Object} jstestdriver Undefined when run from browser (without jstd) + * @param {Function} initScenarioAndRun Function that inits scenario and runs all the tests + * @param {Object=} config Configuration object, supported properties: + * - relativeUrlPrefix: prefix for all relative links when navigateTo() + */ +function initScenarioAdapter(jstestdriver, initScenarioAndRun, config) { + if (jstestdriver) { + // create and register ScenarioPlugin + jstestdriver.pluginRegistrar.register(plugin); + plugin.runScenario = initScenarioAndRun; + + /** + * HACK (angular.scenario.Application.navigateTo) + * + * We need to navigate to relative urls when running from browser (without JSTD), + * because we want to allow running scenario tests without creating its own virtual host. + * For example: http://angular.local/build/docs/docs-scenario.html + * + * On the other hand, when running with JSTD, we need to navigate to absolute urls, + * because of JSTD proxy. (proxy, because of same domain policy) + * + * So this hack is applied only if running with JSTD and change all relative urls to absolute. + */ + var appProto = angular.scenario.Application.prototype, + navigateTo = appProto.navigateTo, + relativeUrlPrefix = config && config.relativeUrlPrefix || '/'; + + appProto.navigateTo = function(url, loadFn, errorFn) { + if (url.charAt(0) != '/' && url.charAt(0) != '#' && + url != 'about:blank' && !url.match(/^https?/)) { + url = relativeUrlPrefix + url; + } + + return navigateTo.call(this, url, loadFn, errorFn); + }; + } +} + +/** + * Builds proper TestResult object from given model spec + * + * TODO(vojta) report error details + * + * @param {angular.scenario.ObjectModel.Spec} spec + * @returns {jstestdriver.TestResult} + */ +function createTestResultFromSpec(spec) { + var map = { + success: 'PASSED', + error: 'ERROR', + failure: 'FAILED' + }; + + return new jstestdriver.TestResult( + spec.fullDefinitionName, + spec.name, + jstestdriver.TestResult.RESULT[map[spec.status]], + spec.error || '', + spec.line || '', + spec.duration); +} + +/** + * Generates JSTD output (jstestdriver.TestResult) + */ +angular.scenario.output('jstd', function(context, runner, model) { + model.on('SpecEnd', function(spec) { + plugin.reportResult(createTestResultFromSpec(spec)); + }); + + model.on('RunnerEnd', function() { + plugin.reportEnd(); + }); +}); -- cgit v1.2.3