jasmine-browser-runner 0.7.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -9
- package/bin/jasmine-browser-runner +6 -2
- package/config.js.ejs +1 -0
- package/index.js +50 -28
- package/lib/command.js +46 -19
- package/lib/config.js +20 -20
- package/lib/console_reporter.js +311 -0
- package/lib/examples/default_config.json +21 -0
- package/lib/examples/default_esm_config.json +19 -0
- package/lib/jasmineCore.js +11 -0
- package/lib/runner.js +1 -33
- package/lib/server.js +46 -26
- package/lib/types.js +24 -12
- package/lib/usage_error.js +9 -0
- package/package.json +18 -15
- package/run.html.ejs +2 -2
- package/lib/default_reporter.js +0 -19
- package/lib/support/jsonDomReporter.js +0 -45
package/README.md
CHANGED
|
@@ -8,13 +8,13 @@ using either headless Chrome or Saucelabs.
|
|
|
8
8
|
# Getting started
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
-
npm install --save-dev jasmine-browser-runner
|
|
11
|
+
npm install --save-dev jasmine-browser-runner jasmine-core
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
or
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
yarn add -D jasmine-browser-runner
|
|
17
|
+
yarn add -D jasmine-browser-runner jasmine-core
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
Add a `spec/support/jasmine-browser.json`. For example:
|
|
@@ -60,18 +60,95 @@ To use a browser other than Firefox, add a `browser` field to
|
|
|
60
60
|
}
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
Its value can be `"
|
|
63
|
+
Its value can be `"firefox"`, `"safari"`,
|
|
64
64
|
`"MicrosoftEdge"`, `"chrome"`, or `"headlessChrome"`.
|
|
65
65
|
|
|
66
66
|
## ES module support
|
|
67
67
|
|
|
68
68
|
If a source, spec, or helper file's name ends in `.mjs`, it will be loaded as
|
|
69
|
-
an ES module rather than a regular script.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
an ES module rather than a regular script.
|
|
70
|
+
|
|
71
|
+
To allow spec files to import source files via relative paths, set the `specDir`
|
|
72
|
+
config field to something that's high enough up to include both spec and source
|
|
73
|
+
files, and set `srcFiles` to `[]`. You can autogenerate such a configuration by
|
|
74
|
+
running `npx jasmine-browser-runner init --esm`.
|
|
75
|
+
|
|
76
|
+
## Use with Rails
|
|
77
|
+
|
|
78
|
+
You can use jasmine-browser-runner to test your Rails application's JavaScript,
|
|
79
|
+
whether you use the Asset Pipeline or Webpacker.
|
|
80
|
+
|
|
81
|
+
### Webpacker
|
|
82
|
+
|
|
83
|
+
1. Run `yarn add --dev jasmine-browser-runner`.
|
|
84
|
+
2. Run `npx jasmine-browser-runner init`.
|
|
85
|
+
3. Edit `spec/support/jasmine-browser.json` as follows:
|
|
86
|
+
```
|
|
87
|
+
{
|
|
88
|
+
"srcDir": ".",
|
|
89
|
+
"srcFiles": [],
|
|
90
|
+
"specDir": "public/packs/js",
|
|
91
|
+
"specFiles": [
|
|
92
|
+
"specs-*.js"
|
|
93
|
+
],
|
|
94
|
+
"helpers": [],
|
|
95
|
+
// ...
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
4. Create `app/javascript/packs/specs.js` (or `app/javascript/packs/specs.jsx`
|
|
99
|
+
if you use JSX) as follows:
|
|
100
|
+
```
|
|
101
|
+
(function() {
|
|
102
|
+
'use strict';
|
|
103
|
+
|
|
104
|
+
function requireAll(context) {
|
|
105
|
+
context.keys().forEach(context);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
requireAll(require.context('spec/javascript/helpers/', true, /\.js/));
|
|
109
|
+
requireAll(require.context('spec/javascript/', true, /[sS]pec\.js/));
|
|
110
|
+
})();
|
|
111
|
+
```
|
|
112
|
+
5. Add `'spec/javascript'` to the `additional_paths` array in `config/webpacker.yml`.
|
|
113
|
+
6. Put your spec files in `spec/javascript`.
|
|
114
|
+
|
|
115
|
+
To run the specs:
|
|
116
|
+
|
|
117
|
+
1. Run `bin/webpack --watch`.
|
|
118
|
+
2. Run `npx jasmine-browser-runner`.
|
|
119
|
+
3. visit <http://localhost:8888>.
|
|
120
|
+
|
|
121
|
+
### Asset Pipeline
|
|
122
|
+
|
|
123
|
+
1. Run `yarn init` if there isn't already `package.json` file in the root of
|
|
124
|
+
the Rails application.
|
|
125
|
+
2. Run `yarn add --dev jasmine-browser-runner`.
|
|
126
|
+
3. Run `npx jasmine-browser-runner init`.
|
|
127
|
+
5. Edit `spec/support/jasmine-browser.json` as follows:
|
|
128
|
+
```
|
|
129
|
+
{
|
|
130
|
+
"srcDir": "public/assets",
|
|
131
|
+
"srcFiles": [
|
|
132
|
+
"application-*.js"
|
|
133
|
+
],
|
|
134
|
+
"specDir": "spec/javascript",
|
|
135
|
+
"specFiles": [
|
|
136
|
+
"**/*[sS]pec.?(m)js"
|
|
137
|
+
],
|
|
138
|
+
"helpers": [
|
|
139
|
+
"helpers/**/*.?(m)js"
|
|
140
|
+
],
|
|
141
|
+
// ...
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
6. Put your spec files in `spec/javascript`.
|
|
145
|
+
|
|
146
|
+
To run the specs:
|
|
147
|
+
|
|
148
|
+
1. Either run `bundle exec rake assets:precompile` or start the Rails
|
|
149
|
+
application in an environment that's configured to precompile assets.
|
|
150
|
+
2. Run `npx jasmine-browser-runner`.
|
|
151
|
+
3. Visit <http://localhost:8888>.
|
|
75
152
|
|
|
76
153
|
## Saucelabs support
|
|
77
154
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
var path = require('path'),
|
|
4
|
-
jasmineCore = require('
|
|
4
|
+
jasmineCore = require('../lib/jasmineCore'),
|
|
5
5
|
Command = require('../lib/command'),
|
|
6
6
|
jasmineBrowser = require('../index.js');
|
|
7
|
+
const UsageError = require('../lib/usage_error');
|
|
7
8
|
|
|
8
9
|
var command = new Command({
|
|
9
10
|
baseDir: path.resolve(),
|
|
@@ -13,6 +14,9 @@ var command = new Command({
|
|
|
13
14
|
});
|
|
14
15
|
|
|
15
16
|
command.run(process.argv.slice(2)).catch(function(error) {
|
|
16
|
-
|
|
17
|
+
if (!(error instanceof UsageError)) {
|
|
18
|
+
console.error(error);
|
|
19
|
+
}
|
|
20
|
+
|
|
17
21
|
process.exitCode = 1;
|
|
18
22
|
});
|
package/config.js.ejs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
jasmine.getEnv().configure(<%- JSON.stringify(envConfig) %>);
|
package/index.js
CHANGED
|
@@ -1,34 +1,46 @@
|
|
|
1
|
-
const
|
|
1
|
+
const ConsoleReporter = require('./lib/console_reporter'),
|
|
2
2
|
webdriverModule = require('./lib/webdriver'),
|
|
3
3
|
Server = require('./lib/server'),
|
|
4
4
|
Runner = require('./lib/runner'),
|
|
5
5
|
ModuleLoader = require('./lib/moduleLoader');
|
|
6
6
|
|
|
7
7
|
async function createReporters(options) {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
const result = [];
|
|
9
|
+
|
|
10
|
+
if (options.useConsoleReporter !== false) {
|
|
11
|
+
const consoleReporter = new ConsoleReporter();
|
|
12
|
+
consoleReporter.setOptions({ color: options.color });
|
|
13
|
+
result.push(consoleReporter);
|
|
10
14
|
}
|
|
11
15
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
if (options.reporters) {
|
|
17
|
+
// Resolve relative paths relative to the cwd, rather than the default
|
|
18
|
+
// which is the directory containing the moduleLoader module.
|
|
19
|
+
const loader = new ModuleLoader(process.cwd());
|
|
20
|
+
|
|
21
|
+
for (const reporterOrModuleName of options.reporters) {
|
|
22
|
+
if (typeof reporterOrModuleName === 'object') {
|
|
23
|
+
result.push(reporterOrModuleName);
|
|
24
|
+
} else {
|
|
25
|
+
try {
|
|
26
|
+
const Reporter = await loader.load(reporterOrModuleName);
|
|
27
|
+
result.push(new Reporter());
|
|
28
|
+
} catch (e) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`Failed to register reporter ${reporterOrModuleName}: ${e.message}`
|
|
31
|
+
);
|
|
32
|
+
}
|
|
28
33
|
}
|
|
29
34
|
}
|
|
30
35
|
}
|
|
31
36
|
|
|
37
|
+
if (result.length === 0) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
'No reporters were specified. Either add a reporter or remove ' +
|
|
40
|
+
'`useConsoleReporter: false`.'
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
32
44
|
return result;
|
|
33
45
|
}
|
|
34
46
|
|
|
@@ -49,17 +61,11 @@ module.exports = {
|
|
|
49
61
|
},
|
|
50
62
|
/**
|
|
51
63
|
* Runs the specs.
|
|
52
|
-
* @param {
|
|
64
|
+
* @param {Configuration} options
|
|
53
65
|
* @return {Promise<JasmineDoneInfo>} A promise that resolves to the {@link https://jasmine.github.io/api/edge/global.html#JasmineDoneInfo|overall result} when the suite has finished running.
|
|
54
66
|
*/
|
|
55
67
|
runSpecs: async function(options, deps) {
|
|
56
68
|
options = options || {};
|
|
57
|
-
if (options.browser && options.browser.name === 'internet explorer') {
|
|
58
|
-
options.jsonDomReporter = true;
|
|
59
|
-
} else {
|
|
60
|
-
options.batchReporter = true;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
69
|
deps = deps || {};
|
|
64
70
|
const ServerClass = deps.Server || Server;
|
|
65
71
|
const RunnerClass = deps.Runner || Runner;
|
|
@@ -84,12 +90,19 @@ module.exports = {
|
|
|
84
90
|
|
|
85
91
|
const details = await runner.run(options);
|
|
86
92
|
|
|
93
|
+
// Use 0 only for complete success
|
|
94
|
+
// Avoid 1 because Node uses that for unhandled exceptions etc., and
|
|
95
|
+
// some users have CI systems that want to distinguish between spec
|
|
96
|
+
// failures and crashes.
|
|
87
97
|
if (details.overallStatus === 'passed') {
|
|
88
98
|
setExitCode(0);
|
|
99
|
+
} else if (anyLoadErrors(details)) {
|
|
100
|
+
// Use node's general failure code
|
|
101
|
+
setExitCode(1);
|
|
89
102
|
} else if (details.overallStatus === 'incomplete') {
|
|
90
103
|
setExitCode(2);
|
|
91
104
|
} else {
|
|
92
|
-
setExitCode(
|
|
105
|
+
setExitCode(3);
|
|
93
106
|
}
|
|
94
107
|
|
|
95
108
|
return details;
|
|
@@ -108,5 +121,14 @@ module.exports = {
|
|
|
108
121
|
},
|
|
109
122
|
Server,
|
|
110
123
|
Runner,
|
|
111
|
-
|
|
124
|
+
ConsoleReporter,
|
|
112
125
|
};
|
|
126
|
+
|
|
127
|
+
function anyLoadErrors(jasmineDoneInfo) {
|
|
128
|
+
const failures = jasmineDoneInfo.failedExpectations || [];
|
|
129
|
+
const loadError = failures.find(function(fe) {
|
|
130
|
+
return fe.globalErrorType === 'load';
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
return !!loadError;
|
|
134
|
+
}
|
package/lib/command.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fs = require('fs');
|
|
3
|
-
const {
|
|
3
|
+
const {
|
|
4
|
+
loadConfig,
|
|
5
|
+
validateConfig,
|
|
6
|
+
defaultConfig,
|
|
7
|
+
defaultEsmConfig,
|
|
8
|
+
} = require('./config');
|
|
9
|
+
const UsageError = require('./usage_error');
|
|
4
10
|
|
|
5
11
|
const commonOptions = [
|
|
6
12
|
{ name: 'config', type: 'string', description: 'path to the config file' },
|
|
7
|
-
{
|
|
8
|
-
name: 'clear-reporters',
|
|
9
|
-
type: 'bool',
|
|
10
|
-
description: 'clear default reporters in the HTML page',
|
|
11
|
-
},
|
|
12
13
|
{ name: 'port', type: 'number', description: 'port to run the server on' },
|
|
13
14
|
];
|
|
14
15
|
|
|
@@ -22,6 +23,14 @@ const subCommands = [
|
|
|
22
23
|
{
|
|
23
24
|
name: 'init',
|
|
24
25
|
description: 'initialize a new Jasmine project',
|
|
26
|
+
options: [
|
|
27
|
+
{
|
|
28
|
+
name: 'esm',
|
|
29
|
+
type: 'bool',
|
|
30
|
+
description:
|
|
31
|
+
'configure for use with ES modules (<script type="module">)',
|
|
32
|
+
},
|
|
33
|
+
],
|
|
25
34
|
},
|
|
26
35
|
{
|
|
27
36
|
name: 'serve',
|
|
@@ -35,6 +44,7 @@ const subCommands = [
|
|
|
35
44
|
{
|
|
36
45
|
name: 'color',
|
|
37
46
|
type: 'bool',
|
|
47
|
+
reversable: true,
|
|
38
48
|
description: 'turn on or off color output',
|
|
39
49
|
},
|
|
40
50
|
{
|
|
@@ -43,19 +53,15 @@ const subCommands = [
|
|
|
43
53
|
description:
|
|
44
54
|
'filter specs to run only those that match the given string',
|
|
45
55
|
},
|
|
46
|
-
{
|
|
47
|
-
name: 'stop-on-failure',
|
|
48
|
-
type: 'bool',
|
|
49
|
-
description: 'stop spec execution on expectation failure',
|
|
50
|
-
},
|
|
51
56
|
{
|
|
52
57
|
name: 'fail-fast',
|
|
53
58
|
type: 'bool',
|
|
54
|
-
description: 'stop Jasmine execution on
|
|
59
|
+
description: 'stop Jasmine execution on the first failure',
|
|
55
60
|
},
|
|
56
61
|
{
|
|
57
62
|
name: 'random',
|
|
58
63
|
type: 'bool',
|
|
64
|
+
reversable: true,
|
|
59
65
|
description: 'turn on or off randomization',
|
|
60
66
|
},
|
|
61
67
|
{
|
|
@@ -91,7 +97,8 @@ class Command {
|
|
|
91
97
|
});
|
|
92
98
|
|
|
93
99
|
if (!toRun) {
|
|
94
|
-
|
|
100
|
+
this.help();
|
|
101
|
+
throw new UsageError();
|
|
95
102
|
} else if (toRun.options) {
|
|
96
103
|
return this[toRun.name](parseOptions(toRun, args.slice(1)));
|
|
97
104
|
} else {
|
|
@@ -141,7 +148,7 @@ class Command {
|
|
|
141
148
|
this._logger.log('jasmine-core v' + this._config.jasmineCore.version());
|
|
142
149
|
}
|
|
143
150
|
|
|
144
|
-
init() {
|
|
151
|
+
init(options) {
|
|
145
152
|
const dest = 'spec/support/jasmine-browser.json';
|
|
146
153
|
|
|
147
154
|
if (fs.existsSync(dest)) {
|
|
@@ -150,7 +157,13 @@ class Command {
|
|
|
150
157
|
}
|
|
151
158
|
|
|
152
159
|
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
153
|
-
|
|
160
|
+
|
|
161
|
+
if (options.esm) {
|
|
162
|
+
fs.writeFileSync(dest, defaultEsmConfig());
|
|
163
|
+
} else {
|
|
164
|
+
fs.writeFileSync(dest, defaultConfig());
|
|
165
|
+
}
|
|
166
|
+
|
|
154
167
|
this._logger.log(`Wrote configuration to ${dest}.`);
|
|
155
168
|
}
|
|
156
169
|
|
|
@@ -161,7 +174,17 @@ class Command {
|
|
|
161
174
|
}
|
|
162
175
|
|
|
163
176
|
async runSpecs(options) {
|
|
164
|
-
|
|
177
|
+
const config = await this._loadConfig(options);
|
|
178
|
+
|
|
179
|
+
if (options['fail-fast']) {
|
|
180
|
+
config.env = {
|
|
181
|
+
...config.env,
|
|
182
|
+
stopSpecOnExpectationFailure: true,
|
|
183
|
+
stopOnSpecFailure: true,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
await this._config.jasmineBrowser.runSpecs(config);
|
|
165
188
|
}
|
|
166
189
|
|
|
167
190
|
async _loadConfig(options) {
|
|
@@ -210,9 +233,13 @@ function commandText(command) {
|
|
|
210
233
|
}
|
|
211
234
|
|
|
212
235
|
function optionText(option) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
236
|
+
if (option.type !== 'bool') {
|
|
237
|
+
return `--${option.name}=<value>`;
|
|
238
|
+
} else if (option.reversable) {
|
|
239
|
+
return `--[no-]${option.name}`;
|
|
240
|
+
} else {
|
|
241
|
+
return `--${option.name}`;
|
|
242
|
+
}
|
|
216
243
|
}
|
|
217
244
|
|
|
218
245
|
function wrapDescription(indentLevel, prefixWidth, maxWidth, text) {
|
package/lib/config.js
CHANGED
|
@@ -52,24 +52,24 @@ function validateConfig(config) {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
'
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
' "stopSpecOnExpectationFailure": false,\n' +
|
|
70
|
-
' "browser": {\n' +
|
|
71
|
-
' "name": "firefox"\n' +
|
|
72
|
-
' }\n' +
|
|
73
|
-
'}';
|
|
55
|
+
function defaultConfig() {
|
|
56
|
+
return fs.readFileSync(require.resolve('./examples/default_config.json'), {
|
|
57
|
+
encoding: 'utf8',
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function defaultEsmConfig() {
|
|
62
|
+
return fs.readFileSync(
|
|
63
|
+
require.resolve('./examples/default_esm_config.json'),
|
|
64
|
+
{
|
|
65
|
+
encoding: 'utf8',
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
}
|
|
74
69
|
|
|
75
|
-
module.exports = {
|
|
70
|
+
module.exports = {
|
|
71
|
+
loadConfig,
|
|
72
|
+
validateConfig,
|
|
73
|
+
defaultConfig,
|
|
74
|
+
defaultEsmConfig,
|
|
75
|
+
};
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
const util = require('util');
|
|
2
|
+
module.exports = exports = ConsoleReporter;
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @classdesc A reporter that prints spec and suite results to the console.
|
|
6
|
+
* A ConsoleReporter is installed unless {@link Configuration#useConsoleReporter}
|
|
7
|
+
* is set to false.
|
|
8
|
+
*
|
|
9
|
+
* @constructor
|
|
10
|
+
* @example
|
|
11
|
+
* const {ConsoleReporter} = require('jasmine');
|
|
12
|
+
* const reporter = new ConsoleReporter();
|
|
13
|
+
*/
|
|
14
|
+
function ConsoleReporter() {
|
|
15
|
+
let print = function() {
|
|
16
|
+
process.stdout.write(util.format.apply(this, arguments));
|
|
17
|
+
},
|
|
18
|
+
showColors = true,
|
|
19
|
+
jasmineCorePath = null,
|
|
20
|
+
specCount,
|
|
21
|
+
executableSpecCount,
|
|
22
|
+
failureCount,
|
|
23
|
+
failedSpecs = [],
|
|
24
|
+
pendingSpecs = [],
|
|
25
|
+
ansi = {
|
|
26
|
+
green: '\x1B[32m',
|
|
27
|
+
red: '\x1B[31m',
|
|
28
|
+
yellow: '\x1B[33m',
|
|
29
|
+
none: '\x1B[0m',
|
|
30
|
+
},
|
|
31
|
+
failedSuites = [],
|
|
32
|
+
stackFilter = defaultStackFilter;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Configures the reporter.
|
|
36
|
+
* @function
|
|
37
|
+
* @name ConsoleReporter#setOptions
|
|
38
|
+
* @param {ConsoleReporterOptions} options
|
|
39
|
+
*/
|
|
40
|
+
this.setOptions = function(options) {
|
|
41
|
+
if (options.print) {
|
|
42
|
+
print = options.print;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @interface ConsoleReporterOptions
|
|
47
|
+
*/
|
|
48
|
+
/**
|
|
49
|
+
* Whether to colorize the output
|
|
50
|
+
* @name ConsoleReporterOptions#color
|
|
51
|
+
* @type Boolean|undefined
|
|
52
|
+
* @default true
|
|
53
|
+
*/
|
|
54
|
+
if (options.color !== undefined) {
|
|
55
|
+
showColors = options.color;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (options.jasmineCorePath) {
|
|
59
|
+
jasmineCorePath = options.jasmineCorePath;
|
|
60
|
+
}
|
|
61
|
+
if (options.stackFilter) {
|
|
62
|
+
stackFilter = options.stackFilter;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
this.jasmineStarted = function(options) {
|
|
67
|
+
specCount = 0;
|
|
68
|
+
executableSpecCount = 0;
|
|
69
|
+
failureCount = 0;
|
|
70
|
+
if (options && options.order && options.order.random) {
|
|
71
|
+
print('Randomized with seed ' + options.order.seed);
|
|
72
|
+
printNewline();
|
|
73
|
+
}
|
|
74
|
+
print('Started');
|
|
75
|
+
printNewline();
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
this.jasmineDone = function(result) {
|
|
79
|
+
if (result.failedExpectations) {
|
|
80
|
+
failureCount += result.failedExpectations.length;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
printNewline();
|
|
84
|
+
printNewline();
|
|
85
|
+
if (failedSpecs.length > 0) {
|
|
86
|
+
print('Failures:');
|
|
87
|
+
}
|
|
88
|
+
for (let i = 0; i < failedSpecs.length; i++) {
|
|
89
|
+
specFailureDetails(failedSpecs[i], i + 1);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
for (let i = 0; i < failedSuites.length; i++) {
|
|
93
|
+
suiteFailureDetails(failedSuites[i]);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (
|
|
97
|
+
result &&
|
|
98
|
+
result.failedExpectations &&
|
|
99
|
+
result.failedExpectations.length > 0
|
|
100
|
+
) {
|
|
101
|
+
suiteFailureDetails(result);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (pendingSpecs.length > 0) {
|
|
105
|
+
print('Pending:');
|
|
106
|
+
}
|
|
107
|
+
for (let i = 0; i < pendingSpecs.length; i++) {
|
|
108
|
+
pendingSpecDetails(pendingSpecs[i], i + 1);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (specCount > 0) {
|
|
112
|
+
printNewline();
|
|
113
|
+
|
|
114
|
+
if (executableSpecCount !== specCount) {
|
|
115
|
+
print(
|
|
116
|
+
'Ran ' +
|
|
117
|
+
executableSpecCount +
|
|
118
|
+
' of ' +
|
|
119
|
+
specCount +
|
|
120
|
+
plural(' spec', specCount)
|
|
121
|
+
);
|
|
122
|
+
printNewline();
|
|
123
|
+
}
|
|
124
|
+
let specCounts =
|
|
125
|
+
executableSpecCount +
|
|
126
|
+
' ' +
|
|
127
|
+
plural('spec', executableSpecCount) +
|
|
128
|
+
', ' +
|
|
129
|
+
failureCount +
|
|
130
|
+
' ' +
|
|
131
|
+
plural('failure', failureCount);
|
|
132
|
+
|
|
133
|
+
if (pendingSpecs.length) {
|
|
134
|
+
specCounts +=
|
|
135
|
+
', ' +
|
|
136
|
+
pendingSpecs.length +
|
|
137
|
+
' pending ' +
|
|
138
|
+
plural('spec', pendingSpecs.length);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
print(specCounts);
|
|
142
|
+
} else {
|
|
143
|
+
print('No specs found');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
printNewline();
|
|
147
|
+
const seconds = result ? result.totalTime / 1000 : 0;
|
|
148
|
+
print('Finished in ' + seconds + ' ' + plural('second', seconds));
|
|
149
|
+
printNewline();
|
|
150
|
+
|
|
151
|
+
if (result && result.overallStatus === 'incomplete') {
|
|
152
|
+
print('Incomplete: ' + result.incompleteReason);
|
|
153
|
+
printNewline();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (result && result.order && result.order.random) {
|
|
157
|
+
print('Randomized with seed ' + result.order.seed);
|
|
158
|
+
print(
|
|
159
|
+
' (jasmine-browser-runner runSpecs --seed=' + result.order.seed + ')'
|
|
160
|
+
);
|
|
161
|
+
printNewline();
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
this.specDone = function(result) {
|
|
166
|
+
specCount++;
|
|
167
|
+
|
|
168
|
+
if (result.status == 'pending') {
|
|
169
|
+
pendingSpecs.push(result);
|
|
170
|
+
executableSpecCount++;
|
|
171
|
+
print(colored('yellow', '*'));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (result.status == 'passed') {
|
|
176
|
+
executableSpecCount++;
|
|
177
|
+
print(colored('green', '.'));
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (result.status == 'failed') {
|
|
182
|
+
failureCount++;
|
|
183
|
+
failedSpecs.push(result);
|
|
184
|
+
executableSpecCount++;
|
|
185
|
+
print(colored('red', 'F'));
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
this.suiteDone = function(result) {
|
|
190
|
+
if (result.failedExpectations && result.failedExpectations.length > 0) {
|
|
191
|
+
failureCount++;
|
|
192
|
+
failedSuites.push(result);
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
return this;
|
|
197
|
+
|
|
198
|
+
function printNewline() {
|
|
199
|
+
print('\n');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function colored(color, str) {
|
|
203
|
+
return showColors ? ansi[color] + str + ansi.none : str;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function plural(str, count) {
|
|
207
|
+
return count == 1 ? str : str + 's';
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function repeat(thing, times) {
|
|
211
|
+
const arr = [];
|
|
212
|
+
for (let i = 0; i < times; i++) {
|
|
213
|
+
arr.push(thing);
|
|
214
|
+
}
|
|
215
|
+
return arr;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function indent(str, spaces) {
|
|
219
|
+
const lines = (str || '').split('\n');
|
|
220
|
+
const newArr = [];
|
|
221
|
+
for (let i = 0; i < lines.length; i++) {
|
|
222
|
+
newArr.push(repeat(' ', spaces).join('') + lines[i]);
|
|
223
|
+
}
|
|
224
|
+
return newArr.join('\n');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function defaultStackFilter(stack) {
|
|
228
|
+
if (!stack) {
|
|
229
|
+
return '';
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const filteredStack = stack
|
|
233
|
+
.split('\n')
|
|
234
|
+
.filter(function(stackLine) {
|
|
235
|
+
return stackLine.indexOf(jasmineCorePath) === -1;
|
|
236
|
+
})
|
|
237
|
+
.join('\n');
|
|
238
|
+
return filteredStack;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function specFailureDetails(result, failedSpecNumber) {
|
|
242
|
+
printNewline();
|
|
243
|
+
print(failedSpecNumber + ') ');
|
|
244
|
+
print(result.fullName);
|
|
245
|
+
printFailedExpectations(result);
|
|
246
|
+
|
|
247
|
+
if (result.debugLogs) {
|
|
248
|
+
printNewline();
|
|
249
|
+
print(indent('Debug logs:', 2));
|
|
250
|
+
printNewline();
|
|
251
|
+
|
|
252
|
+
for (const entry of result.debugLogs) {
|
|
253
|
+
print(indent(`${entry.timestamp}ms: ${entry.message}`, 4));
|
|
254
|
+
printNewline();
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function suiteFailureDetails(result) {
|
|
260
|
+
printNewline();
|
|
261
|
+
print('Suite error: ' + result.fullName);
|
|
262
|
+
printFailedExpectations(result);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function printFailedExpectations(result) {
|
|
266
|
+
for (let i = 0; i < result.failedExpectations.length; i++) {
|
|
267
|
+
const failedExpectation = result.failedExpectations[i];
|
|
268
|
+
printNewline();
|
|
269
|
+
print(indent('Message:', 2));
|
|
270
|
+
printNewline();
|
|
271
|
+
print(colored('red', indent(failedExpectation.message, 4)));
|
|
272
|
+
printNewline();
|
|
273
|
+
print(indent('Stack:', 2));
|
|
274
|
+
printNewline();
|
|
275
|
+
print(indent(stackFilter(failedExpectation.stack), 4));
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// When failSpecWithNoExpectations = true and a spec fails because of no expectations found,
|
|
279
|
+
// jasmine-core reports it as a failure with no message.
|
|
280
|
+
//
|
|
281
|
+
// Therefore we assume that when there are no failed or passed expectations,
|
|
282
|
+
// the failure was because of our failSpecWithNoExpectations setting.
|
|
283
|
+
//
|
|
284
|
+
// Same logic is used by jasmine.HtmlReporter, see https://github.com/jasmine/jasmine/blob/main/src/html/HtmlReporter.js
|
|
285
|
+
if (
|
|
286
|
+
result.failedExpectations.length === 0 &&
|
|
287
|
+
result.passedExpectations.length === 0
|
|
288
|
+
) {
|
|
289
|
+
printNewline();
|
|
290
|
+
print(indent('Message:', 2));
|
|
291
|
+
printNewline();
|
|
292
|
+
print(colored('red', indent('Spec has no expectations', 4)));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
printNewline();
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function pendingSpecDetails(result, pendingSpecNumber) {
|
|
299
|
+
printNewline();
|
|
300
|
+
printNewline();
|
|
301
|
+
print(pendingSpecNumber + ') ');
|
|
302
|
+
print(result.fullName);
|
|
303
|
+
printNewline();
|
|
304
|
+
let pendingReason = 'No reason given';
|
|
305
|
+
if (result.pendingReason && result.pendingReason !== '') {
|
|
306
|
+
pendingReason = result.pendingReason;
|
|
307
|
+
}
|
|
308
|
+
print(indent(colored('yellow', pendingReason), 2));
|
|
309
|
+
printNewline();
|
|
310
|
+
}
|
|
311
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"srcDir": "src",
|
|
3
|
+
"srcFiles": [
|
|
4
|
+
"**/*.js"
|
|
5
|
+
],
|
|
6
|
+
"specDir": "spec",
|
|
7
|
+
"specFiles": [
|
|
8
|
+
"**/*[sS]pec.js"
|
|
9
|
+
],
|
|
10
|
+
"helpers": [
|
|
11
|
+
"helpers/**/*.js"
|
|
12
|
+
],
|
|
13
|
+
"env": {
|
|
14
|
+
"stopSpecOnExpectationFailure": false,
|
|
15
|
+
"stopOnSpecFailure": false,
|
|
16
|
+
"random": true
|
|
17
|
+
},
|
|
18
|
+
"browser": {
|
|
19
|
+
"name": "firefox"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"srcDir": "src",
|
|
3
|
+
"srcFiles": [],
|
|
4
|
+
"specDir": ".",
|
|
5
|
+
"specFiles": [
|
|
6
|
+
"spec/**/*[sS]pec.?(m)js"
|
|
7
|
+
],
|
|
8
|
+
"helpers": [
|
|
9
|
+
"spec/helpers/**/*.?(m)js"
|
|
10
|
+
],
|
|
11
|
+
"env": {
|
|
12
|
+
"stopSpecOnExpectationFailure": false,
|
|
13
|
+
"stopOnSpecFailure": false,
|
|
14
|
+
"random": true
|
|
15
|
+
},
|
|
16
|
+
"browser": {
|
|
17
|
+
"name": "firefox"
|
|
18
|
+
}
|
|
19
|
+
}
|
package/lib/runner.js
CHANGED
|
@@ -18,22 +18,6 @@ function getBatch(driver) {
|
|
|
18
18
|
);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
async function jsDomReporterResults(webdriver) {
|
|
22
|
-
const resultsEl = await new Promise(function(resolve) {
|
|
23
|
-
function poll() {
|
|
24
|
-
webdriver.findElement({ id: 'jasmine-jsonDomReporter-done' }).then(
|
|
25
|
-
el => resolve(el),
|
|
26
|
-
() => setTimeout(poll, 1000)
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
poll();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const text = await resultsEl.getText();
|
|
34
|
-
return JSON.parse(text);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
21
|
function proxyToReporters(batch, reporters) {
|
|
38
22
|
batch.forEach(function(result) {
|
|
39
23
|
const fn = result[0];
|
|
@@ -91,8 +75,6 @@ function urlParams(runOptions) {
|
|
|
91
75
|
filterUndefined({
|
|
92
76
|
random: runOptions.random,
|
|
93
77
|
seed: runOptions.seed,
|
|
94
|
-
failFast: runOptions.failFast,
|
|
95
|
-
throwFailures: runOptions.stopOnFailure,
|
|
96
78
|
spec: runOptions.filter,
|
|
97
79
|
})
|
|
98
80
|
)
|
|
@@ -122,21 +104,7 @@ class Runner {
|
|
|
122
104
|
this._options.host + urlParams(runOptions)
|
|
123
105
|
);
|
|
124
106
|
|
|
125
|
-
|
|
126
|
-
console.log(
|
|
127
|
-
"Note: Results won't be shown until the entire suite has finished running."
|
|
128
|
-
);
|
|
129
|
-
let results = await jsDomReporterResults(this._options.webdriver);
|
|
130
|
-
proxyToReporters(results, this._options.reporters);
|
|
131
|
-
|
|
132
|
-
if (!isDone(results)) {
|
|
133
|
-
throw new Error("Didn't find a jasmineDone event");
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return runDetails(results);
|
|
137
|
-
} else {
|
|
138
|
-
return await runTillEnd(this._options.webdriver, this._options.reporters);
|
|
139
|
-
}
|
|
107
|
+
return await runTillEnd(this._options.webdriver, this._options.reporters);
|
|
140
108
|
}
|
|
141
109
|
}
|
|
142
110
|
|
package/lib/server.js
CHANGED
|
@@ -15,11 +15,10 @@ class Server {
|
|
|
15
15
|
*/
|
|
16
16
|
constructor(options) {
|
|
17
17
|
this.options = options;
|
|
18
|
-
this.
|
|
19
|
-
|
|
20
|
-
this.jsonDomReporter = options.jsonDomReporter || false;
|
|
18
|
+
this.useHtmlReporter =
|
|
19
|
+
options.useHtmlReporter === undefined ? true : options.useHtmlReporter;
|
|
21
20
|
this.projectBaseDir = options.projectBaseDir || path.resolve();
|
|
22
|
-
this.jasmineCore = options.jasmineCore || require('
|
|
21
|
+
this.jasmineCore = options.jasmineCore || require('./jasmineCore');
|
|
23
22
|
this.jasmineCssFiles = this.jasmineCore.files.cssFiles.map(function(
|
|
24
23
|
fileName
|
|
25
24
|
) {
|
|
@@ -29,11 +28,15 @@ class Server {
|
|
|
29
28
|
.map(function(fileName) {
|
|
30
29
|
return unWindows(path.join('/__jasmine__', fileName));
|
|
31
30
|
})
|
|
32
|
-
.concat(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
.concat(this.bootFiles());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
bootFiles() {
|
|
35
|
+
const bootFiles = this.jasmineCore.files.bootFiles.map(function(fileName) {
|
|
36
|
+
return unWindows(path.join('/__boot__', fileName));
|
|
37
|
+
});
|
|
38
|
+
bootFiles.splice(1, 0, '/__config__/config.js');
|
|
39
|
+
return bootFiles;
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
allCss() {
|
|
@@ -48,25 +51,18 @@ class Server {
|
|
|
48
51
|
getUrls(baseDir, globs, urlRoot) {
|
|
49
52
|
return findFiles(path.join(this.projectBaseDir, baseDir), globs || []).map(
|
|
50
53
|
function(p) {
|
|
51
|
-
return unWindows(path.join(urlRoot, p));
|
|
54
|
+
return isUrl(p) ? p : unWindows(path.join(urlRoot, p));
|
|
52
55
|
}
|
|
53
56
|
);
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
getSupportFiles() {
|
|
57
60
|
var result = ['/__support__/loadEsModule.js'];
|
|
58
|
-
if (this.
|
|
61
|
+
if (!this.useHtmlReporter) {
|
|
59
62
|
result.push('/__support__/clearReporters.js');
|
|
60
63
|
}
|
|
61
64
|
|
|
62
|
-
|
|
63
|
-
result.push('/__support__/batchReporter.js');
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (this.jsonDomReporter) {
|
|
67
|
-
result.push('/__support__/jsonDomReporter.js');
|
|
68
|
-
}
|
|
69
|
-
|
|
65
|
+
result.push('/__support__/batchReporter.js');
|
|
70
66
|
return result;
|
|
71
67
|
}
|
|
72
68
|
|
|
@@ -118,15 +114,18 @@ class Server {
|
|
|
118
114
|
express.static(path.join(this.projectBaseDir, this.options.srcDir))
|
|
119
115
|
);
|
|
120
116
|
|
|
121
|
-
var
|
|
117
|
+
var indexTemplate = ejs.compile(
|
|
122
118
|
fs.readFileSync(path.resolve(__dirname, '../run.html.ejs')).toString()
|
|
123
119
|
);
|
|
120
|
+
var configTemplate = ejs.compile(
|
|
121
|
+
fs.readFileSync(path.resolve(__dirname, '../config.js.ejs')).toString()
|
|
122
|
+
);
|
|
124
123
|
|
|
125
124
|
var self = this;
|
|
126
125
|
app.get('/', function(req, res) {
|
|
127
126
|
try {
|
|
128
127
|
res.send(
|
|
129
|
-
|
|
128
|
+
indexTemplate({
|
|
130
129
|
cssFiles: self.allCss(),
|
|
131
130
|
jasmineJsFiles: self.jasmineJs(),
|
|
132
131
|
userJsFiles: self.userJs(),
|
|
@@ -137,6 +136,19 @@ class Server {
|
|
|
137
136
|
console.error(error);
|
|
138
137
|
}
|
|
139
138
|
});
|
|
139
|
+
app.get('/__config__/config.js', function(req, res) {
|
|
140
|
+
try {
|
|
141
|
+
res.append('Content-type', 'application/javascript');
|
|
142
|
+
res.send(
|
|
143
|
+
configTemplate({
|
|
144
|
+
envConfig: self.options.env || {},
|
|
145
|
+
})
|
|
146
|
+
);
|
|
147
|
+
} catch (error) {
|
|
148
|
+
res.status(500).send('An error occurred');
|
|
149
|
+
console.error(error);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
140
152
|
|
|
141
153
|
var port = findPort(serverOptions.port, this.options.port);
|
|
142
154
|
return new Promise(resolve => {
|
|
@@ -200,6 +212,10 @@ function findPort(serverPort, optionsPort) {
|
|
|
200
212
|
return 8888;
|
|
201
213
|
}
|
|
202
214
|
|
|
215
|
+
function isUrl(s) {
|
|
216
|
+
return s.startsWith('http://') || s.startsWith('https://');
|
|
217
|
+
}
|
|
218
|
+
|
|
203
219
|
function findFiles(baseDir, globs) {
|
|
204
220
|
const { includeGlobs, excludeGlobs } = globs.reduce(
|
|
205
221
|
function(ongoing, g) {
|
|
@@ -220,12 +236,16 @@ function findFiles(baseDir, globs) {
|
|
|
220
236
|
const result = [];
|
|
221
237
|
|
|
222
238
|
for (const g of includeGlobs) {
|
|
223
|
-
|
|
239
|
+
if (isUrl(g)) {
|
|
240
|
+
result.push(g);
|
|
241
|
+
} else {
|
|
242
|
+
const files = glob.sync(g, { ignore: excludeGlobs, cwd: baseDir });
|
|
224
243
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
244
|
+
for (const f of files) {
|
|
245
|
+
// De-duplicate
|
|
246
|
+
if (result.indexOf(f) === -1) {
|
|
247
|
+
result.push(f);
|
|
248
|
+
}
|
|
229
249
|
}
|
|
230
250
|
}
|
|
231
251
|
}
|
package/lib/types.js
CHANGED
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
* @see Server
|
|
10
10
|
*/
|
|
11
11
|
/**
|
|
12
|
-
* Whether to
|
|
13
|
-
* @name ServerCtorOptions#
|
|
12
|
+
* Whether to use Jasmine's default HTML reporter.
|
|
13
|
+
* @name ServerCtorOptions#useHtmlReporter
|
|
14
14
|
* @type boolean | undefined
|
|
15
|
+
* @default true
|
|
15
16
|
*/
|
|
16
17
|
/**
|
|
17
18
|
* An array of CSS file paths or {@link https://github.com/isaacs/node-glob#glob-primer|globs}
|
|
@@ -71,26 +72,37 @@
|
|
|
71
72
|
*/
|
|
72
73
|
|
|
73
74
|
/**
|
|
74
|
-
*
|
|
75
|
+
* Specifies the properties of the configuration file, as well as
|
|
76
|
+
* the argument to runSpecs.
|
|
77
|
+
*
|
|
78
|
+
* @interface Configuration
|
|
75
79
|
* @augments ServerCtorOptions
|
|
76
|
-
* @augments RunnerRunOptions
|
|
77
80
|
*/
|
|
78
81
|
/**
|
|
79
82
|
* The browser to run the specs in.
|
|
80
|
-
* @name
|
|
83
|
+
* @name Configuration#browser
|
|
81
84
|
* @type string | BrowserInfo | undefined
|
|
82
85
|
*/
|
|
83
86
|
/**
|
|
84
|
-
* Whether to use color in the console output.
|
|
85
|
-
* @name
|
|
87
|
+
* Whether to use color in the console output.
|
|
88
|
+
* @name Configuration#color
|
|
86
89
|
* @type boolean | undefined
|
|
90
|
+
* @default true
|
|
91
|
+
*/
|
|
92
|
+
/**
|
|
93
|
+
* An array of {@link https://jasmine.github.io/api/edge/Reporter.html|reporters}
|
|
94
|
+
* or names of modules defining reporters. If an entry is a string, it should be
|
|
95
|
+
* the {@link https://nodejs.org/api/esm.html#esm_import_specifiers|import specifier}
|
|
96
|
+
* for a module that default exports a reporter constructor. The constructor will
|
|
97
|
+
* be called with no arguments.
|
|
98
|
+
* @name Configuration#reporters
|
|
99
|
+
* @type Array<string | Reporter>
|
|
87
100
|
*/
|
|
88
101
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* {@link https://jasmine.github.io/api/edge/Reporter.html|reporter}.
|
|
92
|
-
* @name RunSpecsOptions#color
|
|
102
|
+
* Whether to use the built-in {@link ConsoleReporter}.
|
|
103
|
+
* @name Configuration#useConsoleReporter
|
|
93
104
|
* @type boolean | undefined
|
|
105
|
+
* @default true
|
|
94
106
|
*/
|
|
95
107
|
|
|
96
108
|
/**
|
|
@@ -104,7 +116,7 @@
|
|
|
104
116
|
* @type boolean | undefined
|
|
105
117
|
*/
|
|
106
118
|
/**
|
|
107
|
-
* The browser name. Valid values include "
|
|
119
|
+
* The browser name. Valid values include "firefox",
|
|
108
120
|
* "safari", "MicrosoftEdge", "chrome", and "headlessChrome".
|
|
109
121
|
* @name BrowserInfo#name
|
|
110
122
|
* @type string | undefined
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jasmine-browser-runner",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Serve and run your Jasmine specs in a browser",
|
|
5
5
|
"bin": "bin/jasmine-browser-runner",
|
|
6
6
|
"exports": "./index.js",
|
|
@@ -9,45 +9,48 @@
|
|
|
9
9
|
"README.md",
|
|
10
10
|
"package.json",
|
|
11
11
|
"index.js",
|
|
12
|
+
"config.js.ejs",
|
|
12
13
|
"run.html.ejs",
|
|
13
14
|
"bin/*.js",
|
|
14
|
-
"lib/**/*.js"
|
|
15
|
+
"lib/**/*.js",
|
|
16
|
+
"lib/examples/default_config.json",
|
|
17
|
+
"lib/examples/default_esm_config.json"
|
|
15
18
|
],
|
|
16
19
|
"scripts": {
|
|
17
|
-
"posttest": "eslint bin/* lib
|
|
20
|
+
"posttest": "eslint bin/* lib spec scripts index.js --ignore-path=.styleIgnore && prettier --check --ignore-path=.styleIgnore lib/*.js lib/**/*.js spec/**/*.js scripts/*.js index.js",
|
|
18
21
|
"test": "jasmine",
|
|
19
22
|
"cleanup": "prettier --write --ignore-path=.styleIgnore lib/*.js lib/**/*.js spec/**/*.js scripts/*.js index.js",
|
|
20
23
|
"release": "node scripts/release.js"
|
|
21
24
|
},
|
|
22
25
|
"repository": {
|
|
23
26
|
"type": "git",
|
|
24
|
-
"url": "git+https://github.com/jasmine/jasmine-browser.git"
|
|
27
|
+
"url": "git+https://github.com/jasmine/jasmine-browser-runner.git"
|
|
25
28
|
},
|
|
26
29
|
"keywords": [
|
|
27
30
|
"jasmine",
|
|
28
31
|
"testing",
|
|
29
32
|
"tdd"
|
|
30
33
|
],
|
|
31
|
-
"engines": {
|
|
32
|
-
"node": ">=14"
|
|
33
|
-
},
|
|
34
34
|
"author": "Slackersoft",
|
|
35
35
|
"license": "MIT",
|
|
36
36
|
"bugs": {
|
|
37
|
-
"url": "https://github.com/jasmine/jasmine-browser/issues"
|
|
37
|
+
"url": "https://github.com/jasmine/jasmine-browser-runner/issues"
|
|
38
38
|
},
|
|
39
|
-
"homepage": "https://github.com/jasmine/jasmine-browser#readme",
|
|
39
|
+
"homepage": "https://github.com/jasmine/jasmine-browser-runner#readme",
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"ejs": "^
|
|
41
|
+
"ejs": "^3.1.6",
|
|
42
42
|
"express": "^4.16.4",
|
|
43
43
|
"glob": "^7.1.7",
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
"selenium-webdriver": "^4.1.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"jasmine-core": "^4.0.0"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
|
-
"eslint": "^
|
|
50
|
-
"eslint-plugin-jasmine": "^
|
|
50
|
+
"eslint": "^7.32.0",
|
|
51
|
+
"eslint-plugin-jasmine": "^4.1.3",
|
|
52
|
+
"jasmine": "^4.0.0",
|
|
53
|
+
"jasmine-core": "^4.0.0",
|
|
51
54
|
"prettier": "^1.17.1",
|
|
52
55
|
"shelljs": "^0.8.3",
|
|
53
56
|
"temp": "^0.9.4"
|
package/run.html.ejs
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
<% cssFiles.forEach(function(cssFile) { %>
|
|
9
9
|
<link rel="stylesheet" href="<%= cssFile %>" type="text/css" media="screen"/>
|
|
10
10
|
<% }) %>
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
11
13
|
<% jasmineJsFiles.forEach(function(jsFile) { %>
|
|
12
14
|
<script src="<%= jsFile %>" type="text/javascript"></script>
|
|
13
15
|
<% }) %>
|
|
@@ -19,8 +21,6 @@
|
|
|
19
21
|
<% } %>
|
|
20
22
|
<% }) %>
|
|
21
23
|
|
|
22
|
-
</head>
|
|
23
|
-
<body>
|
|
24
24
|
<div id="jasmine_content"></div>
|
|
25
25
|
</body>
|
|
26
26
|
</html>
|
package/lib/default_reporter.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
const ConsoleReporter = require('jasmine').ConsoleReporter;
|
|
2
|
-
const util = require('util');
|
|
3
|
-
|
|
4
|
-
function DefaultReporter(options) {
|
|
5
|
-
options = options || {};
|
|
6
|
-
ConsoleReporter.call(this);
|
|
7
|
-
|
|
8
|
-
this.setOptions({
|
|
9
|
-
print: function() {
|
|
10
|
-
process.stdout.write(util.format.apply(this, arguments));
|
|
11
|
-
},
|
|
12
|
-
randomSeedReproductionCmd: function(seed) {
|
|
13
|
-
return 'jasmine-browser-runner runSpecs --seed=' + seed;
|
|
14
|
-
},
|
|
15
|
-
showColors: options.color === 'undefined' ? true : options.color,
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
module.exports = DefaultReporter;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/* eslint-env browser, jasmine */
|
|
2
|
-
|
|
3
|
-
// This is mainly intended for use with IE. When controlling IE,
|
|
4
|
-
// webdriver.executeScript is unreliable. It tends to fail if too
|
|
5
|
-
// much JS is running on the page when it's called or if the return
|
|
6
|
-
// value of the executed JS is non-tiny. Both of these are common
|
|
7
|
-
// conditions in Jasmine. JsonDomReporter works around the problem
|
|
8
|
-
// by exposing all data through the DOM, so that the runner can
|
|
9
|
-
// entirely avoid calling webdriver.executeScript. The drawback is
|
|
10
|
-
// that results can't be shown until all specs have finished.
|
|
11
|
-
function JsonDomReporter() {
|
|
12
|
-
var events = [];
|
|
13
|
-
|
|
14
|
-
this.jasmineStarted = function(info) {
|
|
15
|
-
events.push(['jasmineStarted', info]);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
this.suiteStarted = function(info) {
|
|
19
|
-
events.push(['suiteStarted', info]);
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
this.specStarted = function(info) {
|
|
23
|
-
events.push(['specStarted', info]);
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
this.jasmineDone = function(info) {
|
|
27
|
-
events.push(['jasmineDone', info]);
|
|
28
|
-
|
|
29
|
-
var resultsEl = document.createElement('div');
|
|
30
|
-
resultsEl.id = 'jasmine-jsonDomReporter-done';
|
|
31
|
-
resultsEl.textContent = JSON.stringify(events);
|
|
32
|
-
document.body.appendChild(resultsEl);
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
this.suiteDone = function(info) {
|
|
36
|
-
events.push(['suiteDone', info]);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
this.specDone = function(info) {
|
|
40
|
-
events.push(['specDone', info]);
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
window.jsonDomReporter = new JsonDomReporter();
|
|
45
|
-
jasmine.getEnv().addReporter(window.jsonDomReporter);
|