UNPKG

airtap-sauce-browsers

Version:

Get a list of normalized Sauce Labs browsers as browser manifests

203 lines (171 loc) 6.99 kB
'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) }