This repository has been archived by the owner on Jan 3, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathplugin.js
128 lines (109 loc) · 4.56 KB
/
plugin.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
/**
* @license
* Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
var _ = require('lodash');
var request = require('request');
var browsers = require('./browsers');
var sauce = require('./sauce');
/** WCT plugin that enables support for remote browsers via Sauce Labs. */
module.exports = function(wct, pluginOptions) {
// The capabilities objects for browsers to run. We don't know the tunnel id
// until `prepare`, so we've gotta hang onto them.
var eachCapabilities = [];
wct.hook('configure', function(done) {
if (!pluginOptions.browsers || pluginOptions.browsers.length === 0) return done();
expandOptions(pluginOptions);
browsers.expand(pluginOptions, function(error, expanded) {
if (error) return done(error);
wct.emit('log:debug', 'Using sauce browsers:', expanded);
// We are careful to append these to the configuration object, even though
// we don't know the tunnel id yet. This allows WCT to give a useful error
// if no browsers were configured.
var activeBrowsers = wct.options.activeBrowsers;
activeBrowsers.push.apply(activeBrowsers, expanded);
// But we still need to inject the sauce tunnel ID once we know it.
eachCapabilities = expanded;
done();
});
});
wct.hook('prepare', function(done) {
// Don't bother spinning up the tunnel if we don't have any browsers talking
// over it.
if (eachCapabilities.length === 0) return done();
// Is there already an active sauce tunnel?
if (pluginOptions.tunnelId) {
_injectTunnelId(eachCapabilities, pluginOptions.tunnelId);
return done();
}
// Let anyone know, and give them a chance to modify the options prior to
// booting up the Sauce Connect tunnel.
wct.emitHook('prepare:sauce-tunnel', function(error) {
if (error) return done(error);
sauce.startTunnel(pluginOptions, wct, function(error, tunnelId) {
if (error) return done(error);
_injectTunnelId(eachCapabilities, tunnelId);
done();
});
});
});
wct.on('browser-start', function(def, data, stats, browser) {
if (!browser) return;
// Bump the connection periodically to advance Sauce's remote timeout.
browser._keepalive = setInterval(function(){
browser.title(function() {});
}, (def.testTimeout / 2) || 45 * 1000);
// do not let the keepalive hang node
browser._keepalive.unref();
});
wct.on('browser-end', function(def, error, stats, sessionId, browser) {
if (eachCapabilities.length === 0 || !sessionId) return;
if (browser._keepalive) {
clearInterval(browser._keepalive);
}
var payload = {
passed: (stats.status === 'complete' && stats.failing === 0),
"public": pluginOptions.visibility,
build: parseInt(""+pluginOptions.buildNumber),
name: pluginOptions.jobName
};
wct.emit('log:debug', 'Updating sauce job', sessionId, payload);
// Send the pass/fail info to sauce-labs if we are testing remotely.
var username = wct.options.plugins.sauce.username;
var accessKey = wct.options.plugins.sauce.accessKey;
request.put({
url: 'https://saucelabs.com/rest/v1/' + encodeURIComponent(username) + '/jobs/' + encodeURIComponent(sessionId),
auth: {user: username, pass: accessKey},
json: true,
body: payload,
});
});
};
function expandOptions(options) {
_.defaults(options, {
username: process.env.SAUCE_USERNAME,
accessKey: process.env.SAUCE_ACCESS_KEY,
// Under Travis CI, the tunnel id is $TRAVIS_JOB_NUMBER: https://docs.travis-ci.com/user/sauce-connect
tunnelId: process.env.SAUCE_TUNNEL_ID || process.env.TRAVIS_JOB_NUMBER,
buildNumber: process.env.TRAVIS_BUILD_NUMBER,
jobName: process.env.TRAVIS_JOB_ID,
visibility: "public"
});
}
/**
* @param {!Array<!Object>} eachCapabilities
* @param {string} tunnelId
*/
function _injectTunnelId(eachCapabilities, tunnelId) {
eachCapabilities.forEach(function(browser) {
browser['tunnel-identifier'] = tunnelId;
});
}
// Hacks for the wct-st binary.
module.exports.expandOptions = expandOptions;
module.exports.startTunnel = sauce.startTunnel;