mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 09:23:13 +01:00
Merge pull request #136 from ascribe/AD-1528-set-up-integration-testing-on-onion
Set up integration testing on onion
This commit is contained in:
commit
533a9efa8f
3
.env-template
Normal file
3
.env-template
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
SAUCE_USERNAME=ascribe
|
||||||
|
SAUCE_ACCESS_KEY=
|
||||||
|
SAUCE_DEFAULT_URL=
|
@ -2,7 +2,7 @@
|
|||||||
"parser": "babel-eslint",
|
"parser": "babel-eslint",
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"es6": true
|
"es6": true,
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"new-cap": [2, {newIsCap: true, capIsNew: false}],
|
"new-cap": [2, {newIsCap: true, capIsNew: false}],
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -22,3 +22,4 @@ node_modules/*
|
|||||||
build
|
build
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.env
|
||||||
|
17
package.json
17
package.json
@ -8,9 +8,12 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "eslint ./js",
|
"lint": "eslint ./js",
|
||||||
|
"preinstall": "export SAUCE_CONNECT_DOWNLOAD_ON_INSTALL=true",
|
||||||
"postinstall": "npm run build",
|
"postinstall": "npm run build",
|
||||||
"build": "gulp build --production",
|
"build": "gulp build --production",
|
||||||
"start": "node server.js"
|
"start": "node server.js",
|
||||||
|
"test": "mocha",
|
||||||
|
"tunnel": "node test/tunnel.js"
|
||||||
},
|
},
|
||||||
"browser": {
|
"browser": {
|
||||||
"fineUploader": "./js/components/ascribe_uploader/vendor/s3.fine-uploader.js"
|
"fineUploader": "./js/components/ascribe_uploader/vendor/s3.fine-uploader.js"
|
||||||
@ -35,8 +38,14 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-eslint": "^3.1.11",
|
"babel-eslint": "^3.1.11",
|
||||||
"babel-jest": "^5.2.0",
|
"babel-jest": "^5.2.0",
|
||||||
"gulp-sass": "^2.1.1",
|
"chai": "^3.4.1",
|
||||||
"jest-cli": "^0.4.0"
|
"chai-as-promised": "^5.1.0",
|
||||||
|
"colors": "^1.1.2",
|
||||||
|
"dotenv": "^1.2.0",
|
||||||
|
"jest-cli": "^0.4.0",
|
||||||
|
"mocha": "^2.3.4",
|
||||||
|
"sauce-connect-launcher": "^0.13.0",
|
||||||
|
"wd": "^0.4.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"alt": "^0.16.5",
|
"alt": "^0.16.5",
|
||||||
@ -62,7 +71,7 @@
|
|||||||
"gulp-if": "^1.2.5",
|
"gulp-if": "^1.2.5",
|
||||||
"gulp-minify-css": "^1.1.6",
|
"gulp-minify-css": "^1.1.6",
|
||||||
"gulp-notify": "^2.2.0",
|
"gulp-notify": "^2.2.0",
|
||||||
"gulp-sass": "^2.0.1",
|
"gulp-sass": "^2.1.1",
|
||||||
"gulp-sourcemaps": "^1.5.2",
|
"gulp-sourcemaps": "^1.5.2",
|
||||||
"gulp-template": "~3.0.0",
|
"gulp-template": "~3.0.0",
|
||||||
"gulp-uglify": "^1.2.0",
|
"gulp-uglify": "^1.2.0",
|
||||||
|
36
test/.eslintrc
Normal file
36
test/.eslintrc
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"parser": "babel-eslint",
|
||||||
|
"env": {
|
||||||
|
"mocha": true,
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"new-cap": [2, {newIsCap: true, capIsNew: false}],
|
||||||
|
"quotes": [2, "single"],
|
||||||
|
"eol-last": [0],
|
||||||
|
"no-mixed-requires": [0],
|
||||||
|
"no-underscore-dangle": [0],
|
||||||
|
"global-strict": [2, "always"],
|
||||||
|
"no-trailing-spaces": [2, { skipBlankLines: true }],
|
||||||
|
"no-console": 0,
|
||||||
|
"camelcase": [2, {"properties": "never"}],
|
||||||
|
},
|
||||||
|
"globals": {},
|
||||||
|
"plugins": [],
|
||||||
|
"ecmaFeatures": {
|
||||||
|
"modules": 1,
|
||||||
|
"arrowFunctions",
|
||||||
|
"classes": 1,
|
||||||
|
"blockBindings": 1,
|
||||||
|
"defaultParams": 1,
|
||||||
|
"destructuring": 1,
|
||||||
|
"objectLiteralComputedProperties": 1,
|
||||||
|
"objectLiteralDuplicateProperties": 0,
|
||||||
|
"objectLiteralShorthandMethods": 1,
|
||||||
|
"objectLiteralShorthandProperties": 1,
|
||||||
|
"restParams": 1,
|
||||||
|
"spread": 1,
|
||||||
|
"superInFunctions": 1,
|
||||||
|
"templateStrings": 1
|
||||||
|
}
|
||||||
|
}
|
256
test/README.md
Normal file
256
test/README.md
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
# TL;DR
|
||||||
|
Copy the contents of `.env-template` to `.env` and [fill up the missing keys with
|
||||||
|
information from your SauceLabs account](#how-to-set-up-your-env-config-file).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ npm install
|
||||||
|
$ npm run tunnel
|
||||||
|
$ npm test && git commit
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
* Use gulp to parallelize mocha invocations with different browsers
|
||||||
|
* Figure out good system for changing subdomain through test scripts
|
||||||
|
|
||||||
|
|
||||||
|
# Welcome to our test suite, let me be your guide
|
||||||
|
|
||||||
|
Dear reader, first of all thanks for taking your time reading this document.
|
||||||
|
The purpose of this document is to give you an overview on what we want to test
|
||||||
|
and how we are doing it.
|
||||||
|
|
||||||
|
|
||||||
|
# How it works (bird's-eye view)
|
||||||
|
|
||||||
|
You will notice that the setup is a bit convoluted. This section will explain
|
||||||
|
you why. Testing single functions in JavaScript is not that hard (if you don't
|
||||||
|
need to interact with the DOM), and can be easily achieved using frameworks
|
||||||
|
like [Mocha](https://mochajs.org/). Integration and cross browser testing is,
|
||||||
|
on the other side, a huge PITA. Moreover, "browser testing" includes also
|
||||||
|
"mobile browser testing". On the top of that the same browser (type and
|
||||||
|
version) can behave in a different way on different operating systems.
|
||||||
|
|
||||||
|
To achieve that you can have your own cluster of machines with different
|
||||||
|
operating systems and browsers or, if you don't want to spend the rest of your
|
||||||
|
life configuring an average of 100 browsers for each different operating
|
||||||
|
system, you can pay someone else to do that. Check out [this
|
||||||
|
article](https://saucelabs.com/selenium/selenium-grid) if you want to know why
|
||||||
|
using Selenium Grid is better than a DIY approach.
|
||||||
|
|
||||||
|
We decided to use [saucelabs](https://saucelabs.com/) cloud (they support [over
|
||||||
|
700 combinations](https://saucelabs.com/platforms/) of operating systems and
|
||||||
|
browsers) to run our tests.
|
||||||
|
|
||||||
|
|
||||||
|
## Components and tools
|
||||||
|
|
||||||
|
Right now we are just running the test locally, so no Continuous Integration™.
|
||||||
|
|
||||||
|
The components involved are:
|
||||||
|
- **[Selenium WebDriver](https://www.npmjs.com/package/wd)**: it's a library
|
||||||
|
that can control a browser. You can use the **WebDriver** to load new URLs,
|
||||||
|
click around, fill out forms, submit forms etc. It's basically a way to
|
||||||
|
control remotely a browser. The protocol (language agnostic) is called
|
||||||
|
[JsonWire](https://code.google.com/p/selenium/wiki/JsonWireProtocol), `wd`
|
||||||
|
wraps it and gives you a nice
|
||||||
|
[API](https://github.com/admc/wd/blob/master/doc/jsonwire-full-mapping.md)
|
||||||
|
you can use in JavaScript. There are other implementations in Python, PHP,
|
||||||
|
Java, etc. Also, a **WebDriver** can be initialized with a list of [desired
|
||||||
|
capabilities](https://code.google.com/p/selenium/wiki/DesiredCapabilities)
|
||||||
|
describing which features (like the platform, browser name and version) you
|
||||||
|
want to use to run your tests.
|
||||||
|
|
||||||
|
- **[Selenium Grid](https://github.com/SeleniumHQ/selenium/wiki/Grid2)**: it's
|
||||||
|
the controller for the cluster of machines/devices that can run browsers.
|
||||||
|
Selenium Grid is able to scale by distributing tests on several machines,
|
||||||
|
manage multiple environments from a central point, making it easy to run the
|
||||||
|
tests against a vast combination of browsers / OS, minimize the maintenance
|
||||||
|
time for the grid by allowing you to implement custom hooks to leverage
|
||||||
|
virtual infrastructure for instance.
|
||||||
|
|
||||||
|
- **[Saucelabs](https://saucelabs.com/)**: a private company providing a
|
||||||
|
cluster to run your tests on over 700 combinations of browsers/operating
|
||||||
|
systems. (They do other things, check out their websites).
|
||||||
|
|
||||||
|
- **[SauceConnect](https://wiki.saucelabs.com/display/DOCS/Setting+Up+Sauce+Connect)**:
|
||||||
|
is a Java software by Saucelabs to connect to your `localhost` to test the
|
||||||
|
application. There is also a Node.js wrapper
|
||||||
|
[sauce-connect-launcher](https://www.npmjs.com/package/sauce-connect-launcher),
|
||||||
|
so you can use it programmatically within your code for tests. Please note
|
||||||
|
that this module is just a wrapper around the actual software. Running `npm
|
||||||
|
install` should install the additional Java software as well.
|
||||||
|
|
||||||
|
|
||||||
|
On the JavaScript side, we use:
|
||||||
|
- [Mocha](https://mochajs.org/): a test framework running on Node.js.
|
||||||
|
|
||||||
|
- [chai](http://chaijs.com/): a BDD/TDD assertion library for node that can be
|
||||||
|
paired with any javascript testing framework.
|
||||||
|
|
||||||
|
- [chaiAsPromised](https://github.com/domenic/chai-as-promised/): an extension
|
||||||
|
for Chai with a fluent language for asserting facts about promises. The
|
||||||
|
extension is actually quite cool, we can do assertions on promises without
|
||||||
|
writing callbacks but just chaining operators. Check out their `README` on
|
||||||
|
GitHub to see an example.
|
||||||
|
|
||||||
|
- [dotenv](https://github.com/motdotla/dotenv): a super nice package to load
|
||||||
|
environment variables from `.env` into `process.env`.
|
||||||
|
|
||||||
|
|
||||||
|
## How to set up your `.env` config file
|
||||||
|
In the root of this repository there is a file called `.env-template`. Create a
|
||||||
|
copy and call it `.env`. This file will store some values we need to connect to
|
||||||
|
Saucelabs.
|
||||||
|
|
||||||
|
There are two values to be set:
|
||||||
|
- `SAUCE_ACCESS_KEY`
|
||||||
|
- `SAUCE_USERNAME`
|
||||||
|
|
||||||
|
The two keys are the [default
|
||||||
|
ones](https://github.com/admc/wd#environment-variables-for-saucelabs) used by
|
||||||
|
many products related to Saucelabs. This allow us to keep the configuration
|
||||||
|
fairly straightforward and simple.
|
||||||
|
|
||||||
|
After logging in to https://saucelabs.com/, you can find your **api key** under
|
||||||
|
the **My Account**. Copy paste the value in your `.env` file.
|
||||||
|
|
||||||
|
|
||||||
|
## Anatomy of a test
|
||||||
|
|
||||||
|
First, you need to learn how [Mocha](https://mochajs.org/) works. Brew a coffee
|
||||||
|
(or tea, if coffee is not your cup of tea), sit down and read the docs.
|
||||||
|
|
||||||
|
Done? Great, let's move on and analyze how a test is written.
|
||||||
|
|
||||||
|
From a very high level, the flow of a test is the following:
|
||||||
|
1. load a page with a specific URL
|
||||||
|
2. do something on the page (click a button, submit a form, etc.)
|
||||||
|
3. maybe wait some seconds, or wait if something has changed
|
||||||
|
4. check if the new page contains some text you expect to be there
|
||||||
|
|
||||||
|
This is not set in stone, so go crazy if you want. But keep in mind that we
|
||||||
|
have a one page application, there might be some gotchas on how to wait for
|
||||||
|
stuff to happen. I suggest you to read the section [Wait for
|
||||||
|
something](https://github.com/admc/wd#waiting-for-something) to understand
|
||||||
|
better which tools you have to solve this problem.
|
||||||
|
Again, take a look to the [`wd` implementation of the JsonWire
|
||||||
|
protocol](https://github.com/admc/wd/blob/master/doc/jsonwire-full-mapping.md)
|
||||||
|
to know all the methods you can use to control the browser.
|
||||||
|
|
||||||
|
|
||||||
|
Import the libraries we need.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
require('dotenv').load();
|
||||||
|
|
||||||
|
const wd = require('wd');
|
||||||
|
const chai = require('chai');
|
||||||
|
const chaiAsPromised = require('chai-as-promised');
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Set up `chai` to use `chaiAsPromised`.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
chai.use(chaiAsPromised);
|
||||||
|
chai.should();
|
||||||
|
```
|
||||||
|
|
||||||
|
`browser` is the main object to interact with Saucelab "real" browsers. We will
|
||||||
|
use this object a lot. It allows us to load pages, click around, check if a
|
||||||
|
specific text is present, etc.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
describe('Login logs users in', function() {
|
||||||
|
let browser;
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the driver to control the browser. `before` will be executed once at the
|
||||||
|
start of the test before any `it` functions. Use `beforeEach` instead if you'd
|
||||||
|
like to run some code before each `it` function.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
before(function() {
|
||||||
|
browser = wd.promiseChainRemote('ondemand.saucelabs.com', 80);
|
||||||
|
|
||||||
|
// Start the browser, go to /login, and wait for the react app to render
|
||||||
|
return browser
|
||||||
|
.init({ browserName, version, platform })
|
||||||
|
.get(config.APP_URL + '/login')
|
||||||
|
.waitForElementByCss('.ascribe-default-app', asserters.isDisplayed, 10000);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Close the browser after finishing all tests. `after` will be executed at the end
|
||||||
|
of all `it` functions. Use `afterEach` instead if you'd like to run some code
|
||||||
|
after each `it` function.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
after(function() {
|
||||||
|
// Destroys the browser session
|
||||||
|
return browser.quit();
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
The actual test. We query the `browser` object to get the title of the page.
|
||||||
|
Note that `.title()` returns a `promise` **but**, since we are using
|
||||||
|
`chaiAsPromised`, we have some syntactic sugar to handle the promise in line,
|
||||||
|
without writing new functions.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
it('should contain "Log in" in the title', function() {
|
||||||
|
return browser.title().should.become('Log in');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
All together:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function testSuite(browserName, version, platform) {
|
||||||
|
describe(`[${browserName} ${version} ${platform}] Login logs users in`, function() {
|
||||||
|
// Set timeout to zero so Mocha won't time out.
|
||||||
|
this.timeout(0);
|
||||||
|
let browser;
|
||||||
|
|
||||||
|
before(function() {
|
||||||
|
// No need to inject `username` or `access_key`, by default the constructor
|
||||||
|
// looks up the values in `process.env.SAUCE_USERNAME` and `process.env.SAUCE_ACCESS_KEY`
|
||||||
|
browser = wd.promiseChainRemote('ondemand.saucelabs.com', 80);
|
||||||
|
|
||||||
|
// Start the browser, go to /login, and wait for the react app to render
|
||||||
|
return browser
|
||||||
|
.init({ browserName, version, platform })
|
||||||
|
.get(config.APP_URL + '/login')
|
||||||
|
.waitForElementByCss('.ascribe-default-app', asserters.isDisplayed, 10000);
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function() {
|
||||||
|
return browser.quit();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should contain "Log in" in the title', function() {
|
||||||
|
return browser.title().should.become('Log in');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## How to run the test suite
|
||||||
|
To run the tests, type:
|
||||||
|
```bash
|
||||||
|
$ mocha
|
||||||
|
```
|
||||||
|
|
||||||
|
By default the test suite runs on `http://www.localhost.com:3000/`, if you
|
||||||
|
want to change the URL, change the `APP_URL` env variable.
|
||||||
|
|
||||||
|
|
||||||
|
# How to have fun
|
||||||
|
Try this!
|
||||||
|
```bash
|
||||||
|
$ mocha -R nyan
|
||||||
|
```
|
18
test/config.js
Normal file
18
test/config.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
require('dotenv').load();
|
||||||
|
|
||||||
|
|
||||||
|
// https://code.google.com/p/selenium/wiki/DesiredCapabilities
|
||||||
|
const BROWSERS = [
|
||||||
|
'chrome,47,WINDOWS',
|
||||||
|
'chrome,46,WINDOWS',
|
||||||
|
'firefox,43,MAC',
|
||||||
|
'internet explorer,10,VISTA'
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
BROWSERS: BROWSERS.map(x => x.split(',')),
|
||||||
|
APP_URL: process.env.SAUCE_DEFAULT_URL || 'http://www.localhost.com:3000'
|
||||||
|
};
|
50
test/setup.js
Normal file
50
test/setup.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const config = require('./config');
|
||||||
|
const colors = require('colors');
|
||||||
|
const sauceConnectLauncher = require('sauce-connect-launcher');
|
||||||
|
|
||||||
|
|
||||||
|
let globalSauceProcess;
|
||||||
|
|
||||||
|
if (!process.env.SAUCE_USERNAME) {
|
||||||
|
console.log(colors.red('SAUCE_USERNAME is missing. Please check the README.md file.'));
|
||||||
|
process.exit(1); //eslint-disable-line no-process-exit
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!process.env.SAUCE_ACCESS_KEY) {
|
||||||
|
console.log(colors.red('SAUCE_ACCESS_KEY is missing. Please check the README.md file.'));
|
||||||
|
process.exit(1); //eslint-disable-line no-process-exit
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (process.env.SAUCE_AUTO_CONNECT) {
|
||||||
|
before(function(done) {
|
||||||
|
console.log(colors.yellow('Setting up tunnel from Saucelabs to your lovely computer, will take a while.'));
|
||||||
|
// Creating the tunnel takes a bit of time. For this case we can safely disable Mocha timeouts.
|
||||||
|
this.timeout(0);
|
||||||
|
|
||||||
|
sauceConnectLauncher(function (err, sauceConnectProcess) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
globalSauceProcess = sauceConnectProcess;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
after(function (done) {
|
||||||
|
// Creating the tunnel takes a bit of time. For this case we can safely disable it.
|
||||||
|
this.timeout(0);
|
||||||
|
|
||||||
|
if (globalSauceProcess) {
|
||||||
|
globalSauceProcess.close(done);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (config.APP_URL.match(/localhost/)) {
|
||||||
|
console.log(colors.yellow(`You are running tests on ${config.APP_URL}, make sure you already have a tunnel running.`));
|
||||||
|
console.log(colors.yellow('To create the tunnel, run:'));
|
||||||
|
console.log(colors.yellow(' $ node test/tunnel.js'));
|
||||||
|
}
|
50
test/test-login.js
Normal file
50
test/test-login.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Q = require('q');
|
||||||
|
const wd = require('wd');
|
||||||
|
const asserters = wd.asserters; // Commonly used asserters for async waits in the browser
|
||||||
|
const chai = require('chai');
|
||||||
|
const chaiAsPromised = require('chai-as-promised');
|
||||||
|
const config = require('./config.js');
|
||||||
|
|
||||||
|
chai.use(chaiAsPromised);
|
||||||
|
chai.should();
|
||||||
|
|
||||||
|
|
||||||
|
function testSuite(browserName, version, platform) {
|
||||||
|
describe(`[${browserName} ${version} ${platform}] Login logs users in`, function() {
|
||||||
|
// Set timeout to zero so Mocha won't time out.
|
||||||
|
this.timeout(0);
|
||||||
|
let browser;
|
||||||
|
|
||||||
|
before(function() {
|
||||||
|
// No need to inject `username` or `access_key`, by default the constructor
|
||||||
|
// looks up the values in `process.env.SAUCE_USERNAME` and `process.env.SAUCE_ACCESS_KEY`
|
||||||
|
browser = wd.promiseChainRemote('ondemand.saucelabs.com', 80);
|
||||||
|
|
||||||
|
// Start the browser, go to /login, and wait for the react app to render
|
||||||
|
return browser
|
||||||
|
.configureHttp({ baseUrl: config.APP_URL })
|
||||||
|
.init({ browserName, version, platform })
|
||||||
|
.get('/login')
|
||||||
|
.waitForElementByCss('.ascribe-default-app', asserters.isDisplayed, 10000)
|
||||||
|
.catch(function (err) {
|
||||||
|
console.log('Failure -- unable to load app.');
|
||||||
|
console.log('Skipping tests for this browser...');
|
||||||
|
return Q.reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
after(function() {
|
||||||
|
return browser.quit();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should contain "Log in" in the title', function() {
|
||||||
|
return browser.
|
||||||
|
waitForElementByCss('.ascribe-login-wrapper', asserters.isDisplayed, 2000)
|
||||||
|
title().should.become('Log in');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
config.BROWSERS.map(x => testSuite(...x));
|
23
test/tunnel.js
Normal file
23
test/tunnel.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const config = require('./config'); //eslint-disable-line no-unused-vars
|
||||||
|
const colors = require('colors');
|
||||||
|
const sauceConnectLauncher = require('sauce-connect-launcher');
|
||||||
|
|
||||||
|
|
||||||
|
function connect() {
|
||||||
|
console.log(colors.yellow('Setting up tunnel from Saucelabs to your lovely computer, will take a while.'));
|
||||||
|
// Creating the tunnel takes a bit of time. For this case we can safely disable Mocha timeouts.
|
||||||
|
|
||||||
|
sauceConnectLauncher(function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log(colors.green('Connected! Keep this process running and execute your tests.'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require.main === module) {
|
||||||
|
connect();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user