ci: move local and saucelabs unit tests to circle (#27937)

Moving the tests over to CircleCI in pretty much "as-is" state just so that we can drop the dependency on Travis.

In the followup changes we plan to migrate these tests to run on sauce under bazel. @gregmagolan is working on that.

I've previously verified that all the tests executed in legacy-unit-tests-local already under bazel.
Therefore the legacy-unit-tests-local job is strictly not necessary any more, but given how flaky legacy-unit-tests-saucelabs is,
it is good to have the -local job just so that we can quickly determine if any failure is a flake or legit issue
(the bazel version of these tests could theoretically run in a slightly different way and fail or not fail in a different way, so having -lcoal job is just an extra safety check).

This change was coauthored with @devversion

PR Close #27937
This commit is contained in:
Igor Minar 2019-01-04 11:58:33 -08:00 committed by Kara Erickson
parent c1dacdd890
commit 04ca3bcf10
17 changed files with 205 additions and 346 deletions

View File

@ -399,6 +399,54 @@ jobs:
command: 'curl --request POST --header "Content-Type: application/json" --data "{\"text\":\":x: \`$CIRCLE_JOB\` job failed on build $CIRCLE_BUILD_NUM: $CIRCLE_BUILD_URL :scream:\"}" $CI_SECRET_SLACK_CARETAKER_WEBHOOK_URL'
when: on_fail
legacy-unit-tests-local:
<<: *job_defaults
docker:
- image: *browsers_docker_image
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *yarn_install
- run: yarn tsc -p packages
- run: yarn tsc -p packages/examples
- run: yarn tsc -p modules
- run: yarn karma start ./karma-js.conf.js --single-run --browsers=ChromeNoSandbox
legacy-unit-tests-saucelabs:
<<: *job_defaults
# In order to avoid the bottleneck of having a slow host machine, we acquire a better
# container for this job. This is necessary because we launch a lot of browsers concurrently
# and therefore the tunnel and Karma need to process a lot of file requests and tests.
resource_class: xlarge
steps:
- checkout:
<<: *post_checkout
- restore_cache:
key: *cache_key
- *define_env_vars
- *yarn_install
- run:
name: Preparing environment for running tests on Saucelabs.
command: |
setPublicVar KARMA_JS_BROWSERS $(node -e 'console.log(require("./browser-providers.conf").sauceAliases.CI_REQUIRED.join(","))')
setSecretVar SAUCE_ACCESS_KEY $(echo $SAUCE_ACCESS_KEY | rev)
- run:
name: Starting Saucelabs tunnel
command: ./scripts/saucelabs/start-tunnel.sh
background: true
- run: yarn tsc -p packages
- run: yarn tsc -p packages/examples
- run: yarn tsc -p modules
# Waits for the Saucelabs tunnel to be ready. This ensures that we don't run tests
# too early without Saucelabs not being ready.
- run: ./scripts/saucelabs/wait-for-tunnel.sh
- run: yarn karma start ./karma-js.conf.js --single-run --browsers=${KARMA_JS_BROWSERS}
- run: ./scripts/saucelabs/stop-tunnel.sh
workflows:
version: 2
default_workflow:
@ -408,6 +456,8 @@ workflows:
- test_ivy_aot
- build-packages-dist
- test_aio
- legacy-unit-tests-local
- legacy-unit-tests-saucelabs
- deploy_aio:
requires:
- test_aio
@ -451,6 +501,9 @@ workflows:
# Get the artifacts to publish from the build-packages-dist job
# since the publishing script expects the legacy outputs layout.
- build-packages-dist
- legacy-unit-tests-local
- legacy-unit-tests-saucelabs
aio_monitoring:
jobs:
@ -462,3 +515,9 @@ workflows:
branches:
only:
- master
# TODO:
# - don't build the g3 branch
# - verify that we are bootstrapping with the right yarn version coming from the docker image
# - check local chrome version pulled from docker image
# - remove /tools/ngcontainer

View File

@ -9,6 +9,8 @@ echo "source $envHelpersPath;" >> $BASH_ENV;
####################################################################################################
# Define PUBLIC environment variables for CircleCI.
####################################################################################################
# See https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables for more info.
####################################################################################################
setPublicVar PROJECT_ROOT "$(pwd)";
setPublicVar CI_AIO_MIN_PWA_SCORE "95";
# This is the branch being built; e.g. `pull/12345` for PR builds.
@ -31,5 +33,26 @@ setSecretVar CI_SECRET_PAYLOAD_FIREBASE_TOKEN "$ANGULAR_PAYLOAD_TOKEN";
setSecretVar CI_SECRET_SLACK_CARETAKER_WEBHOOK_URL "$SLACK_CARETAKER_WEBHOOK_URL";
####################################################################################################
# Define SauceLabs environment variables for CircleCI.
####################################################################################################
# In order to have a meaningful SauceLabs badge on the repo page,
# the angular2-ci account is used only when pushing commits to master;
# in all other cases, the regular angular-ci account is used.
if [ "${CI_PULL_REQUEST}" = "false" ] && [ "${CI_REPO_OWNER}" = "angular" ] && [ "${CI_BRANCH}" = "master" ]; then
setPublicVar SAUCE_USERNAME "angular2-ci";
setSecretVar SAUCE_ACCESS_KEY "693ebc16208a-0b5b-1614-8d66-a2662f4e";
else
setPublicVar SAUCE_USERNAME "angular-ci";
setSecretVar SAUCE_ACCESS_KEY "9b988f434ff8-fbca-8aa4-4ae3-35442987";
fi
setPublicVar SAUCE_READY_FILE /tmp/angular/sauce-connect-ready-file.lock
setPublicVar SAUCE_PID_FILE /tmp/angular/sauce-connect-pid-file.lock
setPublicVar SAUCE_TUNNEL_IDENTIFIER "angular-${CIRCLE_BUILD_NUM}-${CIRCLE_NODE_INDEX}"
# Amount of seconds we wait for sauceconnect to establish a tunnel instance. In order to not
# acquire CircleCI instances for too long if sauceconnect failed, we need a connect timeout.
setPublicVar SAUCE_READY_FILE_TIMEOUT 120
# Source `$BASH_ENV` to make the variables available immediately.
source $BASH_ENV;

View File

@ -1,58 +1,11 @@
language: node_js
sudo: false
dist: trusty
node_js:
- '10.9.0'
addons:
# firefox: "38.0"
apt:
sources:
# needed to install g++ that is used by npms's native modules
- ubuntu-toolchain-r-test
packages:
# needed to install g++ that is used by npms's native modules
- g++-4.8
branches:
except:
- g3
cache:
yarn: true
directories:
- ./node_modules
- ./.chrome/chromium
- ./aio/node_modules
env:
global:
# GITHUB_TOKEN_ANGULAR=<github token, a personal access token of the angular-builds account, account access in valentine>
# This is needed for the e2e Travis matrix task to publish packages to github for continuous packages delivery.
- secure: "aCdHveZuY8AT4Jr1JoJB4LxZsnGWRe/KseZh1YXYe5UtufFCtTVHvUcLn0j2aLBF0KpdyS+hWf0i4np9jthKu2xPKriefoPgCMpisYeC0MFkwbmv+XlgkUbgkgVZMGiVyX7DCYXVahxIoOUjVMEDCbNiHTIrfEuyq24U3ok2tHc="
matrix:
# Order: a slower build first, so that we don't occupy an idle travis worker waiting for others to complete.
- CI_MODE=e2e
- CI_MODE=js
- CI_MODE=saucelabs_required
# deactivated, see #19768
# - CI_MODE=browserstack_required
# We disable these optional jobs because those acquire tunnel and browser instances which
# could lead to rate limit excess while those are failing most of the time and nobody pays
# attention anyway.
# - CI_MODE=saucelabs_optional
# - CI_MODE=browserstack_optional
matrix:
fast_finish: true
allow_failures:
- env: "CI_MODE=saucelabs_optional"
- env: "CI_MODE=browserstack_optional"
before_install:
# source the env.sh script so that the exported variables are available to other scripts later on
- source ./scripts/ci/env.sh print
install:
- ./scripts/ci/install.sh

View File

@ -144,20 +144,19 @@ module.exports = function(config) {
browserNoActivityTimeout: 300000,
});
if (process.env.TRAVIS) {
var buildId =
'TRAVIS #' + process.env.TRAVIS_BUILD_NUMBER + ' (' + process.env.TRAVIS_BUILD_ID + ')';
if (process.env.CI_MODE.startsWith('saucelabs')) {
config.sauceLabs.build = buildId;
config.sauceLabs.tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER;
if (process.env.CIRCLECI) {
const tunnelIdentifier = process.env['SAUCE_TUNNEL_IDENTIFIER'];
// Setup the Saucelabs plugin so that it can launch browsers using the proper tunnel.
config.sauceLabs.build = tunnelIdentifier;
config.sauceLabs.tunnelIdentifier = tunnelIdentifier;
// Setup the Browserstack plugin so that it can launch browsers using the proper tunnel.
// TODO: This is currently not used because BS doesn't run on the CI. Consider removing.
config.browserStack.build = tunnelIdentifier;
config.browserStack.tunnelIdentifier = tunnelIdentifier;
// Try "websocket" for a faster transmission first. Fallback to "polling" if necessary.
config.transports = ['websocket', 'polling'];
}
if (process.env.CI_MODE.startsWith('browserstack')) {
config.browserStack.build = buildId;
config.browserStack.tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER;
}
}
};

View File

@ -133,6 +133,7 @@
"rollup-plugin-node-resolve": "3.0.0",
"rollup-plugin-sourcemaps": "0.4.2",
"rxjs": "^6.3.0",
"sauce-connect": "https://saucelabs.com/downloads/sc-4.5.2-linux.tar.gz",
"semver": "5.4.1",
"systemjs": "0.18.10",
"tslint": "5.7.0",

View File

@ -0,0 +1,26 @@
# Legacy docs for @angular/compiler-cli Developers
*Note from Igor: This doc is likely outdated now but I'm keeping it around because offline_compiler_test.sh need to be converted to bazel/circleci (or deleted) and these docs seem relevant to anyone who needs to understand those tests. Once that's done this file can be deleted.*
```
# Build Angular and the compiler
./build.sh
# Run the test once
# (First edit the LINKABLE_PKGS to use npm link instead of npm install)
$ ./scripts/ci/offline_compiler_test.sh
# Keep a package fresh in watch mode
./node_modules/.bin/tsc -p packages/compiler/tsconfig-build.json -w
# Recompile @angular/core module (needs to use tsc-ext to keep the metadata)
$ export NODE_PATH=${NODE_PATH}:$(pwd)/dist/all:$(pwd)/dist/tools
$ node dist/tools/@angular/compiler-cli/src/main -p packages/core/tsconfig-build.json
# Iterate on the test
$ cd /tmp/wherever/e2e_test.1464388257/
$ ./node_modules/.bin/ngc
$ ./node_modules/.bin/jasmine test/*_spec.js
```

View File

@ -1,139 +0,0 @@
# Angular Template Compiler
Angular applications are built with templates, which may be `.html` or `.css` files,
or may be inline `template` attributes on Decorators like `@Component`.
These templates are compiled into executable JS at application runtime (except in `interpretation` mode).
This compilation can occur on the client, but it results in slower bootstrap time, and also
requires that the compiler be included in the code downloaded to the client.
You can produce smaller, faster applications by running Angular's compiler as a build step,
and then downloading only the executable JS to the client.
## Install and use
```
# First install angular, see https://github.com/angular/angular/blob/master/CHANGELOG.md#200-rc0-2016-05-02
$ npm install @angular/compiler-cli typescript@next @angular/platform-server @angular/compiler
# Optional sanity check, make sure TypeScript can compile.
$ ./node_modules/.bin/tsc -p path/to/project
# ngc is a drop-in replacement for tsc.
$ ./node_modules/.bin/ngc -p path/to/project
```
In order to write a `bootstrap` that imports the generated code, you should first write your
top-level component, and run `ngc` once to produce a generated `.ngfactory.ts` file.
Then you can add an import statement in the `bootstrap` allowing you to bootstrap off the
generated code:
```typescript
main.module.ts
-------------
import {BrowserModule} from '@angular/platform-browser';
import {Component, NgModule, ApplicationRef} from '@angular/core';
@Component(...)
export class MyComponent {}
@NgModule({
imports: [BrowserModule],
declarations: [MyComponent],
entryComponents: [MyComponent]
})
export class MainModule {
constructor(appRef: ApplicationRef) {
appRef.bootstrap(MyComponent);
}
}
bootstrap.ts
-------------
import {MainModuleNgFactory} from './main.module.ngfactory';
import {platformBrowser} from '@angular/platform-browser';
platformBrowser().bootstrapModuleFactory(MainModuleNgFactory);
```
## Configuration
The `tsconfig.json` file may contain an additional configuration block:
```
"angularCompilerOptions": {
"genDir": ".",
"debug": true
}
```
### `genDir`
the `genDir` option controls the path (relative to `tsconfig.json`) where the generated file tree
will be written. If `genDir` is not set, then the code will be generated in the source tree, next
to your original sources. More options may be added as we implement more features.
We recommend you avoid checking generated files into version control. This permits a state where
the generated files in the repository were created from sources that were never checked in,
making it impossible to reproduce the current state. Also, your changes will effectively appear
twice in code reviews, with the generated version inscrutible by the reviewer.
In TypeScript 1.8, the generated sources will have to be written alongside your originals,
so set `genDir` to the same location as your files (typicially the same as `rootDir`).
Add `**/*.ngfactory.ts` and `**/*.ngsummary.json` to your `.gitignore` or other mechanism for your
version control system.
In TypeScript 1.9 and above, you can add a generated folder into your application,
such as `codegen`. Using the `rootDirs` option, you can allow relative imports like
`import {} from './foo.ngfactory'` even though the `src` and `codegen` trees are distinct.
Add `**/codegen` to your `.gitignore` or similar.
Note that in the second option, TypeScript will emit the code into two parallel directories
as well. This is by design, see https://github.com/Microsoft/TypeScript/issues/8245.
This makes the configuration of your runtime module loader more complex, so we don't recommend
this option yet.
### `debug`
Set the `debug` option to true to generate debug information in the generate files.
Default to `false`.
See the example in the `test/` directory for a working example.
## Compiler CLI
This program mimics the TypeScript tsc command line. It accepts a `-p` flag which points to a
`tsconfig.json` file, or a directory containing one.
This CLI is intended for demos, prototyping, or for users with simple build systems
that run bare `tsc`.
Users with a build system should expect an Angular template plugin. Such a plugin would be
based on the `public_api.ts` in this directory, but should share the TypeScript compiler instance
with the one already used in the plugin for TypeScript typechecking and emit.
## Design
At a high level, this program
- collects static metadata about the sources
- uses the `OfflineCompiler` from `@angular/compiler` to codegen additional `.ts` files
- these `.ts` files are written to the `genDir` path, then compiled together with the application.
## For developers
```
# Build Angular and the compiler
./build.sh
# Run the test once
# (First edit the LINKABLE_PKGS to use npm link instead of npm install)
$ ./scripts/ci/offline_compiler_test.sh
# Keep a package fresh in watch mode
./node_modules/.bin/tsc -p packages/compiler/tsconfig-build.json -w
# Recompile @angular/core module (needs to use tsc-ext to keep the metadata)
$ export NODE_PATH=${NODE_PATH}:$(pwd)/dist/all:$(pwd)/dist/tools
$ node dist/tools/@angular/compiler-cli/src/main -p packages/core/tsconfig-build.json
# Iterate on the test
$ cd /tmp/wherever/e2e_test.1464388257/
$ ./node_modules/.bin/ngc
$ ./node_modules/.bin/jasmine test/*_spec.js
```

View File

@ -20,6 +20,8 @@ if [[ ${CI_MODE:-} == "bazel" ]]; then
fi
travisFoldStart "tsc tools"
# TODO: I think these three can be deleted... but I'm not sure
# let's delete them one at a time and test on CI
$(npm bin)/tsc -p tools
$(npm bin)/tsc -p packages/compiler/tsconfig-tools.json
$(npm bin)/tsc -p packages/compiler-cli/tsconfig-tools.json

View File

@ -5,64 +5,11 @@ set -u -e -o pipefail
TRAVIS=${TRAVIS:-}
CI_MODE=${CI_MODE:-}
# Setup environment
readonly thisDir=$(cd $(dirname $0); pwd)
source ${thisDir}/_travis-fold.sh
# If the previous commands in the `script` section of .travis.yaml failed, then abort.
# The variable is not set in early stages of the build, so we default to 0 there.
# https://docs.travis-ci.com/user/environment-variables/
if [[ ${TRAVIS_TEST_RESULT=0} == 1 ]]; then
exit 1;
fi
mkdir -p ${LOGS_DIR}
# TODO: install nvm?? it's already on travis so we don't need it
#curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.0/install.sh | bash
# Install node
#nvm install ${NODE_VERSION}
# Install version of yarn that we are locked against
travisFoldStart "install-yarn"
curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version "${YARN_VERSION}"
travisFoldEnd "install-yarn"
# Install all npm dependencies according to yarn.lock
travisFoldStart "yarn-install"
(node tools/npm/check-node-modules --purge && yarn postinstall) || yarn install --frozen-lockfile --non-interactive
travisFoldEnd "yarn-install"
# Install Chromium
if [[ ${TRAVIS} &&
${CI_MODE} == "js" ||
${CI_MODE} == "e2e" ||
${CI_MODE} == "e2e_2"
]]; then
travisFoldStart "install-chromium"
(
${thisDir}/install-chromium.sh
# Start xvfb for local Chrome used for testing
if [[ ${TRAVIS} ]]; then
travisFoldStart "install-chromium.xvfb-start"
sh -e /etc/init.d/xvfb start
travisFoldEnd "install-chromium.xvfb-start"
fi
)
travisFoldEnd "install-chromium"
fi
# Install Sauce Connect
if [[ ${TRAVIS}] && (${CI_MODE} == "saucelabs_required" || ${CI_MODE} == "saucelabs_optional") ]]; then
travisFoldStart "install-sauceConnect"

View File

@ -1,11 +0,0 @@
#!/usr/bin/env bash
set -u -e -o pipefail
# Setup environment
readonly thisDir=$(cd $(dirname $0); pwd)
source ${thisDir}/_travis-fold.sh
travisFoldStart "test.unit.localChrome"
$(npm bin)/karma start ./karma-js.conf.js --single-run --browsers=${KARMA_JS_BROWSERS}
travisFoldEnd "test.unit.localChrome"

View File

@ -1,10 +0,0 @@
#!/bin/bash
# Wait for Connect to be ready before exiting
printf "Connecting to Sauce."
while [ ! -f $BROWSER_PROVIDER_READY_FILE ]; do
printf "."
#dart2js takes longer than the travis 10 min timeout to complete
sleep .5
done
echo "Connected"

View File

@ -1,57 +0,0 @@
#!/bin/bash
set +x -u -e -o pipefail
# Setup environment
readonly thisDir=$(cd $(dirname $0); pwd)
source ${thisDir}/../ci/_travis-fold.sh
# Setup and start Sauce Connect for your TravisCI build
# This script requires your .travis.yml to include the following two private env variables:
# SAUCE_USERNAME
# SAUCE_ACCESS_KEY
# Follow the steps at https://saucelabs.com/opensource/travis to set that up.
#
# Curl and run this script as part of your .travis.yml before_script section:
# before_script:
# - curl https://gist.github.com/santiycr/5139565/raw/sauce_connect_setup.sh | bash
CONNECT_URL="https://saucelabs.com/downloads/sc-${SAUCE_CONNECT_VERSION}-linux.tar.gz"
CONNECT_DIR="/tmp/sauce-connect-$RANDOM"
CONNECT_DOWNLOAD="sc-latest-linux.tar.gz"
# We don't want to create a log file because sauceconnect always logs in verbose mode. This seems
# to be overwhelming Travis and causing flakes when we are cat-ing the log in "print-logs.sh"
CONNECT_LOG="/dev/null"
# Even though the stdout of sauceconnect is not very verbose, we don't want to log this to
# Travis because it will show up in between different travis log-output groups
CONNECT_STDOUT="/dev/null"
# Get Connect and start it
mkdir -p $CONNECT_DIR
cd $CONNECT_DIR
curl $CONNECT_URL -o $CONNECT_DOWNLOAD 2> /dev/null 1> /dev/null
mkdir sauce-connect
tar --extract --file=$CONNECT_DOWNLOAD --strip-components=1 --directory=sauce-connect > /dev/null
rm $CONNECT_DOWNLOAD
SAUCE_ACCESS_KEY=`echo $SAUCE_ACCESS_KEY | rev`
ARGS=""
# Set tunnel-id only on Travis, to make local testing easier.
if [ ! -z "$TRAVIS_JOB_NUMBER" ]; then
ARGS="$ARGS --tunnel-identifier $TRAVIS_JOB_NUMBER"
fi
if [ ! -z "$BROWSER_PROVIDER_READY_FILE" ]; then
ARGS="$ARGS --readyfile $BROWSER_PROVIDER_READY_FILE"
fi
set -v
echo "Starting Sauce Connect in the background."
sauce-connect/bin/sc -u $SAUCE_USERNAME -k $SAUCE_ACCESS_KEY $ARGS --logfile $CONNECT_LOG \
> $CONNECT_STDOUT &
set +v

View File

@ -1,16 +0,0 @@
#!/bin/bash
set -e -o pipefail
echo "Shutting down Sauce Connect tunnel"
killall sc
while [[ -n `ps -ef | grep "sauce-connect-" | grep -v "grep"` ]]; do
printf "."
sleep .5
done
echo ""
echo "Sauce Connect tunnel has been shut down"

View File

@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -x -u -e -o pipefail
readonly currentDir=$(cd $(dirname $0); pwd)
# Command arguments that will be passed to sauce-connect.
sauceArgs=""
if [[ ! -z "${SAUCE_READY_FILE}" ]]; then
sauceArgs="${sauceArgs} --readyfile ${SAUCE_READY_FILE}"
fi
if [[ ! -z "${SAUCE_PID_FILE}" ]]; then
mkdir -p $(dirname ${SAUCE_PID_FILE})
sauceArgs="${sauceArgs} --pidfile ${SAUCE_PID_FILE}"
fi
if [[ ! -z "${SAUCE_TUNNEL_IDENTIFIER}" ]]; then
sauceArgs="${sauceArgs} --tunnel-identifier ${SAUCE_TUNNEL_IDENTIFIER}"
fi
echo "Starting Sauce Connect. Passed arguments: ${sauceArgs}"
${currentDir}/../../node_modules/sauce-connect/bin/sc -u ${SAUCE_USERNAME} -k ${SAUCE_ACCESS_KEY} ${sauceArgs}

View File

@ -0,0 +1,27 @@
#!/usr/bin/env bash
# Disable printing of any executed command because this would cause a lot
# of spam due to the loop.
set +x -u -e -o pipefail
if [[ ! -f ${SAUCE_PID_FILE} ]]; then
echo "Could not find Saucelabs tunnel PID file. Cannot stop tunnel.."
exit 1
fi
echo "Shutting down Sauce Connect tunnel"
# The process id for the sauce-connect instance is stored inside of the pidfile.
tunnelProcessId=$(cat ${SAUCE_PID_FILE})
# Kill the process by using the PID that has been read from the pidfile. Note that
# we cannot use killall because CircleCI base container images don't have it installed.
kill ${tunnelProcessId}
while (ps -p ${tunnelProcessId} &> /dev/null); do
printf "."
sleep .5
done
echo ""
echo "Sauce Connect tunnel has been shut down"

View File

@ -0,0 +1,26 @@
#!/usr/bin/env bash
# Disable printing of any executed command because this would cause a lot
# of spam due to the loop.
set +x -u -e -o pipefail
# Waits for Saucelabs Connect to be ready before executing any tests.
counter=0
while [[ ! -f ${SAUCE_READY_FILE} ]]; do
counter=$((counter + 1))
# Counter needs to be multiplied by two because the while loop only sleeps a half second.
# This has been made in favor of better progress logging (printing dots every half second)
if [ $counter -gt $[${SAUCE_READY_FILE_TIMEOUT} * 2] ]; then
echo ""
echo "Timed out after ${SAUCE_READY_FILE_TIMEOUT} seconds waiting for tunnel ready file"
exit 5
fi
printf "."
sleep 0.5
done
echo ""
echo "Connected to Saucelabs"

View File

@ -7222,6 +7222,10 @@ sauce-connect-launcher@^1.2.2, sauce-connect-launcher@^1.2.4:
lodash "^4.16.6"
rimraf "^2.5.4"
"sauce-connect@https://saucelabs.com/downloads/sc-4.5.2-linux.tar.gz":
version "0.0.0"
resolved "https://saucelabs.com/downloads/sc-4.5.2-linux.tar.gz#2a923ca09bab5d8096844ace36f4a89994364482"
saucelabs@^1.4.0, saucelabs@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/saucelabs/-/saucelabs-1.5.0.tgz#9405a73c360d449b232839919a86c396d379fd9d"