-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
202 lines (171 loc) · 6.83 KB
/
index.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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
'use strict'
const b = require('browser-names')
const fetch = require('minipass-fetch')
function factory (source) {
return {
callback (callback) {
source()
.then(manifests => process.nextTick(callback, null, normalize(manifests)))
.catch(err => process.nextTick(callback, err))
},
async promise () {
return normalize(await source())
},
factory
}
}
module.exports = factory(async function () {
const res = await fetch('https://saucelabs.com/rest/v1/info/platforms/all')
return res.json()
})
// See https://wiki.saucelabs.com/display/DOCS/Test+Configuration+Options
// See https://wiki.saucelabs.com/display/DOCS/Platform+Information+Methods#PlatformInformationMethods-GetSupportedPlatforms
// See https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/
function normalize (manifests) {
// Android 6.0 defaults to Chrome but can also be paired with Android Browser.
// This is not reflected in the Sauce Labs API.
// See https://wiki.saucelabs.com/display/DOCS/2017/03/31/Android+6.0+and+7.0+Support+Released
manifests.filter(manifest =>
manifest.automation_backend === 'appium' &&
is(manifest.api_name, 'android') &&
major(manifest.short_version) === 6
).forEach(manifest => {
manifests.push({ ...manifest, browser_name: 'Browser' })
})
return manifests.map(function (manifest) {
const automationBackend = manifest.automation_backend
const lowApiName = manifest.api_name.toLowerCase()
const capabilities = {}
// The version of a browser or device
const version = manifest.short_version.replace(/\.$/, '')
if (automationBackend !== 'webdriver' && automationBackend !== 'appium') {
// Can't happen, at the time of writing.
return null
}
if (manifest.device || automationBackend === 'appium') {
// I don't know why Sauce Labs returns mobile devices with a webdriver
// backend, while it would actually use appium. Let's ignore these.
if (automationBackend !== 'appium') return null
// Capabilities for Appium
// See http://appium.io/docs/en/writing-running-appium/caps/index.html
// See https://wiki.saucelabs.com/display/DOCS/Test+Configuration+Options#TestConfigurationOptions-Appium-SpecificOptions
capabilities.appium = {}
if (lowApiName === 'ipad' || lowApiName === 'iphone') {
capabilities.appium.browserName = 'Safari'
capabilities.appium.platformName = 'iOS'
} else if (lowApiName === 'android') {
// "Browser" is aka "Android Browser"
capabilities.appium.browserName = manifest.browser_name ||
(major(version) >= 6 ? 'Chrome' : 'Browser')
capabilities.appium.platformName = 'Android'
} else {
// Something new
return null
}
// Note: on Android, there's no way to specify the Chrome version
// (e.g. 78). We can only match by Android version (e.g. 7).
capabilities.appium.platformVersion = version
capabilities.appium.deviceName = manifest.long_name
} else {
// Capabilities for Selenium 2/3
// See https://wiki.saucelabs.com/display/DOCS/Test+Configuration+Options#TestConfigurationOptions-Selenium-SpecificOptions
// See https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities
capabilities.legacy = {
// Selenium is case-sensitive. Use the original values.
browserName: manifest.api_name,
version: version,
platform: manifest.os
}
// Capabilities for W3C WebDriver
// See https://wiki.saucelabs.com/display/DOCS/W3C+Capabilities+Support
if ((is(manifest.api_name, 'firefox') && major(version) >= 53) ||
(is(manifest.api_name, 'chrome') && major(version) >= 61) ||
(is(manifest.api_name, 'internet explorer') && major(version) === 11)) {
capabilities.w3c = {
browserName: manifest.api_name,
browserVersion: version,
platformName: manifest.os
}
// "For tests on Google Chrome version 74 or lower.."
if (is(manifest.api_name, 'chrome') && major(version) <= 74) {
// ".. the W3C capability must be set as an experimental option"
capabilities.w3c.w3c = true
}
}
}
const name = getName(lowApiName, automationBackend, capabilities)
const title = getTitle(name, capabilities)
// For mobile (appium) devices, "manifest.os" is the host OS that runs
// the emulator or simulator. Use Appium's platform name instead.
const platform = (capabilities.appium ? capabilities.appium.platformName : manifest.os).toLowerCase()
// Exclude Safari 11 on Mac 10.12 because it throws an error upon console.log() which
// is caused by the WebDriver extension that Sauce Labs has installed on MacOS 10.12
// but luckily not on 10.13, so Safari 11 can be tested on 10.13 instead.
// See https://github.com/apache/cordova-plugin-media-capture/issues/105#issuecomment-425052111
if (name === 'safari' && platform === 'mac 10.12' && major(version) === 11) {
return null
}
const result = {
name,
version,
platform,
title,
wants: {
loopback: [
'safari',
'edge',
'chrome',
'and_chr',
'firefox'
].includes(name),
tunnel: true,
secureEnv: true
},
automationBackend,
capabilities
}
if (manifest.recommended_backend_version) {
result.recommendedBackendVersion = manifest.recommended_backend_version
}
// Excluded for now because behavior of array matching is TBD
// if (manifest.supported_backend_versions) {
// result.supportedBackendVersions = manifest.supported_backend_versions
// }
return result
}).filter(Boolean)
}
function is (a, b) {
return a.toLowerCase() === b.toLowerCase()
}
function major (version) {
return parseInt(version, 10)
}
function getName (lowApiName, automationBackend, capabilities) {
if (automationBackend === 'appium') {
if (is(capabilities.appium.platformName, 'android')) {
if (is(capabilities.appium.browserName, 'chrome')) {
return 'and_chr'
} else if (is(capabilities.appium.browserName, 'browser')) {
return 'android'
}
}
if (is(capabilities.appium.platformName, 'ios')) {
return 'ios_saf'
}
}
return b.common(lowApiName) || lowApiName
}
function getTitle (name, capabilities) {
if (capabilities.appium) {
const c = capabilities.appium
const browserTitle = b.title(name) || ucfirst(c.browserName)
return `Sauce Labs ${browserTitle} on ${c.platformName} ${c.platformVersion} on ${c.deviceName}`
} else {
const c = capabilities.legacy
const browserTitle = b.title(name) || ucfirst(c.browserName)
return `Sauce Labs ${browserTitle} ${c.version} on ${c.platform}`
}
}
function ucfirst (str) {
return str[0].toUpperCase() + str.slice(1)
}