From 1e60a9504c883a95f3500eafa38e1fc11dc28c9b Mon Sep 17 00:00:00 2001 From: Hank Duan Date: Tue, 30 Dec 2014 12:23:57 -0800 Subject: [PATCH] feat(frameworks): add jasmine2 framework --- docs/referenceConf.js | 14 ++- lib/frameworks/jasmine2.js | 95 +++++++++++++++++++ lib/runner.js | 2 + package.json | 2 + scripts/test.js | 12 +-- scripts/unit_test.json | 7 ++ spec/altRootConf.js | 2 + spec/basic/locators_spec.js | 14 ++- spec/basicConf.js | 2 + spec/ciConf.js | 2 + spec/directConnectConf.js | 2 + .../afterLaunchChangesExitCodeConf.js | 2 + spec/errorTest/multiFailureConf.js | 2 + spec/errorTest/shardedFailureConf.js | 2 + spec/errorTest/singleFailureConf.js | 2 + spec/errorTest/timeoutConf.js | 2 + spec/interactionConf.js | 2 + spec/junitOutputConf.js | 2 + spec/multiConf.js | 2 + spec/ngHintFailConfig.js | 1 + spec/ngHintSuccessConfig.js | 1 + spec/onCleanUpAsyncReturnValueConf.js | 2 + spec/onCleanUpNoReturnValueConf.js | 2 + spec/onCleanUpSyncReturnValueConf.js | 2 + spec/onPrepareConf.js | 2 + spec/onPrepareFileConf.js | 2 + spec/onPreparePromiseConf.js | 2 + spec/onPreparePromiseFileConf.js | 2 + spec/pluginsBasicConf.js | 2 + spec/pluginsFullConf.js | 2 + spec/restartBrowserBetweenTestsConf.js | 2 + spec/smokeConf.js | 2 + spec/suitesConf.js | 2 + spec/unit/config_test.js | 2 +- spec/withLoginConf.js | 2 + 35 files changed, 186 insertions(+), 14 deletions(-) create mode 100644 lib/frameworks/jasmine2.js create mode 100644 scripts/unit_test.json diff --git a/docs/referenceConf.js b/docs/referenceConf.js index 4a224c2aa..f50600344 100644 --- a/docs/referenceConf.js +++ b/docs/referenceConf.js @@ -236,7 +236,7 @@ exports.config = { // ----- The test framework -------------------------------------------------- // --------------------------------------------------------------------------- - // Test framework to use. This may be jasmine, cucumber, or mocha. + // Test framework to use. This may be jasmine, jasmine2, cucumber, or mocha. // // Jasmine is fully supported as a test and assertion framework. // Mocha and Cucumber have limited beta support. You will need to include your @@ -257,6 +257,18 @@ exports.config = { defaultTimeoutInterval: 30000 }, + // Options to be passed to jasmine2. + // + // See the full list at https://github.com/jasmine/jasmine-npm + jasmineNodeOpts: { + // If true, print colors to the terminal. + showColors: true, + // Default time to wait in ms before a test fails. + defaultTimeoutInterval: 30000, + // Function called to print jasmine results + print: function() {}, + }, + // Options to be passed to Mocha. // // See the full list at http://visionmedia.github.io/mocha/ diff --git a/lib/frameworks/jasmine2.js b/lib/frameworks/jasmine2.js new file mode 100644 index 000000000..b03e4c760 --- /dev/null +++ b/lib/frameworks/jasmine2.js @@ -0,0 +1,95 @@ +var q = require('q'); + +var RunnerReporter = function(emitter) { + this.emitter = emitter; + this.testResult = [], + this.failedCount = 0; +}; + +RunnerReporter.prototype.jasmineStarted = function() { + // Need to initiate startTime here, in case reportSpecStarting is not + // called (e.g. when fit is used) + this.startTime = new Date(); +}; + +RunnerReporter.prototype.specStarted = function() { + this.startTime = new Date(); +}; + +RunnerReporter.prototype.specDone = function(result) { + if (result.status == 'passed') { + this.emitter.emit('testPass'); + } else if (result.status == 'failed') { + this.emitter.emit('testFail'); + this.failedCount++; + } + + var entry = { + description: result.description, + assertions: [], + duration: new Date().getTime() - this.startTime.getTime() + }; + + result.failedExpectations.forEach(function(item) { + entry.assertions.push({ + passed: item.passed, + errorMsg: item.passed ? undefined : item.message, + stackTrace: item.passed ? undefined : item.stack + }); + }); + this.testResult.push(entry); +}; + +/** + * Execute the Runner's test cases through Jasmine. + * + * @param {Runner} runner The current Protractor Runner. + * @param {Array} specs Array of Directory Path Strings. + * @return {q.Promise} Promise resolved with the test results + */ +exports.run = function(runner, specs) { + var JasmineRunner = require('jasmine'); + var jrunner = new JasmineRunner(); + /* global jasmine */ + + require('jasminewd2'); + + // On timeout, the flow should be reset. This will prevent webdriver tasks + // from overflowing into the next test and causing it to fail or timeout + // as well. This is done in the reporter instead of an afterEach block + // to ensure that it runs after any afterEach() blocks with webdriver tasks + // get to complete first. + var reporter = new RunnerReporter(runner); + jasmine.getEnv().addReporter(reporter); + + return runner.runTestPreparer().then(function() { + return q.promise(function (resolve, reject) { + var jasmineNodeOpts = runner.getConfig().jasmineNodeOpts; + + if (jasmineNodeOpts && jasmineNodeOpts.defaultTimeoutInterval) { + jasmine.DEFAULT_TIMEOUT_INTERVAL = jasmineNodeOpts.defaultTimeoutInterval; + } + + var originalOnComplete = runner.getConfig().onComplete; + jasmineNodeOpts.onComplete = function(passed) { + try { + if (originalOnComplete) { + originalOnComplete(passed); + } + resolve({ + failedCount: reporter.failedCount, + specResults: reporter.testResult + }); + } catch(err) { + reject(err); + } + }; + + jrunner.configureDefaultReporter(jasmineNodeOpts); + jrunner.projectBaseDir = ''; + jrunner.specDir = ''; + jrunner.addSpecFiles(specs); + jrunner.execute(); + }); + }); +}; diff --git a/lib/runner.js b/lib/runner.js index f6f03b05c..3a8116c70 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -263,6 +263,8 @@ Runner.prototype.run = function() { var frameworkPath = ''; if (self.config_.framework === 'jasmine') { frameworkPath = './frameworks/jasmine.js'; + } else if (self.config_.framework === 'jasmine2') { + frameworkPath = './frameworks/jasmine2.js'; } else if (self.config_.framework === 'mocha') { frameworkPath = './frameworks/mocha.js'; } else if (self.config_.framework === 'cucumber') { diff --git a/package.json b/package.json index bd23dfa8b..6d7b7f0da 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,8 @@ "selenium-webdriver": "2.44.0", "minijasminenode": "1.1.1", "jasminewd": "1.1.0", + "jasminewd2": "0.0.2", + "jasmine": "2.1.1", "saucelabs": "~0.1.0", "glob": "~3.2", "adm-zip": "0.4.4", diff --git a/scripts/test.js b/scripts/test.js index 5581734f0..f18cd724d 100755 --- a/scripts/test.js +++ b/scripts/test.js @@ -1,7 +1,6 @@ #!/usr/bin/env node var Executor = require('./test/test_util').Executor; -var glob = require('glob').sync; var passingTests = [ 'node lib/cli.js spec/basicConf.js', @@ -26,14 +25,10 @@ var passingTests = [ 'node lib/cli.js spec/interactionConf.js', 'node lib/cli.js spec/directConnectConf.js', 'node lib/cli.js spec/restartBrowserBetweenTestsConf.js', - 'node lib/cli.js spec/getCapabilitiesConf.js' + 'node lib/cli.js spec/getCapabilitiesConf.js', + 'node node_modules/.bin/jasmine JASMINE_CONFIG_PATH=scripts/unit_test.json' ]; -passingTests.push( - 'node node_modules/minijasminenode/bin/minijn ' + - glob('spec/unit/*.js').join(' ') + ' ' + - glob('website/docgen/spec/*.js').join(' ')); - var executor = new Executor(); passingTests.forEach(function(passing_test) { @@ -56,7 +51,8 @@ executor.addCommandlineTest('node lib/cli.js spec/errorTest/singleFailureConf.js executor.addCommandlineTest('node lib/cli.js spec/errorTest/timeoutConf.js') .expectExitCode(1) .expectErrors({ - message: 'timeout: timed out after 1 msec waiting for spec to complete' + message: 'Timeout - Async callback was not invoked within timeout ' + + 'specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.' }) .expectTestDuration(0, 100); diff --git a/scripts/unit_test.json b/scripts/unit_test.json new file mode 100644 index 000000000..aa5e7bacd --- /dev/null +++ b/scripts/unit_test.json @@ -0,0 +1,7 @@ +{ + "spec_dir": "", + "spec_files": [ + "spec/unit/*.js", + "website/docgen/spec/*.js" + ] +} diff --git a/spec/altRootConf.js b/spec/altRootConf.js index 1422a70f0..1b9bd53f5 100644 --- a/spec/altRootConf.js +++ b/spec/altRootConf.js @@ -4,6 +4,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + // Spec patterns are relative to this config. specs: [ 'altRoot/*_spec.js', diff --git a/spec/basic/locators_spec.js b/spec/basic/locators_spec.js index 7e33c5e01..7388a5ea5 100644 --- a/spec/basic/locators_spec.js +++ b/spec/basic/locators_spec.js @@ -12,10 +12,16 @@ describe('locators', function() { it('should allow custom expectations to expect an element', function() { this.addMatchers({ - toHaveText: function(actualText) { - return this.actual.getText().then(function(expectedText) { - return expectedText === actualText; - }); + toHaveText: function() { + return { + compare: function(actual, expected) { + return { + pass: actual.getText().then(function(actual) { + return actual === expected; + }) + }; + } + }; } }); diff --git a/spec/basicConf.js b/spec/basicConf.js index 1a841574d..3509f76f7 100644 --- a/spec/basicConf.js +++ b/spec/basicConf.js @@ -4,6 +4,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + // Spec patterns are relative to this directory. specs: [ 'basic/*_spec.js' diff --git a/spec/ciConf.js b/spec/ciConf.js index 11b5c238c..4dfb2624b 100644 --- a/spec/ciConf.js +++ b/spec/ciConf.js @@ -5,6 +5,8 @@ exports.config = { sauceUser: process.env.SAUCE_USERNAME, sauceKey: process.env.SAUCE_ACCESS_KEY, + framework: 'jasmine2', + // Spec patterns are relative to this directory. specs: [ 'basic/*_spec.js' diff --git a/spec/directConnectConf.js b/spec/directConnectConf.js index b11aca79b..cc1155615 100644 --- a/spec/directConnectConf.js +++ b/spec/directConnectConf.js @@ -4,6 +4,8 @@ var env = require('./environment.js'); exports.config = { directConnect: true, + framework: 'jasmine2', + capabilities: { 'browserName': 'chrome' }, diff --git a/spec/errorTest/afterLaunchChangesExitCodeConf.js b/spec/errorTest/afterLaunchChangesExitCodeConf.js index 8ddb108fc..9d2de4f5d 100644 --- a/spec/errorTest/afterLaunchChangesExitCodeConf.js +++ b/spec/errorTest/afterLaunchChangesExitCodeConf.js @@ -3,6 +3,8 @@ var env = require('../environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + specs: [ 'baseCase/single_failure_spec1.js' ], diff --git a/spec/errorTest/multiFailureConf.js b/spec/errorTest/multiFailureConf.js index bfa64c2e3..32754268d 100644 --- a/spec/errorTest/multiFailureConf.js +++ b/spec/errorTest/multiFailureConf.js @@ -3,6 +3,8 @@ var env = require('../environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + specs: [ 'baseCase/single_failure_spec1.js', 'baseCase/single_failure_spec2.js' diff --git a/spec/errorTest/shardedFailureConf.js b/spec/errorTest/shardedFailureConf.js index f30e3b35d..accf79768 100644 --- a/spec/errorTest/shardedFailureConf.js +++ b/spec/errorTest/shardedFailureConf.js @@ -3,6 +3,8 @@ var env = require('../environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + specs: [ 'baseCase/single_failure_spec1.js', 'baseCase/single_failure_spec2.js' diff --git a/spec/errorTest/singleFailureConf.js b/spec/errorTest/singleFailureConf.js index e9a68ea8f..58e1bcdae 100644 --- a/spec/errorTest/singleFailureConf.js +++ b/spec/errorTest/singleFailureConf.js @@ -3,6 +3,8 @@ var env = require('../environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + specs: [ 'baseCase/single_failure_spec1.js' ], diff --git a/spec/errorTest/timeoutConf.js b/spec/errorTest/timeoutConf.js index 8e49d5cfb..f3da26b28 100644 --- a/spec/errorTest/timeoutConf.js +++ b/spec/errorTest/timeoutConf.js @@ -3,6 +3,8 @@ var env = require('../environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + specs: [ 'baseCase/timeout_spec.js' ], diff --git a/spec/interactionConf.js b/spec/interactionConf.js index 2ffe9cb04..c63353d47 100644 --- a/spec/interactionConf.js +++ b/spec/interactionConf.js @@ -4,6 +4,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + // Spec patterns are relative to this directory. specs: [ 'interaction/*_spec.js' diff --git a/spec/junitOutputConf.js b/spec/junitOutputConf.js index 25ea7b1b8..498e88091 100644 --- a/spec/junitOutputConf.js +++ b/spec/junitOutputConf.js @@ -8,6 +8,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + specs: [ 'basic/*_spec.js' ], diff --git a/spec/multiConf.js b/spec/multiConf.js index fc61bae1a..11bf5b8c3 100644 --- a/spec/multiConf.js +++ b/spec/multiConf.js @@ -4,6 +4,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + // Spec patterns are relative to this directory. specs: [ 'basic/lib_spec.js' diff --git a/spec/ngHintFailConfig.js b/spec/ngHintFailConfig.js index a80bee567..070021361 100644 --- a/spec/ngHintFailConfig.js +++ b/spec/ngHintFailConfig.js @@ -2,6 +2,7 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', specs: ['ngHint/fail_spec.js'], baseUrl: env.baseUrl, plugins: [{ diff --git a/spec/ngHintSuccessConfig.js b/spec/ngHintSuccessConfig.js index b4e847fbe..ade665b5a 100644 --- a/spec/ngHintSuccessConfig.js +++ b/spec/ngHintSuccessConfig.js @@ -2,6 +2,7 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', specs: ['ngHint/success_spec.js'], baseUrl: env.baseUrl, plugins: [{ diff --git a/spec/onCleanUpAsyncReturnValueConf.js b/spec/onCleanUpAsyncReturnValueConf.js index 24695dbf2..e481b03cf 100644 --- a/spec/onCleanUpAsyncReturnValueConf.js +++ b/spec/onCleanUpAsyncReturnValueConf.js @@ -5,6 +5,8 @@ var q = require('q'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + specs: [ 'onCleanUp/*_spec.js' ], diff --git a/spec/onCleanUpNoReturnValueConf.js b/spec/onCleanUpNoReturnValueConf.js index 6f31620af..2cf6e5161 100644 --- a/spec/onCleanUpNoReturnValueConf.js +++ b/spec/onCleanUpNoReturnValueConf.js @@ -4,6 +4,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + specs: [ 'onCleanUp/*_spec.js' ], diff --git a/spec/onCleanUpSyncReturnValueConf.js b/spec/onCleanUpSyncReturnValueConf.js index a0bf0549b..9b64fff5f 100644 --- a/spec/onCleanUpSyncReturnValueConf.js +++ b/spec/onCleanUpSyncReturnValueConf.js @@ -4,6 +4,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + specs: [ 'onCleanUp/*_spec.js' ], diff --git a/spec/onPrepareConf.js b/spec/onPrepareConf.js index 2b57b6634..1b3b5c705 100644 --- a/spec/onPrepareConf.js +++ b/spec/onPrepareConf.js @@ -6,6 +6,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + specs: [ 'onPrepare/*_spec.js' ], diff --git a/spec/onPrepareFileConf.js b/spec/onPrepareFileConf.js index f19175726..ffe0871aa 100644 --- a/spec/onPrepareFileConf.js +++ b/spec/onPrepareFileConf.js @@ -5,6 +5,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + // Spec patterns are relative to this directory. specs: [ 'onPrepare/*_spec.js' diff --git a/spec/onPreparePromiseConf.js b/spec/onPreparePromiseConf.js index 6f664a2f6..379d289d5 100644 --- a/spec/onPreparePromiseConf.js +++ b/spec/onPreparePromiseConf.js @@ -7,6 +7,8 @@ var q = require('q'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + specs: [ 'onPrepare/*_spec.js' ], diff --git a/spec/onPreparePromiseFileConf.js b/spec/onPreparePromiseFileConf.js index d19da5dd0..51ba3242f 100644 --- a/spec/onPreparePromiseFileConf.js +++ b/spec/onPreparePromiseFileConf.js @@ -5,6 +5,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + // Spec patterns are relative to this directory. specs: [ 'onPrepare/*_spec.js' diff --git a/spec/pluginsBasicConf.js b/spec/pluginsBasicConf.js index 6b72620eb..e10e2f99b 100644 --- a/spec/pluginsBasicConf.js +++ b/spec/pluginsBasicConf.js @@ -5,6 +5,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + // Spec patterns are relative to this directory. specs: [ 'plugins/basic_spec.js' diff --git a/spec/pluginsFullConf.js b/spec/pluginsFullConf.js index 307752498..2ae7b8d57 100644 --- a/spec/pluginsFullConf.js +++ b/spec/pluginsFullConf.js @@ -4,6 +4,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + // Spec patterns are relative to this directory. specs: [ 'plugins/basic_spec.js' diff --git a/spec/restartBrowserBetweenTestsConf.js b/spec/restartBrowserBetweenTestsConf.js index 4d0bc1454..c1c3c2467 100644 --- a/spec/restartBrowserBetweenTestsConf.js +++ b/spec/restartBrowserBetweenTestsConf.js @@ -4,6 +4,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + // Spec patterns are relative to this directory. specs: [ 'restartBrowserBetweenTests/*_spec.js' diff --git a/spec/smokeConf.js b/spec/smokeConf.js index 1937070db..46997f3c9 100644 --- a/spec/smokeConf.js +++ b/spec/smokeConf.js @@ -6,6 +6,8 @@ exports.config = { sauceUser: process.env.SAUCE_USERNAME, sauceKey: process.env.SAUCE_ACCESS_KEY, + framework: 'jasmine2', + specs: [ 'basic/locators_spec.js', 'basic/mockmodule_spec.js', diff --git a/spec/suitesConf.js b/spec/suitesConf.js index 972d53b88..303e344cf 100644 --- a/spec/suitesConf.js +++ b/spec/suitesConf.js @@ -3,6 +3,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + // Spec patterns are relative to this directory. suites: { okspec: 'suites/ok_spec.js', diff --git a/spec/unit/config_test.js b/spec/unit/config_test.js index 6dccb2cb9..15c655657 100644 --- a/spec/unit/config_test.js +++ b/spec/unit/config_test.js @@ -41,7 +41,7 @@ describe('the config parser', function() { describe('resolving globs', function() { it('should resolve relative to the cwd', function() { - spyOn(process, 'cwd').andReturn(__dirname + '/'); + spyOn(process, 'cwd').and.returnValue(__dirname + '/'); var toAdd = { specs: 'data/*spec[AB].js' }; diff --git a/spec/withLoginConf.js b/spec/withLoginConf.js index fbb31e3c5..1607afc82 100644 --- a/spec/withLoginConf.js +++ b/spec/withLoginConf.js @@ -5,6 +5,8 @@ var env = require('./environment.js'); exports.config = { seleniumAddress: env.seleniumAddress, + framework: 'jasmine2', + specs: [ 'login/login_spec.js' ],