1 | #!/usr/bin/env node
|
2 | 'use strict';
|
3 |
|
4 | var path = require('path');
|
5 | var spawn = require('child_process').spawn;
|
6 |
|
7 | var wd = require('wd');
|
8 | wd.configureHttp({timeout: 180000});
|
9 | var sauceConnectLauncher = require('sauce-connect-launcher');
|
10 | var querystring = require('querystring');
|
11 | var request = require('request').defaults({json: true});
|
12 |
|
13 | var devServer = require('http-server');
|
14 |
|
15 | var SELENIUM_PATH = '../vendor/selenium-server-standalone-2.43.0.jar';
|
16 | var SELENIUM_HUB = 'http://localhost:4444/wd/hub/status';
|
17 |
|
18 | var testTimeout = 30 * 60 * 1000;
|
19 |
|
20 | var username = process.env.SAUCE_USERNAME;
|
21 | var accessKey = process.env.SAUCE_ACCESS_KEY;
|
22 |
|
23 |
|
24 | var bail = process.env.BAIL !== '0';
|
25 |
|
26 |
|
27 |
|
28 | var tmp = (process.env.CLIENT || 'selenium:firefox').split(':');
|
29 | var client = {
|
30 | runner: tmp[0] || 'selenium',
|
31 | browser: tmp[1] || 'firefox',
|
32 | version: tmp[2] || null,
|
33 | platform: tmp[3] || null
|
34 | };
|
35 |
|
36 | var testUrl = 'http://127.0.0.1:8000/tests/';
|
37 | var qs = {};
|
38 |
|
39 | var sauceClient;
|
40 | var sauceConnectProcess;
|
41 | var tunnelId = process.env.TRAVIS_JOB_NUMBER || 'tunnel-' + Date.now();
|
42 |
|
43 | if (client.runner === 'saucelabs') {
|
44 | qs.saucelabs = true;
|
45 | }
|
46 | if (process.env.GREP) {
|
47 | qs.grep = process.env.GREP;
|
48 | }
|
49 | if (process.env.ADAPTERS) {
|
50 | qs.adapters = process.env.ADAPTERS;
|
51 | }
|
52 | if (process.env.ES5_SHIM || process.env.ES5_SHIMS) {
|
53 | qs.es5shim = true;
|
54 | }
|
55 | if (process.env.AUTO_COMPACTION) {
|
56 | qs.autoCompaction = true;
|
57 | }
|
58 | if (process.env.SERVER) {
|
59 | qs.SERVER = process.env.SERVER;
|
60 | }
|
61 |
|
62 | testUrl += '?';
|
63 | testUrl += querystring.stringify(qs);
|
64 |
|
65 | if (process.env.TRAVIS &&
|
66 | client.runner === 'saucelabs' &&
|
67 | process.env.TRAVIS_SECURE_ENV_VARS === 'false') {
|
68 | console.error('Not running test, cannot connect to saucelabs');
|
69 | process.exit(0);
|
70 | return;
|
71 | }
|
72 |
|
73 | function testError(e) {
|
74 | console.error(e);
|
75 | console.error('Doh, tests failed');
|
76 | sauceClient.quit();
|
77 | process.exit(3);
|
78 | }
|
79 |
|
80 | function testComplete(result) {
|
81 | console.log(result);
|
82 |
|
83 | sauceClient.quit().then(function () {
|
84 | if (sauceConnectProcess) {
|
85 | sauceConnectProcess.close(function() {
|
86 | process.exit(result.failed ? 1 : 0);
|
87 | });
|
88 | } else {
|
89 | process.exit(result.failed ? 1 : 0);
|
90 | }
|
91 | });
|
92 | }
|
93 |
|
94 | function startSelenium(callback) {
|
95 |
|
96 |
|
97 | spawn('java', ['-jar', path.resolve(__dirname, SELENIUM_PATH)], {});
|
98 |
|
99 | var retries = 0;
|
100 | var started = function () {
|
101 |
|
102 | if (++retries > 60) {
|
103 | console.error('Unable to connect to selenium');
|
104 | process.exit(1);
|
105 | return;
|
106 | }
|
107 |
|
108 | request(SELENIUM_HUB, function (err, resp) {
|
109 | if (resp && resp.statusCode === 200) {
|
110 | sauceClient = wd.promiseChainRemote();
|
111 | callback();
|
112 | } else {
|
113 | setTimeout(started, 1000);
|
114 | }
|
115 | });
|
116 | };
|
117 |
|
118 | started();
|
119 |
|
120 | }
|
121 |
|
122 | function startSauceConnect(callback) {
|
123 |
|
124 | var options = {
|
125 | username: username,
|
126 | accessKey: accessKey,
|
127 | tunnelIdentifier: tunnelId
|
128 | };
|
129 |
|
130 | sauceConnectLauncher(options, function (err, process_) {
|
131 | if (err) {
|
132 | console.error('Failed to connect to saucelabs');
|
133 | console.error(err);
|
134 | return process.exit(1);
|
135 | }
|
136 | sauceConnectProcess = process_;
|
137 | sauceClient = wd.promiseChainRemote('localhost', 4445, username, accessKey);
|
138 | callback();
|
139 | });
|
140 | }
|
141 |
|
142 | function startTest() {
|
143 |
|
144 | console.log('Starting', client);
|
145 |
|
146 | var opts = {
|
147 | browserName: client.browser,
|
148 | version: client.version,
|
149 | platform: client.platform,
|
150 | tunnelTimeout: testTimeout,
|
151 | name: client.browser + ' - ' + tunnelId,
|
152 | 'max-duration': 60 * 45,
|
153 | 'command-timeout': 599,
|
154 | 'idle-timeout': 599,
|
155 | 'tunnel-identifier': tunnelId
|
156 | };
|
157 |
|
158 | sauceClient.init(opts).get(testUrl, function () {
|
159 |
|
160 |
|
161 | var interval = setInterval(function () {
|
162 | sauceClient.eval('window.results', function (err, results) {
|
163 | if (err) {
|
164 | clearInterval(interval);
|
165 | testError(err);
|
166 | } else if (results.completed || (results.failures.length && bail)) {
|
167 | clearInterval(interval);
|
168 | testComplete(results);
|
169 | } else {
|
170 | console.log('=> ', results);
|
171 | }
|
172 | });
|
173 | }, 10 * 1000);
|
174 | });
|
175 | }
|
176 |
|
177 | devServer.createServer().listen(8000, '127.0.0.1', function() {
|
178 | if (client.runner === 'saucelabs') {
|
179 | startSauceConnect(startTest);
|
180 | } else {
|
181 | startSelenium(startTest);
|
182 | }
|
183 | });
|