-
Notifications
You must be signed in to change notification settings - Fork 25
/
index.js
150 lines (130 loc) · 4.45 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
const ConsoleReporter = require('./lib/console_reporter');
const webdriverModule = require('./lib/webdriver');
const Server = require('./lib/server');
const Runner = require('./lib/runner');
const ModuleLoader = require('./lib/moduleLoader');
async function createReporters(options, deps) {
const result = [];
if (options.useConsoleReporter !== false) {
deps = deps || {};
const ReporterCtor = deps.ConsoleReporter || ConsoleReporter;
const consoleReporter = new ReporterCtor();
consoleReporter.setOptions({
color: options.color,
alwaysListPendingSpecs: options.alwaysListPendingSpecs,
});
result.push(consoleReporter);
}
if (options.reporters) {
// Resolve relative paths relative to the cwd, rather than the default
// which is the directory containing the moduleLoader module.
const loader = new ModuleLoader(process.cwd());
for (const reporterOrModuleName of options.reporters) {
if (typeof reporterOrModuleName === 'object') {
result.push(reporterOrModuleName);
} else {
try {
const Reporter = await loader.load(reporterOrModuleName);
result.push(new Reporter());
} catch (e) {
throw new Error(
`Failed to register reporter ${reporterOrModuleName}: ${e.message}`
);
}
}
}
}
if (result.length === 0) {
throw new Error(
'No reporters were specified. Either add a reporter or remove ' +
'`useConsoleReporter: false`.'
);
}
return result;
}
/**
* @module jasmine-browser-runner
*/
module.exports = {
/**
* Starts a {@link Server} that will serve the specs and supporting files via HTTP.
* @param {ServerCtorOptions} options to use to construct the server
* @return {Promise<undefined>} A promise that is resolved when the server is
* started.
*/
startServer: function(options) {
const server = new Server(options);
return server.start();
},
/**
* Runs the specs.
* @param {Configuration} options
* @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.
*/
runSpecs: async function(options, deps) {
options = { ...options };
deps = deps || {};
const useRemote = options.browser && options.browser.useRemoteSeleniumGrid;
if (!options.port) {
if (useRemote) {
options.port = 5555;
} else {
options.port = 0;
}
}
const ServerClass = deps.Server || Server;
const RunnerClass = deps.Runner || Runner;
const buildWebdriver =
deps.buildWebdriver || webdriverModule.buildWebdriver;
const setExitCode = deps.setExitCode || (code => (process.exitCode = code));
const server = new ServerClass(options);
const reporters = await createReporters(options, deps);
const useSauceCompletionReporting =
useRemote &&
options.browser.remoteSeleniumGrid?.url?.includes('saucelabs.com');
await server.start();
try {
const webdriver = buildWebdriver(options.browser);
try {
const host = `${server.scheme()}://${server.hostname()}:${server.port()}`;
const runner = new RunnerClass({ webdriver, reporters, host });
console.log('Running tests in the browser...');
const details = await runner.run(options);
// Use 0 only for complete success
// Avoid 1 because Node uses that for unhandled exceptions etc., and
// some users have CI systems that want to distinguish between spec
// failures and crashes.
if (details.overallStatus === 'passed') {
setExitCode(0);
} else if (anyLoadErrors(details)) {
// Use node's general failure code
setExitCode(1);
} else if (details.overallStatus === 'incomplete') {
setExitCode(2);
} else {
setExitCode(3);
}
return details;
} finally {
if (useSauceCompletionReporting) {
await webdriver.executeScript(
`sauce:job-result=${process.exitCode === 0}`
);
}
await webdriver.close();
}
} finally {
await server.stop();
}
},
Server,
Runner,
ConsoleReporter,
};
function anyLoadErrors(jasmineDoneInfo) {
const failures = jasmineDoneInfo.failedExpectations || [];
const loadError = failures.find(function(fe) {
return fe.globalErrorType === 'load';
});
return !!loadError;
}