mirror of
https://github.com/ascribe/onion.git
synced 2025-01-03 10:25:08 +01:00
Refactor, add setup.py
This commit is contained in:
parent
e631f3374f
commit
e8bdeffad8
@ -1,2 +1,2 @@
|
|||||||
ONION_SAUCELABS_USER=ascribe
|
SAUCE_USERNAME=ascribe
|
||||||
ONION_SAUCELABS_APIKEY=
|
SAUCE_ACCESS_KEY=
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
},
|
},
|
||||||
"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"
|
||||||
@ -40,6 +41,7 @@
|
|||||||
"dotenv": "^1.2.0",
|
"dotenv": "^1.2.0",
|
||||||
"jest-cli": "^0.4.0",
|
"jest-cli": "^0.4.0",
|
||||||
"mocha": "^2.3.4",
|
"mocha": "^2.3.4",
|
||||||
|
"sauce-connect-launcher": "^0.13.0",
|
||||||
"wd": "^0.4.0"
|
"wd": "^0.4.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -34,7 +34,11 @@ The components involved are:
|
|||||||
- **[Selenium WebDriver](https://www.npmjs.com/package/wd)**: it's a library
|
- **[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,
|
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
|
click around, fill out forms, submit forms etc. It's basically a way to
|
||||||
control remotely a browser. There are other implementations in Python, PHP,
|
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
|
Java, etc. Also, a **WebDriver** can be initialized with a list of [desired
|
||||||
capabilities](https://code.google.com/p/selenium/wiki/DesiredCapabilities)
|
capabilities](https://code.google.com/p/selenium/wiki/DesiredCapabilities)
|
||||||
describing which features (like the platform, browser name and version) you
|
describing which features (like the platform, browser name and version) you
|
||||||
@ -53,9 +57,12 @@ The components involved are:
|
|||||||
systems. (They do other things, check out their websites).
|
systems. (They do other things, check out their websites).
|
||||||
|
|
||||||
- **[SauceConnect](https://wiki.saucelabs.com/display/DOCS/Setting+Up+Sauce+Connect)**:
|
- **[SauceConnect](https://wiki.saucelabs.com/display/DOCS/Setting+Up+Sauce+Connect)**:
|
||||||
it allows Saucelabs to connect to your `localhost` to test the app. (There
|
is a Java software by Saucelabs to connect to your `localhost` to test the
|
||||||
is also a [Node.js wrapper](https://www.npmjs.com/package/sauce-connect), so
|
application. There is also a Node.js wrapper
|
||||||
you can use it programmatically within your code for tests).
|
[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:
|
On the JavaScript side, we use:
|
||||||
@ -74,8 +81,49 @@ On the JavaScript side, we use:
|
|||||||
environment variables from `.env` into `process.env`.
|
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
|
## 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
|
```javascript
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
@ -84,33 +132,61 @@ require('dotenv').load();
|
|||||||
const wd = require('wd');
|
const wd = require('wd');
|
||||||
const chai = require('chai');
|
const chai = require('chai');
|
||||||
const chaiAsPromised = require('chai-as-promised');
|
const chaiAsPromised = require('chai-as-promised');
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Set up `chai` to use `chaiAsPromised`.
|
||||||
|
|
||||||
|
```javascript
|
||||||
chai.use(chaiAsPromised);
|
chai.use(chaiAsPromised);
|
||||||
chai.should();
|
chai.should();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`browser` is the main object to interact with Saucelab "real" browsers. We will
|
||||||
|
use this object a lot. It allow us to load pages, click around, check if a
|
||||||
|
specific text is present etc.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
describe('Login logs users in', function() {
|
describe('Login logs users in', function() {
|
||||||
let browser;
|
let browser;
|
||||||
|
```
|
||||||
|
|
||||||
|
Create the driver to control the browser.
|
||||||
|
```javascript
|
||||||
before(function() {
|
before(function() {
|
||||||
browser = wd.promiseChainRemote('ondemand.saucelabs.com', 80,
|
browser = wd.promiseChainRemote('ondemand.saucelabs.com', 80);
|
||||||
process.env.ONION_SAUCELABS_USER,
|
|
||||||
process.env.ONION_SAUCELABS_APIKEY,
|
|
||||||
return browser.init({ browserName: 'chrome' });
|
return browser.init({ browserName: 'chrome' });
|
||||||
});
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
This function will be executed before each `it` function. Here we point the browser to a specific URL.
|
||||||
|
|
||||||
|
```javascript
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
return browser.get('http://www.ascribe.ninja/app/login');
|
return browser.get('http://www.ascribe.ninja/app/login');
|
||||||
});
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
While this function will be executed after each `it` function. `quit` will destroy the browser session.
|
||||||
|
|
||||||
|
```javascript
|
||||||
after(function() {
|
after(function() {
|
||||||
return browser.quit();
|
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() {
|
it('should contain "Log in" in the title', function() {
|
||||||
return browser.title().should.become('Log in');
|
return browser.title().should.become('Log in');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## How to run the test suite
|
||||||
|
|
33
test/setup.js
Normal file
33
test/setup.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
require('dotenv').load();
|
||||||
|
|
||||||
|
const sauceConnectLauncher = require('sauce-connect-launcher');
|
||||||
|
let globalSauceProcess;
|
||||||
|
|
||||||
|
|
||||||
|
if (process.env.SAUCE_AUTO_CONNECT) {
|
||||||
|
before(function(done) {
|
||||||
|
// Creating the tunnel takes a bit of time. For this case we can safely disable it.
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
@ -1,7 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
require('dotenv').load();
|
|
||||||
|
|
||||||
const wd = require('wd');
|
const wd = require('wd');
|
||||||
const chai = require('chai');
|
const chai = require('chai');
|
||||||
const chaiAsPromised = require('chai-as-promised');
|
const chaiAsPromised = require('chai-as-promised');
|
||||||
@ -10,13 +8,11 @@ chai.should();
|
|||||||
|
|
||||||
|
|
||||||
describe('Login logs users in', function() {
|
describe('Login logs users in', function() {
|
||||||
|
this.timeout(0);
|
||||||
let browser;
|
let browser;
|
||||||
|
|
||||||
before(function() {
|
before(function() {
|
||||||
browser = wd.promiseChainRemote('ondemand.saucelabs.com', 80,
|
browser = wd.promiseChainRemote('ondemand.saucelabs.com', 80);
|
||||||
process.env.ONION_SAUCELABS_USER,
|
|
||||||
process.env.ONION_SAUCELABS_APIKEY);
|
|
||||||
|
|
||||||
return browser.init({ browserName: 'chrome' });
|
return browser.init({ browserName: 'chrome' });
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user