|
1 | 1 | var util = require('util');
|
2 | 2 | var path = require('path')
|
3 | 3 | var fs = require('fs');
|
4 |
| -var webdriver = require('selenium-webdriver'); |
5 |
| -var remote = require('selenium-webdriver/remote'); |
6 |
| -var minijn = require('minijasminenode'); |
7 |
| -var protractor = require('./protractor.js'); |
8 |
| -var SauceLabs = require('saucelabs'); |
| 4 | +var runner = require('./runner.js'); |
9 | 5 | var glob = require('glob');
|
10 | 6 |
|
11 |
| -var args = process.argv.slice(2); |
12 |
| -var configDir, configPath; |
| 7 | +/** |
| 8 | + * The command line interface for interacting with the Protractor runner. |
| 9 | + * It takes care of parsing the config file and command line options. |
| 10 | + */ |
13 | 11 |
|
14 |
| -var merge = function(into, from) { |
15 |
| - for (key in from) { |
16 |
| - if (into[key] instanceof Object) { |
17 |
| - merge(into[key], from[key]); |
18 |
| - } else { |
19 |
| - into[key] = from[key]; |
20 |
| - } |
21 |
| - } |
22 |
| -}; |
23 |
| - |
24 |
| -// Default configuration. |
25 |
| -var config = { |
26 |
| - seleniumServerJar: null, |
27 |
| - seleniumArgs: [], |
28 |
| - seleniumPort: null, |
29 |
| - seleniumAddress: null, |
30 |
| - allScriptsTimeout: 11000, |
31 |
| - capabilities: { |
32 |
| - 'browserName': 'chrome' |
33 |
| - }, |
34 |
| - rootElement: 'body', |
35 |
| - jasmineNodeOpts: { |
36 |
| - isVerbose: false, |
37 |
| - showColors: true, |
38 |
| - includeStackTrace: true |
39 |
| - } |
40 |
| -} |
41 |
| - |
42 |
| -var originalOnComplete; |
43 |
| -var server; |
44 |
| -var driver; |
45 |
| -var id; |
46 |
| - |
47 |
| -var cleanUp = function(runner, log) { |
48 |
| - if (originalOnComplete) { |
49 |
| - originalOnComplete(runner, log); |
50 |
| - } |
51 |
| - |
52 |
| - var passed = runner.results().failedCount == 0; |
53 |
| - var exitCode = passed ? 0 : 1; |
| 12 | +var args = process.argv.slice(2); |
| 13 | +var configPath; |
54 | 14 |
|
55 |
| - driver.quit().then(function() { |
56 |
| - if (sauceAccount) { |
57 |
| - sauceAccount.updateJob(id, {'passed': passed}, function(err) { |
58 |
| - if (err) { |
59 |
| - throw new Error( |
60 |
| - "Error updating Sauce pass/fail status: " + util.inspect(err) |
61 |
| - ); |
62 |
| - } |
63 |
| - process.exit(exitCode); |
64 |
| - }); |
65 |
| - } else if (server) { |
66 |
| - util.puts('Shutting down selenium standalone server'); |
67 |
| - server.stop().then(function() { |
68 |
| - process.exit(exitCode); |
69 |
| - }); |
70 |
| - } else { |
71 |
| - process.exit(exitCode); |
72 |
| - } |
73 |
| - }); |
74 |
| -}; |
75 | 15 |
|
76 | 16 | var printVersion = function () {
|
77 | 17 | util.puts('Version ' + JSON.parse(
|
78 | 18 | fs.readFileSync(__dirname + '/../package.json', 'utf8')).version);
|
79 | 19 | process.exit(0);
|
80 | 20 | };
|
81 | 21 |
|
82 |
| -var run = function() { |
83 |
| - if (config.jasmineNodeOpts.specFolders) { |
84 |
| - throw new Error('Using config.jasmineNodeOpts.specFolders is deprecated ' + |
85 |
| - 'in Protractor 0.6.0. Please switch to config.specs.'); |
86 |
| - } |
87 |
| - var specs = config.specs; |
88 |
| - var resolvedSpecs = []; |
89 |
| - for (var i = 0; i < specs.length; ++i) { |
90 |
| - var matches = glob.sync(specs[i], {cwd: configDir}); |
91 |
| - if (!matches.length) { |
92 |
| - throw new Error('Test file ' + specs[i] + ' did not match any files.'); |
93 |
| - } |
94 |
| - for (var j = 0; j < matches.length; ++j) { |
95 |
| - resolvedSpecs.push(path.resolve(configDir, matches[j])); |
96 |
| - } |
97 |
| - } |
98 |
| - minijn.addSpecs(resolvedSpecs); |
99 |
| - |
100 |
| - if (config.sauceUser && config.sauceKey) { |
101 |
| - config.capabilities.username = config.sauceUser; |
102 |
| - config.capabilities.accessKey = config.sauceKey; |
103 |
| - if (!config.jasmineNodeOpts.defaultTimeoutInterval) { |
104 |
| - config.jasmineNodeOpts.defaultTimeoutInterval = 30 * 1000; |
105 |
| - } |
106 |
| - config.seleniumAddress = 'http://' + config.sauceUser + ':' + |
107 |
| - config.sauceKey + '@ondemand.saucelabs.com:80/wd/hub'; |
108 |
| - |
109 |
| - util.puts('Using SauceLabs selenium server at ' + config.seleniumAddress); |
110 |
| - startJasmineTests(); |
111 |
| - } else if (config.seleniumAddress) { |
112 |
| - |
113 |
| - util.puts('Using the selenium server at ' + config.seleniumAddress); |
114 |
| - startJasmineTests(); |
115 |
| - } else if (config.seleniumServerJar) { |
116 |
| - util.puts('Starting selenium standalone server...'); |
117 |
| - if (config.chromeDriver) { |
118 |
| - if (!fs.existsSync(config.chromeDriver)) { |
119 |
| - if (fs.existsSync(config.chromeDriver + '.exe')) { |
120 |
| - config.chromeDriver += '.exe'; |
121 |
| - } else { |
122 |
| - throw 'Could not find chromedriver at ' + config.chromeDriver; |
123 |
| - } |
124 |
| - } |
125 |
| - config.seleniumArgs.push( |
126 |
| - '-Dwebdriver.chrome.driver=' + config.chromeDriver); |
127 |
| - } |
128 |
| - server = new remote.SeleniumServer(config.seleniumServerJar, { |
129 |
| - args: config.seleniumArgs, |
130 |
| - port: config.seleniumPort |
131 |
| - }); |
132 |
| - server.start().then(function(url) { |
133 |
| - |
134 |
| - util.puts('Selenium standalone server started at ' + url); |
135 |
| - config.seleniumAddress = server.address(); |
136 |
| - startJasmineTests(); |
137 |
| - }); |
138 |
| - } else { |
139 |
| - throw new Error('You must specify either a seleniumAddress, ' + |
140 |
| - 'seleniumServerJar, or saucelabs account.'); |
141 |
| - } |
142 |
| -} |
143 |
| - |
144 |
| -var startJasmineTests = function() { |
145 |
| - driver = new webdriver.Builder(). |
146 |
| - usingServer(config.seleniumAddress). |
147 |
| - withCapabilities(config.capabilities).build(); |
148 |
| - |
149 |
| - driver.getSession().then(function(session) { |
150 |
| - driver.manage().timeouts().setScriptTimeout(config.allScriptsTimeout); |
151 |
| - |
152 |
| - id = session.getId(); |
153 |
| - |
154 |
| - protractor.setInstance(protractor.wrapDriver(driver, config.baseUrl, config.rootElement)); |
155 |
| - |
156 |
| - // Export protractor to the global namespace to be used in tests. |
157 |
| - global.protractor = protractor; |
158 |
| - |
159 |
| - // Set up the Jasmine WebDriver Adapter. |
160 |
| - require('../jasminewd'); |
161 |
| - |
162 |
| - var options = config.jasmineNodeOpts; |
163 |
| - originalOnComplete = options.onComplete; |
164 |
| - options.onComplete = cleanUp; |
165 |
| - |
166 |
| - // Let the configuration configure the protractor instance before running |
167 |
| - // the tests. |
168 |
| - webdriver.promise.controlFlow().execute(function() { |
169 |
| - if (config.onPrepare) { |
170 |
| - if (typeof config.onPrepare == 'function') { |
171 |
| - config.onPrepare(); |
172 |
| - } else if (typeof config.onPrepare == 'string') { |
173 |
| - require(path.resolve(process.cwd(), config.onPrepare)); |
174 |
| - } else { |
175 |
| - throw 'config.onPrepare must be a string or function'; |
176 |
| - } |
177 |
| - } |
178 |
| - }).then(function() { |
179 |
| - minijn.executeSpecs(options); |
180 |
| - }); |
181 |
| - }); |
182 |
| -} |
183 | 22 |
|
184 | 23 | if (!args.length) {
|
185 |
| - util.puts('USAGE: protractor configFile [options]'); |
| 24 | + util.puts('USAGE: protractor [configFile] [options]'); |
186 | 25 | util.puts('Options:');
|
187 | 26 | util.puts(' --version: Print Protractor version');
|
| 27 | + util.puts(' --browser <string>: Browsername, e.g. chrome or firefox'); |
188 | 28 | util.puts(' --seleniumAddress <string>: A running selenium address to use');
|
189 | 29 | util.puts(' --seleniumServerJar <string>: Location of the standalone selenium server .jar file');
|
190 | 30 | util.puts(' --seleniumPort <string>: Optional port for the standalone selenium server');
|
@@ -232,6 +72,9 @@ while(args.length) {
|
232 | 72 | case '--seleniumPort':
|
233 | 73 | commandLineConfig.seleniumPort = args.shift();
|
234 | 74 | break;
|
| 75 | + case '--chromeDriver': |
| 76 | + commandLineConfig.chromeDriver = args.shift(); |
| 77 | + break; |
235 | 78 | case '--sauceUser':
|
236 | 79 | commandLineConfig.sauceUser = args.shift();
|
237 | 80 | break;
|
@@ -262,24 +105,15 @@ while(args.length) {
|
262 | 105 | break;
|
263 | 106 | default:
|
264 | 107 | configPath = path.resolve(process.cwd(), arg);
|
265 |
| - configDir = path.dirname(configPath); |
266 | 108 | break;
|
267 | 109 | }
|
268 | 110 | }
|
269 | 111 |
|
270 | 112 | if (configPath) {
|
271 |
| - merge(config, require(configPath).config); |
272 |
| -} else { |
273 |
| - configDir = "./"; |
| 113 | + runner.addConfig(require(configPath).config); |
| 114 | + runner.addConfig({specFileBase: path.dirname(configPath)}) |
274 | 115 | }
|
275 |
| -merge(config, commandLineConfig); |
276 | 116 |
|
277 |
| -var sauceAccount; |
278 |
| -if (config.sauceUser && config.sauceKey) { |
279 |
| - sauceAccount = new SauceLabs({ |
280 |
| - username: config.sauceUser, |
281 |
| - password: config.sauceKey |
282 |
| - }); |
283 |
| -} |
| 117 | +runner.addConfig(commandLineConfig); |
284 | 118 |
|
285 |
| -run(); |
| 119 | +runner.runOnce(); |
0 commit comments