jasmine-browser-runner 0.6.0 → 0.10.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 +87 -5
- package/bin/{jasmine-browser → jasmine-browser-runner} +1 -1
- package/config.js.ejs +1 -0
- package/index.js +63 -50
- package/lib/command.js +50 -34
- package/lib/config.js +75 -0
- package/lib/console_reporter.js +307 -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/moduleLoader.js +38 -0
- package/lib/runner.js +0 -2
- package/lib/server.js +45 -16
- package/lib/types.js +23 -11
- package/package.json +36 -22
- package/run.html.ejs +2 -2
- package/lib/default_config.js +0 -19
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:
|
|
@@ -67,15 +67,97 @@ Its value can be `"internet explorer"`, `"firefox"`, `"safari"`,
|
|
|
67
67
|
|
|
68
68
|
If a source, spec, or helper file's name ends in `.mjs`, it will be loaded as
|
|
69
69
|
an ES module rather than a regular script. Note that ES modules are not
|
|
70
|
-
available in all browsers supported by jasmine-browser. Currently,
|
|
71
|
-
jasmine-browser does not try to determine whether the browser supports ES
|
|
70
|
+
available in all browsers supported by jasmine-browser-runner. Currently,
|
|
71
|
+
jasmine-browser-runner does not try to determine whether the browser supports ES
|
|
72
72
|
modules. ES modules will silently fail to load in browsers that don't
|
|
73
73
|
support them. Other kinds of load-time errors are detected and reported as suite
|
|
74
74
|
errors.
|
|
75
75
|
|
|
76
|
+
To allow spec files to import source files via relative paths, set the `specDir`
|
|
77
|
+
config field to something that's high enough up to include both spec and source
|
|
78
|
+
files, and set `srcFiles` to `[]`. You can autogenerate such a configuration by
|
|
79
|
+
running `npx jasmine-browser-runner init --esm`.
|
|
80
|
+
|
|
81
|
+
## Use with Rails
|
|
82
|
+
|
|
83
|
+
You can use jasmine-browser-runner to test your Rails application's JavaScript,
|
|
84
|
+
whether you use the Asset Pipeline or Webpacker.
|
|
85
|
+
|
|
86
|
+
### Webpacker
|
|
87
|
+
|
|
88
|
+
1. Run `yarn add --dev jasmine-browser-runner`.
|
|
89
|
+
2. Run `npx jasmine-browser-runner init`.
|
|
90
|
+
3. Edit `spec/support/jasmine-browser.json` as follows:
|
|
91
|
+
```
|
|
92
|
+
{
|
|
93
|
+
"srcDir": ".",
|
|
94
|
+
"srcFiles": [],
|
|
95
|
+
"specDir": "public/packs/js",
|
|
96
|
+
"specFiles": [
|
|
97
|
+
"specs-*.js"
|
|
98
|
+
],
|
|
99
|
+
"helpers": [],
|
|
100
|
+
// ...
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
4. Create `app/javascript/packs/specs.js` (or `app/javascript/packs/specs.jsx`
|
|
104
|
+
if you use JSX) as follows:
|
|
105
|
+
```
|
|
106
|
+
(function() {
|
|
107
|
+
'use strict';
|
|
108
|
+
|
|
109
|
+
function requireAll(context) {
|
|
110
|
+
context.keys().forEach(context);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
requireAll(require.context('spec/javascript/helpers/', true, /\.js/));
|
|
114
|
+
requireAll(require.context('spec/javascript/', true, /[sS]pec\.js/));
|
|
115
|
+
})();
|
|
116
|
+
```
|
|
117
|
+
5. Add `'spec/javascript'` to the `additional_paths` array in `config/webpacker.yml`.
|
|
118
|
+
6. Put your spec files in `spec/javascript`.
|
|
119
|
+
|
|
120
|
+
To run the specs:
|
|
121
|
+
|
|
122
|
+
1. Run `bin/webpack --watch`.
|
|
123
|
+
2. Run `npx jasmine-browser-runner`.
|
|
124
|
+
3. visit <http://localhost:8888>.
|
|
125
|
+
|
|
126
|
+
### Asset Pipeline
|
|
127
|
+
|
|
128
|
+
1. Run `yarn init` if there isn't already `package.json` file in the root of
|
|
129
|
+
the Rails application.
|
|
130
|
+
2. Run `yarn add --dev jasmine-browser-runner`.
|
|
131
|
+
3. Run `npx jasmine-browser-runner init`.
|
|
132
|
+
5. Edit `spec/support/jasmine-browser.json` as follows:
|
|
133
|
+
```
|
|
134
|
+
{
|
|
135
|
+
"srcDir": "public/assets",
|
|
136
|
+
"srcFiles": [
|
|
137
|
+
"application-*.js"
|
|
138
|
+
],
|
|
139
|
+
"specDir": "spec/javascript",
|
|
140
|
+
"specFiles": [
|
|
141
|
+
"**/*[sS]pec.?(m)js"
|
|
142
|
+
],
|
|
143
|
+
"helpers": [
|
|
144
|
+
"helpers/**/*.?(m)js"
|
|
145
|
+
],
|
|
146
|
+
// ...
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
6. Put your spec files in `spec/javascript`.
|
|
150
|
+
|
|
151
|
+
To run the specs:
|
|
152
|
+
|
|
153
|
+
1. Either run `bundle exec rake assets:precompile` or start the Rails
|
|
154
|
+
application in an environment that's configured to precompile assets.
|
|
155
|
+
2. Run `npx jasmine-browser-runner`.
|
|
156
|
+
3. Visit <http://localhost:8888>.
|
|
157
|
+
|
|
76
158
|
## Saucelabs support
|
|
77
159
|
|
|
78
|
-
jasmine-browser can run your Jasmine specs on [Saucelabs](https://saucelabs.com/).
|
|
160
|
+
jasmine-browser-runner can run your Jasmine specs on [Saucelabs](https://saucelabs.com/).
|
|
79
161
|
To use Saucelabs, set `browser.name`, `browser.useSauce`, and `browser.sauce`
|
|
80
162
|
in your config file as follows:
|
|
81
163
|
|
package/config.js.ejs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
jasmine.getEnv().configure(<%- JSON.stringify(envConfig) %>);
|
package/index.js
CHANGED
|
@@ -1,39 +1,47 @@
|
|
|
1
|
-
const ConsoleReporter = require('
|
|
1
|
+
const ConsoleReporter = require('./lib/console_reporter'),
|
|
2
2
|
webdriverModule = require('./lib/webdriver'),
|
|
3
|
-
util = require('util'),
|
|
4
3
|
Server = require('./lib/server'),
|
|
5
|
-
Runner = require('./lib/runner')
|
|
4
|
+
Runner = require('./lib/runner'),
|
|
5
|
+
ModuleLoader = require('./lib/moduleLoader');
|
|
6
6
|
|
|
7
|
-
function createReporters(options) {
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
async function createReporters(options) {
|
|
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
|
-
|
|
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());
|
|
13
20
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
+
}
|
|
33
|
+
}
|
|
22
34
|
}
|
|
23
35
|
}
|
|
24
36
|
|
|
25
|
-
|
|
26
|
-
|
|
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
|
+
}
|
|
27
43
|
|
|
28
|
-
|
|
29
|
-
const reporter = new ConsoleReporter();
|
|
30
|
-
reporter.setOptions({
|
|
31
|
-
print: function() {
|
|
32
|
-
process.stdout.write(util.format.apply(this, arguments));
|
|
33
|
-
},
|
|
34
|
-
showColors: options.color === 'undefined' ? true : options.color,
|
|
35
|
-
});
|
|
36
|
-
return [reporter];
|
|
44
|
+
return result;
|
|
37
45
|
}
|
|
38
46
|
|
|
39
47
|
/**
|
|
@@ -53,7 +61,7 @@ module.exports = {
|
|
|
53
61
|
},
|
|
54
62
|
/**
|
|
55
63
|
* Runs the specs.
|
|
56
|
-
* @param {
|
|
64
|
+
* @param {Configuration} options
|
|
57
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.
|
|
58
66
|
*/
|
|
59
67
|
runSpecs: async function(options, deps) {
|
|
@@ -71,41 +79,46 @@ module.exports = {
|
|
|
71
79
|
deps.buildWebdriver || webdriverModule.buildWebdriver;
|
|
72
80
|
const setExitCode = deps.setExitCode || (code => (process.exitCode = code));
|
|
73
81
|
const server = new ServerClass(options);
|
|
74
|
-
const webdriver = buildWebdriver(options.browser);
|
|
75
82
|
|
|
76
|
-
const reporters = createReporters(options);
|
|
83
|
+
const reporters = await createReporters(options);
|
|
77
84
|
const useSauce = options.browser && options.browser.useSauce;
|
|
78
85
|
const portRequest = useSauce ? 5555 : 0;
|
|
79
86
|
await server.start({ port: portRequest });
|
|
80
|
-
const host = `http://localhost:${server.port()}`;
|
|
81
|
-
const runner = new RunnerClass({ webdriver, reporters, host });
|
|
82
|
-
|
|
83
|
-
console.log('Running tests in the browser...');
|
|
84
87
|
|
|
85
88
|
try {
|
|
86
|
-
const
|
|
89
|
+
const webdriver = buildWebdriver(options.browser);
|
|
87
90
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
setExitCode(2);
|
|
92
|
-
} else {
|
|
93
|
-
setExitCode(1);
|
|
94
|
-
}
|
|
91
|
+
try {
|
|
92
|
+
const host = `http://localhost:${server.port()}`;
|
|
93
|
+
const runner = new RunnerClass({ webdriver, reporters, host });
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
} finally {
|
|
98
|
-
await server.stop();
|
|
95
|
+
console.log('Running tests in the browser...');
|
|
99
96
|
|
|
100
|
-
|
|
101
|
-
await webdriver.executeScript(
|
|
102
|
-
`sauce:job-result=${process.exitCode === 0}`
|
|
103
|
-
);
|
|
104
|
-
}
|
|
97
|
+
const details = await runner.run(options);
|
|
105
98
|
|
|
106
|
-
|
|
99
|
+
if (details.overallStatus === 'passed') {
|
|
100
|
+
setExitCode(0);
|
|
101
|
+
} else if (details.overallStatus === 'incomplete') {
|
|
102
|
+
setExitCode(2);
|
|
103
|
+
} else {
|
|
104
|
+
setExitCode(1);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return details;
|
|
108
|
+
} finally {
|
|
109
|
+
if (useSauce) {
|
|
110
|
+
await webdriver.executeScript(
|
|
111
|
+
`sauce:job-result=${process.exitCode === 0}`
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
await webdriver.close();
|
|
116
|
+
}
|
|
117
|
+
} finally {
|
|
118
|
+
await server.stop();
|
|
107
119
|
}
|
|
108
120
|
},
|
|
109
121
|
Server,
|
|
110
122
|
Runner,
|
|
123
|
+
ConsoleReporter,
|
|
111
124
|
};
|
package/lib/command.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
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');
|
|
4
9
|
|
|
5
10
|
const commonOptions = [
|
|
6
11
|
{ 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
12
|
{ name: 'port', type: 'number', description: 'port to run the server on' },
|
|
13
13
|
];
|
|
14
14
|
|
|
@@ -22,6 +22,14 @@ const subCommands = [
|
|
|
22
22
|
{
|
|
23
23
|
name: 'init',
|
|
24
24
|
description: 'initialize a new Jasmine project',
|
|
25
|
+
options: [
|
|
26
|
+
{
|
|
27
|
+
name: 'esm',
|
|
28
|
+
type: 'bool',
|
|
29
|
+
description:
|
|
30
|
+
'configure for use with ES modules (<script type="module">)',
|
|
31
|
+
},
|
|
32
|
+
],
|
|
25
33
|
},
|
|
26
34
|
{
|
|
27
35
|
name: 'serve',
|
|
@@ -35,6 +43,7 @@ const subCommands = [
|
|
|
35
43
|
{
|
|
36
44
|
name: 'color',
|
|
37
45
|
type: 'bool',
|
|
46
|
+
reversable: true,
|
|
38
47
|
description: 'turn on or off color output',
|
|
39
48
|
},
|
|
40
49
|
{
|
|
@@ -43,19 +52,15 @@ const subCommands = [
|
|
|
43
52
|
description:
|
|
44
53
|
'filter specs to run only those that match the given string',
|
|
45
54
|
},
|
|
46
|
-
{
|
|
47
|
-
name: 'stop-on-failure',
|
|
48
|
-
type: 'bool',
|
|
49
|
-
description: 'stop spec execution on expectation failure',
|
|
50
|
-
},
|
|
51
55
|
{
|
|
52
56
|
name: 'fail-fast',
|
|
53
57
|
type: 'bool',
|
|
54
|
-
description: 'stop Jasmine execution on
|
|
58
|
+
description: 'stop Jasmine execution on the first failure',
|
|
55
59
|
},
|
|
56
60
|
{
|
|
57
61
|
name: 'random',
|
|
58
62
|
type: 'bool',
|
|
63
|
+
reversable: true,
|
|
59
64
|
description: 'turn on or off randomization',
|
|
60
65
|
},
|
|
61
66
|
{
|
|
@@ -141,7 +146,7 @@ class Command {
|
|
|
141
146
|
this._logger.log('jasmine-core v' + this._config.jasmineCore.version());
|
|
142
147
|
}
|
|
143
148
|
|
|
144
|
-
init() {
|
|
149
|
+
init(options) {
|
|
145
150
|
const dest = 'spec/support/jasmine-browser.json';
|
|
146
151
|
|
|
147
152
|
if (fs.existsSync(dest)) {
|
|
@@ -150,33 +155,40 @@ class Command {
|
|
|
150
155
|
}
|
|
151
156
|
|
|
152
157
|
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
153
|
-
|
|
158
|
+
|
|
159
|
+
if (options.esm) {
|
|
160
|
+
fs.writeFileSync(dest, defaultEsmConfig());
|
|
161
|
+
} else {
|
|
162
|
+
fs.writeFileSync(dest, defaultConfig());
|
|
163
|
+
}
|
|
164
|
+
|
|
154
165
|
this._logger.log(`Wrote configuration to ${dest}.`);
|
|
155
166
|
}
|
|
156
167
|
|
|
157
168
|
async serve(options) {
|
|
158
|
-
await this._config.jasmineBrowser.startServer(
|
|
169
|
+
await this._config.jasmineBrowser.startServer(
|
|
170
|
+
await this._loadConfig(options)
|
|
171
|
+
);
|
|
159
172
|
}
|
|
160
173
|
|
|
161
174
|
async runSpecs(options) {
|
|
162
|
-
await this.
|
|
175
|
+
const config = await this._loadConfig(options);
|
|
176
|
+
|
|
177
|
+
if (options['fail-fast']) {
|
|
178
|
+
config.env = {
|
|
179
|
+
...config.env,
|
|
180
|
+
stopSpecOnExpectationFailure: true,
|
|
181
|
+
stopOnSpecFailure: true,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
await this._config.jasmineBrowser.runSpecs(config);
|
|
163
186
|
}
|
|
164
187
|
|
|
165
|
-
_loadConfig(options) {
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
Object.keys(options).forEach(function(opt) {
|
|
170
|
-
const camelCase = opt.replace(/-./g, function(input) {
|
|
171
|
-
return input[1].toUpperCase();
|
|
172
|
-
});
|
|
173
|
-
if (camelCase !== opt) {
|
|
174
|
-
options[camelCase] = options[opt];
|
|
175
|
-
delete options[opt];
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
const fullPath = path.resolve(this._config.baseDir, configFile);
|
|
179
|
-
return Object.assign({}, require(fullPath), options);
|
|
188
|
+
async _loadConfig(options) {
|
|
189
|
+
const config = await loadConfig(this._config.baseDir, options);
|
|
190
|
+
validateConfig(config);
|
|
191
|
+
return config;
|
|
180
192
|
}
|
|
181
193
|
}
|
|
182
194
|
|
|
@@ -219,9 +231,13 @@ function commandText(command) {
|
|
|
219
231
|
}
|
|
220
232
|
|
|
221
233
|
function optionText(option) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
234
|
+
if (option.type !== 'bool') {
|
|
235
|
+
return `--${option.name}=<value>`;
|
|
236
|
+
} else if (option.reversable) {
|
|
237
|
+
return `--[no-]${option.name}`;
|
|
238
|
+
} else {
|
|
239
|
+
return `--${option.name}`;
|
|
240
|
+
}
|
|
225
241
|
}
|
|
226
242
|
|
|
227
243
|
function wrapDescription(indentLevel, prefixWidth, maxWidth, text) {
|
package/lib/config.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const ModuleLoader = require('./moduleLoader');
|
|
4
|
+
|
|
5
|
+
async function loadConfig(baseDir, cliOptions) {
|
|
6
|
+
const options = { ...cliOptions };
|
|
7
|
+
const specifiedConfigFile = options.config;
|
|
8
|
+
delete options.config;
|
|
9
|
+
delete options.unknown;
|
|
10
|
+
|
|
11
|
+
Object.keys(options).forEach(function(opt) {
|
|
12
|
+
const camelCase = opt.replace(/-./g, function(input) {
|
|
13
|
+
return input[1].toUpperCase();
|
|
14
|
+
});
|
|
15
|
+
if (camelCase !== opt) {
|
|
16
|
+
options[camelCase] = options[opt];
|
|
17
|
+
delete options[opt];
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const candidates = (specifiedConfigFile
|
|
22
|
+
? [specifiedConfigFile]
|
|
23
|
+
: ['spec/support/jasmine-browser.js', 'spec/support/jasmine-browser.json']
|
|
24
|
+
)
|
|
25
|
+
.filter(name => !!name)
|
|
26
|
+
.map(name => path.resolve(baseDir, name));
|
|
27
|
+
|
|
28
|
+
const fullPath = candidates.find(p => fs.existsSync(p));
|
|
29
|
+
|
|
30
|
+
if (!fullPath) {
|
|
31
|
+
const msg =
|
|
32
|
+
'Could not find configuration file.\nTried:\n' +
|
|
33
|
+
candidates.map(p => `* ${p}`).join('\n');
|
|
34
|
+
throw new Error(msg);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const moduleLoader = new ModuleLoader();
|
|
38
|
+
return Object.assign({}, await moduleLoader.load(fullPath), options);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function validateConfig(config) {
|
|
42
|
+
for (const k of ['specDir', 'srcDir']) {
|
|
43
|
+
if (!config[k]) {
|
|
44
|
+
throw new Error('Configuration is missing ' + k);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
for (const k of ['specFiles', 'srcFiles', 'helpers']) {
|
|
49
|
+
if (config[k] && !Array.isArray(config[k])) {
|
|
50
|
+
throw new Error(`Configuration's ${k} property is not an array`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
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
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = {
|
|
71
|
+
loadConfig,
|
|
72
|
+
validateConfig,
|
|
73
|
+
defaultConfig,
|
|
74
|
+
defaultEsmConfig,
|
|
75
|
+
};
|
|
@@ -0,0 +1,307 @@
|
|
|
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
|
+
printNewline();
|
|
80
|
+
printNewline();
|
|
81
|
+
if (failedSpecs.length > 0) {
|
|
82
|
+
print('Failures:');
|
|
83
|
+
}
|
|
84
|
+
for (let i = 0; i < failedSpecs.length; i++) {
|
|
85
|
+
specFailureDetails(failedSpecs[i], i + 1);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
for (let i = 0; i < failedSuites.length; i++) {
|
|
89
|
+
suiteFailureDetails(failedSuites[i]);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (
|
|
93
|
+
result &&
|
|
94
|
+
result.failedExpectations &&
|
|
95
|
+
result.failedExpectations.length > 0
|
|
96
|
+
) {
|
|
97
|
+
suiteFailureDetails(result);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (pendingSpecs.length > 0) {
|
|
101
|
+
print('Pending:');
|
|
102
|
+
}
|
|
103
|
+
for (let i = 0; i < pendingSpecs.length; i++) {
|
|
104
|
+
pendingSpecDetails(pendingSpecs[i], i + 1);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (specCount > 0) {
|
|
108
|
+
printNewline();
|
|
109
|
+
|
|
110
|
+
if (executableSpecCount !== specCount) {
|
|
111
|
+
print(
|
|
112
|
+
'Ran ' +
|
|
113
|
+
executableSpecCount +
|
|
114
|
+
' of ' +
|
|
115
|
+
specCount +
|
|
116
|
+
plural(' spec', specCount)
|
|
117
|
+
);
|
|
118
|
+
printNewline();
|
|
119
|
+
}
|
|
120
|
+
let specCounts =
|
|
121
|
+
executableSpecCount +
|
|
122
|
+
' ' +
|
|
123
|
+
plural('spec', executableSpecCount) +
|
|
124
|
+
', ' +
|
|
125
|
+
failureCount +
|
|
126
|
+
' ' +
|
|
127
|
+
plural('failure', failureCount);
|
|
128
|
+
|
|
129
|
+
if (pendingSpecs.length) {
|
|
130
|
+
specCounts +=
|
|
131
|
+
', ' +
|
|
132
|
+
pendingSpecs.length +
|
|
133
|
+
' pending ' +
|
|
134
|
+
plural('spec', pendingSpecs.length);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
print(specCounts);
|
|
138
|
+
} else {
|
|
139
|
+
print('No specs found');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
printNewline();
|
|
143
|
+
const seconds = result ? result.totalTime / 1000 : 0;
|
|
144
|
+
print('Finished in ' + seconds + ' ' + plural('second', seconds));
|
|
145
|
+
printNewline();
|
|
146
|
+
|
|
147
|
+
if (result && result.overallStatus === 'incomplete') {
|
|
148
|
+
print('Incomplete: ' + result.incompleteReason);
|
|
149
|
+
printNewline();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (result && result.order && result.order.random) {
|
|
153
|
+
print('Randomized with seed ' + result.order.seed);
|
|
154
|
+
print(
|
|
155
|
+
' (jasmine-browser-runner runSpecs --seed=' + result.order.seed + ')'
|
|
156
|
+
);
|
|
157
|
+
printNewline();
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
this.specDone = function(result) {
|
|
162
|
+
specCount++;
|
|
163
|
+
|
|
164
|
+
if (result.status == 'pending') {
|
|
165
|
+
pendingSpecs.push(result);
|
|
166
|
+
executableSpecCount++;
|
|
167
|
+
print(colored('yellow', '*'));
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (result.status == 'passed') {
|
|
172
|
+
executableSpecCount++;
|
|
173
|
+
print(colored('green', '.'));
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (result.status == 'failed') {
|
|
178
|
+
failureCount++;
|
|
179
|
+
failedSpecs.push(result);
|
|
180
|
+
executableSpecCount++;
|
|
181
|
+
print(colored('red', 'F'));
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
this.suiteDone = function(result) {
|
|
186
|
+
if (result.failedExpectations && result.failedExpectations.length > 0) {
|
|
187
|
+
failureCount++;
|
|
188
|
+
failedSuites.push(result);
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
return this;
|
|
193
|
+
|
|
194
|
+
function printNewline() {
|
|
195
|
+
print('\n');
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function colored(color, str) {
|
|
199
|
+
return showColors ? ansi[color] + str + ansi.none : str;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function plural(str, count) {
|
|
203
|
+
return count == 1 ? str : str + 's';
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function repeat(thing, times) {
|
|
207
|
+
const arr = [];
|
|
208
|
+
for (let i = 0; i < times; i++) {
|
|
209
|
+
arr.push(thing);
|
|
210
|
+
}
|
|
211
|
+
return arr;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function indent(str, spaces) {
|
|
215
|
+
const lines = (str || '').split('\n');
|
|
216
|
+
const newArr = [];
|
|
217
|
+
for (let i = 0; i < lines.length; i++) {
|
|
218
|
+
newArr.push(repeat(' ', spaces).join('') + lines[i]);
|
|
219
|
+
}
|
|
220
|
+
return newArr.join('\n');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function defaultStackFilter(stack) {
|
|
224
|
+
if (!stack) {
|
|
225
|
+
return '';
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const filteredStack = stack
|
|
229
|
+
.split('\n')
|
|
230
|
+
.filter(function(stackLine) {
|
|
231
|
+
return stackLine.indexOf(jasmineCorePath) === -1;
|
|
232
|
+
})
|
|
233
|
+
.join('\n');
|
|
234
|
+
return filteredStack;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function specFailureDetails(result, failedSpecNumber) {
|
|
238
|
+
printNewline();
|
|
239
|
+
print(failedSpecNumber + ') ');
|
|
240
|
+
print(result.fullName);
|
|
241
|
+
printFailedExpectations(result);
|
|
242
|
+
|
|
243
|
+
if (result.trace) {
|
|
244
|
+
printNewline();
|
|
245
|
+
print(indent('Trace:', 2));
|
|
246
|
+
printNewline();
|
|
247
|
+
|
|
248
|
+
for (const entry of result.trace) {
|
|
249
|
+
print(indent(`${entry.timestamp}ms: ${entry.message}`, 4));
|
|
250
|
+
printNewline();
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function suiteFailureDetails(result) {
|
|
256
|
+
printNewline();
|
|
257
|
+
print('Suite error: ' + result.fullName);
|
|
258
|
+
printFailedExpectations(result);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function printFailedExpectations(result) {
|
|
262
|
+
for (let i = 0; i < result.failedExpectations.length; i++) {
|
|
263
|
+
const failedExpectation = result.failedExpectations[i];
|
|
264
|
+
printNewline();
|
|
265
|
+
print(indent('Message:', 2));
|
|
266
|
+
printNewline();
|
|
267
|
+
print(colored('red', indent(failedExpectation.message, 4)));
|
|
268
|
+
printNewline();
|
|
269
|
+
print(indent('Stack:', 2));
|
|
270
|
+
printNewline();
|
|
271
|
+
print(indent(stackFilter(failedExpectation.stack), 4));
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// When failSpecWithNoExpectations = true and a spec fails because of no expectations found,
|
|
275
|
+
// jasmine-core reports it as a failure with no message.
|
|
276
|
+
//
|
|
277
|
+
// Therefore we assume that when there are no failed or passed expectations,
|
|
278
|
+
// the failure was because of our failSpecWithNoExpectations setting.
|
|
279
|
+
//
|
|
280
|
+
// Same logic is used by jasmine.HtmlReporter, see https://github.com/jasmine/jasmine/blob/main/src/html/HtmlReporter.js
|
|
281
|
+
if (
|
|
282
|
+
result.failedExpectations.length === 0 &&
|
|
283
|
+
result.passedExpectations.length === 0
|
|
284
|
+
) {
|
|
285
|
+
printNewline();
|
|
286
|
+
print(indent('Message:', 2));
|
|
287
|
+
printNewline();
|
|
288
|
+
print(colored('red', indent('Spec has no expectations', 4)));
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
printNewline();
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function pendingSpecDetails(result, pendingSpecNumber) {
|
|
295
|
+
printNewline();
|
|
296
|
+
printNewline();
|
|
297
|
+
print(pendingSpecNumber + ') ');
|
|
298
|
+
print(result.fullName);
|
|
299
|
+
printNewline();
|
|
300
|
+
let pendingReason = 'No reason given';
|
|
301
|
+
if (result.pendingReason && result.pendingReason !== '') {
|
|
302
|
+
pendingReason = result.pendingReason;
|
|
303
|
+
}
|
|
304
|
+
print(indent(colored('yellow', pendingReason), 2));
|
|
305
|
+
printNewline();
|
|
306
|
+
}
|
|
307
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const url = require('url');
|
|
3
|
+
|
|
4
|
+
class ModuleLoader {
|
|
5
|
+
constructor(parentDir, deps) {
|
|
6
|
+
deps = deps || {};
|
|
7
|
+
this.require_ = deps.requireShim || requireShim;
|
|
8
|
+
this.import_ = deps.importShim || importShim;
|
|
9
|
+
this.parentDir_ = parentDir;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async load(filePath) {
|
|
13
|
+
if (filePath.endsWith('.json')) {
|
|
14
|
+
return this.require_(filePath);
|
|
15
|
+
} else {
|
|
16
|
+
// The ES module spec requires absolute import paths to be valid URLs. As
|
|
17
|
+
// of v16, Node enforces this on Windows but not on other OSes.
|
|
18
|
+
if (path.isAbsolute(filePath)) {
|
|
19
|
+
filePath = url.pathToFileURL(filePath);
|
|
20
|
+
} else if (filePath.startsWith('./') || filePath.startsWith('../')) {
|
|
21
|
+
filePath = url.pathToFileURL(path.resolve(this.parentDir_, filePath));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const module = await this.import_(filePath);
|
|
25
|
+
return module.default;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function requireShim(path) {
|
|
31
|
+
return require(path);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function importShim(path) {
|
|
35
|
+
return import(path);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = ModuleLoader;
|
package/lib/runner.js
CHANGED
package/lib/server.js
CHANGED
|
@@ -15,11 +15,12 @@ class Server {
|
|
|
15
15
|
*/
|
|
16
16
|
constructor(options) {
|
|
17
17
|
this.options = options;
|
|
18
|
-
this.
|
|
18
|
+
this.useHtmlReporter =
|
|
19
|
+
options.useHtmlReporter === undefined ? true : options.useHtmlReporter;
|
|
19
20
|
this.batchReporter = options.batchReporter || false;
|
|
20
21
|
this.jsonDomReporter = options.jsonDomReporter || false;
|
|
21
22
|
this.projectBaseDir = options.projectBaseDir || path.resolve();
|
|
22
|
-
this.jasmineCore = options.jasmineCore || require('
|
|
23
|
+
this.jasmineCore = options.jasmineCore || require('./jasmineCore');
|
|
23
24
|
this.jasmineCssFiles = this.jasmineCore.files.cssFiles.map(function(
|
|
24
25
|
fileName
|
|
25
26
|
) {
|
|
@@ -29,11 +30,15 @@ class Server {
|
|
|
29
30
|
.map(function(fileName) {
|
|
30
31
|
return unWindows(path.join('/__jasmine__', fileName));
|
|
31
32
|
})
|
|
32
|
-
.concat(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
.concat(this.bootFiles());
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
bootFiles() {
|
|
37
|
+
const bootFiles = this.jasmineCore.files.bootFiles.map(function(fileName) {
|
|
38
|
+
return unWindows(path.join('/__boot__', fileName));
|
|
39
|
+
});
|
|
40
|
+
bootFiles.splice(1, 0, '/__config__/config.js');
|
|
41
|
+
return bootFiles;
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
allCss() {
|
|
@@ -48,14 +53,14 @@ class Server {
|
|
|
48
53
|
getUrls(baseDir, globs, urlRoot) {
|
|
49
54
|
return findFiles(path.join(this.projectBaseDir, baseDir), globs || []).map(
|
|
50
55
|
function(p) {
|
|
51
|
-
return unWindows(path.join(urlRoot, p));
|
|
56
|
+
return isUrl(p) ? p : unWindows(path.join(urlRoot, p));
|
|
52
57
|
}
|
|
53
58
|
);
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
getSupportFiles() {
|
|
57
62
|
var result = ['/__support__/loadEsModule.js'];
|
|
58
|
-
if (this.
|
|
63
|
+
if (!this.useHtmlReporter) {
|
|
59
64
|
result.push('/__support__/clearReporters.js');
|
|
60
65
|
}
|
|
61
66
|
|
|
@@ -118,15 +123,18 @@ class Server {
|
|
|
118
123
|
express.static(path.join(this.projectBaseDir, this.options.srcDir))
|
|
119
124
|
);
|
|
120
125
|
|
|
121
|
-
var
|
|
126
|
+
var indexTemplate = ejs.compile(
|
|
122
127
|
fs.readFileSync(path.resolve(__dirname, '../run.html.ejs')).toString()
|
|
123
128
|
);
|
|
129
|
+
var configTemplate = ejs.compile(
|
|
130
|
+
fs.readFileSync(path.resolve(__dirname, '../config.js.ejs')).toString()
|
|
131
|
+
);
|
|
124
132
|
|
|
125
133
|
var self = this;
|
|
126
134
|
app.get('/', function(req, res) {
|
|
127
135
|
try {
|
|
128
136
|
res.send(
|
|
129
|
-
|
|
137
|
+
indexTemplate({
|
|
130
138
|
cssFiles: self.allCss(),
|
|
131
139
|
jasmineJsFiles: self.jasmineJs(),
|
|
132
140
|
userJsFiles: self.userJs(),
|
|
@@ -137,6 +145,19 @@ class Server {
|
|
|
137
145
|
console.error(error);
|
|
138
146
|
}
|
|
139
147
|
});
|
|
148
|
+
app.get('/__config__/config.js', function(req, res) {
|
|
149
|
+
try {
|
|
150
|
+
res.append('Content-type', 'application/javascript');
|
|
151
|
+
res.send(
|
|
152
|
+
configTemplate({
|
|
153
|
+
envConfig: self.options.env || {},
|
|
154
|
+
})
|
|
155
|
+
);
|
|
156
|
+
} catch (error) {
|
|
157
|
+
res.status(500).send('An error occurred');
|
|
158
|
+
console.error(error);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
140
161
|
|
|
141
162
|
var port = findPort(serverOptions.port, this.options.port);
|
|
142
163
|
return new Promise(resolve => {
|
|
@@ -200,6 +221,10 @@ function findPort(serverPort, optionsPort) {
|
|
|
200
221
|
return 8888;
|
|
201
222
|
}
|
|
202
223
|
|
|
224
|
+
function isUrl(s) {
|
|
225
|
+
return s.startsWith('http://') || s.startsWith('https://');
|
|
226
|
+
}
|
|
227
|
+
|
|
203
228
|
function findFiles(baseDir, globs) {
|
|
204
229
|
const { includeGlobs, excludeGlobs } = globs.reduce(
|
|
205
230
|
function(ongoing, g) {
|
|
@@ -220,12 +245,16 @@ function findFiles(baseDir, globs) {
|
|
|
220
245
|
const result = [];
|
|
221
246
|
|
|
222
247
|
for (const g of includeGlobs) {
|
|
223
|
-
|
|
248
|
+
if (isUrl(g)) {
|
|
249
|
+
result.push(g);
|
|
250
|
+
} else {
|
|
251
|
+
const files = glob.sync(g, { ignore: excludeGlobs, cwd: baseDir });
|
|
224
252
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
253
|
+
for (const f of files) {
|
|
254
|
+
// De-duplicate
|
|
255
|
+
if (result.indexOf(f) === -1) {
|
|
256
|
+
result.push(f);
|
|
257
|
+
}
|
|
229
258
|
}
|
|
230
259
|
}
|
|
231
260
|
}
|
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
|
/**
|
package/package.json
CHANGED
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jasmine-browser-runner",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Serve and run your Jasmine specs in a browser",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
5
|
+
"bin": "bin/jasmine-browser-runner",
|
|
6
|
+
"exports": "./index.js",
|
|
7
7
|
"files": [
|
|
8
8
|
"MIT.LICENSE",
|
|
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",
|
|
@@ -29,25 +32,28 @@
|
|
|
29
32
|
"tdd"
|
|
30
33
|
],
|
|
31
34
|
"engines": {
|
|
32
|
-
"node": ">=
|
|
35
|
+
"node": ">=14"
|
|
33
36
|
},
|
|
34
37
|
"author": "Slackersoft",
|
|
35
38
|
"license": "MIT",
|
|
36
39
|
"bugs": {
|
|
37
|
-
"url": "https://github.com/jasmine/jasmine-browser/issues"
|
|
40
|
+
"url": "https://github.com/jasmine/jasmine-browser-runner/issues"
|
|
38
41
|
},
|
|
39
|
-
"homepage": "https://github.com/jasmine/jasmine-browser#readme",
|
|
42
|
+
"homepage": "https://github.com/jasmine/jasmine-browser-runner#readme",
|
|
40
43
|
"dependencies": {
|
|
41
|
-
"ejs": "^
|
|
44
|
+
"ejs": "^3.1.6",
|
|
42
45
|
"express": "^4.16.4",
|
|
43
46
|
"glob": "^7.1.7",
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
"selenium-webdriver": "^4.1.0"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"jasmine-core": "^3.9.0"
|
|
47
51
|
},
|
|
48
52
|
"devDependencies": {
|
|
49
|
-
"eslint": "^
|
|
50
|
-
"eslint-plugin-jasmine": "^
|
|
53
|
+
"eslint": "^8.3.0",
|
|
54
|
+
"eslint-plugin-jasmine": "^4.1.3",
|
|
55
|
+
"jasmine": "^3.9.0",
|
|
56
|
+
"jasmine-core": "^3.9.0",
|
|
51
57
|
"prettier": "^1.17.1",
|
|
52
58
|
"shelljs": "^0.8.3",
|
|
53
59
|
"temp": "^0.9.4"
|
|
@@ -69,7 +75,7 @@
|
|
|
69
75
|
"expectAsync": "readonly"
|
|
70
76
|
},
|
|
71
77
|
"parserOptions": {
|
|
72
|
-
"ecmaVersion":
|
|
78
|
+
"ecmaVersion": 11
|
|
73
79
|
},
|
|
74
80
|
"plugins": [
|
|
75
81
|
"jasmine"
|
|
@@ -91,7 +97,13 @@
|
|
|
91
97
|
"block-spacing": "error",
|
|
92
98
|
"comma-dangle": [
|
|
93
99
|
"error",
|
|
94
|
-
|
|
100
|
+
{
|
|
101
|
+
"arrays": "always-multiline",
|
|
102
|
+
"objects": "always-multiline",
|
|
103
|
+
"imports": "always-multiline",
|
|
104
|
+
"exports": "always-multiline",
|
|
105
|
+
"functions": "never"
|
|
106
|
+
}
|
|
95
107
|
],
|
|
96
108
|
"func-call-spacing": [
|
|
97
109
|
"error",
|
|
@@ -108,11 +120,13 @@
|
|
|
108
120
|
"space-before-blocks": "error",
|
|
109
121
|
"no-console": "off"
|
|
110
122
|
},
|
|
111
|
-
"overrides":
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
"
|
|
123
|
+
"overrides": [
|
|
124
|
+
{
|
|
125
|
+
"files": "spec/**/*.js",
|
|
126
|
+
"env": {
|
|
127
|
+
"jasmine": true
|
|
128
|
+
}
|
|
115
129
|
}
|
|
116
|
-
|
|
130
|
+
]
|
|
117
131
|
}
|
|
118
132
|
}
|
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_config.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
module.exports =
|
|
2
|
-
'{\n' +
|
|
3
|
-
' "srcDir": "src",\n' +
|
|
4
|
-
' "srcFiles": [\n' +
|
|
5
|
-
' "**/*.?(m)js"\n' +
|
|
6
|
-
' ],\n' +
|
|
7
|
-
' "specDir": "spec",\n' +
|
|
8
|
-
' "specFiles": [\n' +
|
|
9
|
-
' "**/*[sS]pec.?(m)js"\n' +
|
|
10
|
-
' ],\n' +
|
|
11
|
-
' "helpers": [\n' +
|
|
12
|
-
' "helpers/**/*.?(m)js"\n' +
|
|
13
|
-
' ],\n' +
|
|
14
|
-
' "random": true,\n' +
|
|
15
|
-
' "stopSpecOnExpectationFailure": false,\n' +
|
|
16
|
-
' "browser": {\n' +
|
|
17
|
-
' "name": "firefox"\n' +
|
|
18
|
-
' }\n' +
|
|
19
|
-
'}';
|