This repository was archived by the owner on Feb 2, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 122
/
Copy pathprotractor_runner.js
180 lines (160 loc) · 5.89 KB
/
protractor_runner.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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
* grunt-protractor-runner
* https://github.com/teerapap/grunt-protractor-runner
*
* Copyright (c) 2013 Teerapap Changwichukarn
* Licensed under the MIT license.
*/
'use strict';
var util = require('util');
var path = require('path');
var fs = require('fs');
var split = require('split');
var through2 = require('through2');
module.exports = function(grunt) {
grunt.registerMultiTask('protractor', 'A grunt task to run protractor.', function() {
// '.../node_modules/protractor/lib/protractor.js'
var protractorMainPath = require.resolve('protractor');
// '.../node_modules/protractor/bin/protractor'
var protractorBinPath = path.resolve(protractorMainPath, '../../bin/protractor');
// '.../node_modules/protractor/referenceConf.js'
var protractorRefConfPath = path.resolve(protractorMainPath, '../../referenceConf.js');
// '.../node_modules/protractor/bin/webdriver-manager'
var webdriverManagerPath = path.resolve(protractorMainPath, '../../bin/webdriver-manager');
// Merge task-specific and/or target-specific options with these defaults.
var opts = this.options({
configFile: protractorRefConfPath,
keepAlive: false,
noColor: false,
debug: false,
nodeBin: 'node',
args: {},
output: false,
webdriverManagerUpdate: false
});
// configFile is a special property which need not to be in options{} object.
if (!grunt.util._.isUndefined(this.data.configFile)) {
opts.configFile = this.data.configFile;
}
grunt.verbose.writeln("Options: " + util.inspect(opts));
var keepAlive = opts['keepAlive'];
var strArgs = ["seleniumAddress", "seleniumServerJar", "seleniumPort", "baseUrl", "rootElement", "browser", "chromeDriver", "chromeOnly", "directConnect", "sauceUser", "sauceKey", "sauceSeleniumAddress", "framework", "suite", "beforeLaunch", "onPrepare"];
var listArgs = ["specs", "exclude"];
var boolArgs = ["includeStackTrace", "verbose"];
var objectArgs = ["params", "capabilities", "multiCapabilities", "cucumberOpts", "mochaOpts"];
var args = process.execArgv.concat([protractorBinPath, opts.configFile]);
if (opts.noColor){
args.push('--no-jasmineNodeOpts.showColors');
}
if (!grunt.util._.isUndefined(opts.debug) && opts.debug === true){
args.splice(1,0,'debug');
}
// Iterate over all supported arguments.
strArgs.forEach(function(a) {
if (a in opts.args || grunt.option(a)) {
args.push('--'+a, grunt.option(a) || opts.args[a]);
}
});
listArgs.forEach(function(a) {
if (a in opts.args || grunt.option(a)) {
args.push('--'+a, grunt.option(a) || opts.args[a].join(","));
}
});
boolArgs.forEach(function(a) {
if (a in opts.args || grunt.option(a)) {
args.push('--'+a);
}
});
// Convert [object] to --[object].key1 val1 --[object].key2 val2 ....
objectArgs.forEach(function(a) {
(function convert(prefix, obj, args) {
if (typeof obj === 'string'){
obj = JSON.parse(obj);
}
for (var key in obj) {
var val = obj[key];
var type = typeof obj[key];
if (type === "object") {
if (Array.isArray(val)) {
// Add duplicates --[object].key val1 --[object].key val2 ...
for (var i=0;i<val.length;i++) {
args.push(prefix+"."+key, val[i]);
}
} else {
// Dig deeper
convert(prefix+"."+key, val, args);
}
} else if (type === "undefined" || type === "function") {
// Skip these types
} else if (type === "boolean") {
// Add --[object].key
args.push(prefix+"."+key);
} else {
// Add --[object].key value
args.push(prefix+"."+key, val);
}
}
})("--" + a, grunt.option(a) || opts.args[a], args);
});
// Spawn protractor command
var done = this.async();
var startProtractor = function(){
grunt.verbose.writeln("Spawn node with arguments: " + args.join(" "));
var child = grunt.util.spawn({
cmd: opts.nodeBin,
args: args,
opts: {
stdio:'pipe'
}
},
function(error, result, code) {
if (error) {
grunt.log.error(String(result));
if(code === 1 && keepAlive) {
// Test fails but do not want to stop the grunt process.
grunt.log.oklns("Test failed but keep the grunt process alive.");
} else {
// Test fails and want to stop the grunt process,
// or protractor exited with other reason.
grunt.warn('Tests failed, protractor exited with code: '+code, code);
}
}
done();
done = null;
}
);
process.stdin.pipe(child.stdin);
child.stdout.pipe(process.stdout);
child.stderr.pipe(process.stderr);
// Write the result in the output file
if (!grunt.util._.isUndefined(opts.output) && opts.output !== false) {
grunt.log.writeln("Output test result to: " + opts.output);
grunt.file.mkdir(path.dirname(opts.output));
child.stdout
.pipe(split())
.pipe(through2(function (chunk, encoding, callback) {
if ((/^Using the selenium server at/).test(chunk.toString())) {
// skip
}
else {
this.push(chunk + '\n');
}
callback();
}))
.pipe(fs.createWriteStream(opts.output));
}
};
if (opts.webdriverManagerUpdate) {
grunt.log.writeln('webdriver-manager path: ' + webdriverManagerPath);
grunt.util.spawn({
cmd: opts.nodeBin,
args: [webdriverManagerPath, 'update'],
opts: {
stdio: 'inherit'
}
}, startProtractor);
} else {
startProtractor();
}
});
};