UNPKG

5.55 kBJavaScriptView Raw
1var chai = require('chai')
2var chalk = require('chalk')
3var log = require('npmlog')
4var sauceConnectLauncher = require('sauce-connect-launcher')
5var webdriverio = require('webdriverio')
6
7var chaiAsPromised = require('chai-as-promised')
8chai.use(chaiAsPromised)
9chai.should()
10var request = require('request')
11
12var config = require('./lib/config')
13log.level = config.log.level
14
15var tmp = config.client.split(':')
16var runner = tmp[0] || 'selenium'
17var browser = {
18 name: tmp[1] || 'chrome',
19 browserName: tmp[1] || 'chrome',
20 version: tmp[2] || null, // Latest
21 platform: tmp[3] || null
22}
23
24var options = {
25 baseUrl: 'http://' + config.server.host + ':' + config.server.port,
26 logLevel: config.log.level,
27 desiredCapabilities: browser
28}
29
30log.silly('runner', 'runner is %s', runner)
31log.silly('options', 'set options.baseUrl to %s', options.baseUrl)
32
33if (runner === 'saucelabs') {
34 options.user = config.saucelabs.username
35 options.key = config.saucelabs.accessKey
36
37 log.silly('options', 'set options.user to %s', options.user)
38 log.silly('options', 'set options.key to ***')
39
40 // http://webdriver.io/guide/testrunner/cloudservices.html#With_Travis_CI
41 options.desiredCapabilities['tunnel-identifier'] = config.tunnelId
42 options.desiredCapabilities.build = config.saucelabs.desiredCapabilities.build
43
44 options.desiredCapabilities['idle-timeout'] = config.saucelabs.desiredCapabilities['idle-timeout']
45 options.desiredCapabilities['max-duration'] = config.saucelabs.desiredCapabilities['max-duration']
46 options.desiredCapabilities['command-timeout'] = config.saucelabs.desiredCapabilities['command-timeout']
47}
48
49if (process.env.TRAVIS_JOB_NUMBER) {
50 options.desiredCapabilities.name += ' - ' + process.env.TRAVIS_JOB_NUMBER
51}
52
53log.silly('options', 'set options.desiredCapabilities to %j', options.desiredCapabilities)
54
55var client = webdriverio.remote(options)
56chaiAsPromised.transferPromiseness = client.transferPromiseness
57
58/* global before */
59before(function (done) {
60 var self = this
61
62 this.timeout(config.timeout)
63 this.client = client
64
65 var seleniumRetries = 0
66 var saucelabsRetries = 0
67 var started = function () {
68 if (++seleniumRetries > 60) {
69 done(new Error('Unable to connect to selenium'))
70 return
71 }
72
73 if (runner === 'selenium') {
74 startSelenium(assureServer)
75 } else {
76 startSauceConnect(assureServer)
77 }
78
79 function startSelenium (callback) {
80 log.verbose('test', 'wating for selenium at ' + config.selenium.hub + '...')
81 request(config.selenium.hub, function (_error, response) {
82 if (response && response.statusCode === 200) {
83 log.info('selenium', 'started')
84 return callback()
85 }
86
87 log.verbose('selenium', 'not yet ready ...')
88 setTimeout(started, 1000)
89 })
90 }
91
92 function startSauceConnect (callback) {
93 log.verbose('sauce-connect', 'starting ...')
94 var scOptions = {
95 username: options.user,
96 accessKey: options.key,
97 tunnelIdentifier: config.tunnelId
98 }
99
100 sauceConnectLauncher(scOptions, function (error) {
101 if (!error) {
102 return callback()
103 }
104
105 if (/Not authorized/i.test(error.message)) {
106 log.error('sauce-connect', error)
107 return process.exit(1)
108 }
109
110 if (++saucelabsRetries > 10) {
111 log.error('sauce-connect', 'Failed to connect in 10 attempts')
112 log.error('sauce-connect', error)
113 return process.exit(1)
114 }
115
116 log.warn('sauce-connect', 'Failed to connect')
117 log.warn('sauce-connect', error)
118 log.warn('sauce-connect', 'Retry ' + saucelabsRetries + '/10 in 1 minute')
119
120 setTimeout(startSauceConnect.bind(null, callback), 60 * 1000)
121 })
122 }
123
124 function assureServer () {
125 var url = 'http://' + config.server.host + ':' + config.server.port
126 log.verbose('test', 'waiting for server at ' + url + ' ...')
127 request({
128 url: url,
129 headers: {
130 Accept: 'text/html'
131 }
132 }, function (error, response, body) {
133 if (response && response.statusCode === 200) {
134 log.info('test', 'server found')
135 return startTest()
136 }
137
138 if (error) {
139 log.verbose('test', error)
140 } else {
141 log.warn('test', 'server returns ' + response.statusCode + ' but tests expect 200')
142 log.verbose('test', body)
143 }
144
145 log.verbose('test', 'not yet ready, checking again ...')
146 setTimeout(assureServer, 1000)
147 })
148 }
149
150 function startTest () {
151 self.client.on('command', function (command) {
152 log.info('selenium', chalk.cyan(command.method), command.uri.path)
153
154 if (command.data.script) {
155 command.data.script = getScriptName(command.data.script)
156 }
157 log.info('selenium', command.data)
158 })
159 self.client.on('erorr', function (error) {
160 log.error('selenium', chalk.red(error.body.value.class), error.body.value.message)
161 })
162
163 self.client
164 .init()
165
166 // http://webdriver.io/api/protocol/timeouts.html
167 .timeouts('script', config.timeout)
168 .timeouts('implicit', config.timeout)
169 .timeouts('page load', config.timeout)
170
171 .then(function () {
172 done()
173 })
174 }
175
176 function getScriptName (script) {
177 var matches = script.match(/return \(function (\w+)/)
178 return matches ? matches[1] : '[function]'
179 }
180 }
181
182 started()
183})
184
185/* global after */
186after(function (done) {
187 this.client.end(done)
188})