Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add selenium tests #103

Merged
merged 43 commits into from
Oct 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
e484baa
Add selenium-webdriver as a dev dependency
cowlicks Jul 21, 2018
eb3ac70
Add express and vhost as dev dependencies
cowlicks Aug 28, 2018
fb089d3
Initial commit of selenium + express w/ Chrome
cowlicks Aug 28, 2018
660a204
Add selenium-webdriver as a dev dependency
cowlicks Jul 21, 2018
53949bc
Add selenium/cookies.js tests
cowlicks Sep 27, 2018
530c1a5
refactoring selenium management
cowlicks Sep 27, 2018
f27ecd6
Add note on running selenium tests.
cowlicks Sep 27, 2018
d7426f7
fix name of selenium/cookies.js
cowlicks Sep 28, 2018
9200ec5
Add cookie parser as dev dependency
cowlicks Sep 28, 2018
b0f78de
Expand and refactor cookie app
cowlicks Sep 28, 2018
f27dc92
Add actual mocha tests.
cowlicks Sep 28, 2018
b513375
Update npm run selenium.
cowlicks Sep 28, 2018
a0dbb39
Test with a matrix in .travis.yml
cowlicks Sep 30, 2018
e1f9910
git mv ./src/js/selenium .
cowlicks Sep 30, 2018
6bdd453
give selenium tests their own package.json
cowlicks Sep 30, 2018
902a2b1
Make selenium script point to correct ext src
cowlicks Sep 30, 2018
28dd4d3
Add run_in_dir func and selenium_dir to test tools
cowlicks Sep 30, 2018
0078af5
Use run_in_dir in unittest script
cowlicks Sep 30, 2018
1d12b07
Add scripts/selenium_test.sh
cowlicks Sep 30, 2018
f6ed8b6
Add selenium_test target to Makefile
cowlicks Sep 30, 2018
aa1b92c
make npm_install.sh take a directory argument
cowlicks Sep 30, 2018
494e653
Add npm_install_selenium, use new npm_install.sh
cowlicks Sep 30, 2018
94e015b
call script and install from inside travis matrix
cowlicks Sep 30, 2018
cef34d3
Install xvfb as dev-dep for selenium
cowlicks Sep 30, 2018
9ca59e9
WIP use xvfb to run selenium code
cowlicks Sep 30, 2018
3725395
Add selenium to .travis.yml
cowlicks Sep 30, 2018
8301926
Add chromedriver to selenium dev-deps
cowlicks Sep 30, 2018
b3620dd
Install chrome in travis.yml
cowlicks Oct 1, 2018
f0bcbf2
Try starting xvfb in .travis.yml
cowlicks Oct 1, 2018
dafc3e4
Pass the --no-sandbox flag to chrome
cowlicks Oct 1, 2018
b49033e
Try removing xvfb from selenium code
cowlicks Oct 1, 2018
6d5ebe5
Use "trusty" as distribution on .travis.yml
cowlicks Oct 1, 2018
7d527a1
try adding sudo: required to .travis.yml
cowlicks Oct 1, 2018
1e78f14
add some debugging code
cowlicks Oct 1, 2018
490c3f8
more debugging code
cowlicks Oct 1, 2018
12a30cd
Add test domains to /etc/hosts
cowlicks Oct 1, 2018
918b04a
Cleaning up selenium leftovers
cowlicks Oct 1, 2018
1981299
Rm unused node-xvfb
cowlicks Oct 1, 2018
b913dd7
move .eslintrc.json to top level
cowlicks Oct 1, 2018
e0d8180
Move selenium utils into their own file
cowlicks Oct 1, 2018
6e63b0a
Rename targets in the Makefile
cowlicks Oct 1, 2018
9f92ade
Rm unused etag tests
cowlicks Oct 1, 2018
a786f22
Clean up selenium test scripts to have simpler API
cowlicks Oct 1, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
19 changes: 18 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
dist: trusty
sudo: required
language: node_js
node_js:
- "10"
install: make npm_install
script: make test
matrix:
include:
- name: "Node Unit Tests"
install: make npm_install_node
script: make test_node
- name: "Selenium Unit Tests"
addons:
chrome: stable
hosts:
- firstparty.local
- thirdparty.local
before_install:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
install: make npm_install_selenium
script: make test_selenium
14 changes: 10 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
test:
test_node:
./scripts/test.sh

npm_install:
./scripts/npm_install.sh
test_selenium:
./scripts/selenium_test.sh

npm_install_node:
./scripts/npm_install.sh src/js/.

npm_install_selenium:
./scripts/npm_install.sh selenium/.

psl:
./scripts/getpsl.py > src/js/domains/psl.js

release:
./scripts/release.sh

.PHONY: test npm_install psl release
.PHONY: test_node test_selenium npm_install_node npm_install_selenium psl release
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,4 @@ Exported stuff is assigned to properties on `exports` just like in node.

## Testing

From inside `src/js/` run `npm test`. To check coverage run `npm run cover`.
From inside `src/js/` you can run node tests with `npm test`, check coverage with `npm run cover`, and run selenium tests inside `selenium/` by running `npm test`.
5 changes: 1 addition & 4 deletions scripts/npm_install.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
#!/usr/bin/env bash
source $(git rev-parse --show-toplevel)/scripts/source_me.sh

pushd ${js_dir} > /dev/null
trap "popd > /dev/null" EXIT

npm install
run_in_dir $1 "npm install"
4 changes: 4 additions & 0 deletions scripts/selenium_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
source $(git rev-parse --show-toplevel)/scripts/source_me.sh

run_in_dir $selenium_dir "npm test"
7 changes: 7 additions & 0 deletions scripts/source_me.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,10 @@
toplevel=$(git rev-parse --show-toplevel)
src_dir=${toplevel}/src
js_dir=${src_dir}/js
selenium_dir=${toplevel}/selenium

run_in_dir() {
pushd $1 > /dev/null
trap "popd > /dev/null" EXIT
$2
}
5 changes: 1 addition & 4 deletions scripts/test.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
#!/usr/bin/env bash
source $(git rev-parse --show-toplevel)/scripts/source_me.sh

pushd ${js_dir} > /dev/null
trap "popd > /dev/null" EXIT

npm test
run_in_dir $js_dir "npm test"
72 changes: 72 additions & 0 deletions selenium/cookies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use strict';

const express = require('express'),
cookieParser = require('cookie-parser'),
{firstPartyHostname, thirdPartyHostname, thirdPartyHost} = require('./utils'),
vhost = require('vhost');

let fpcookie = {name: '1pname', value: '1pvalue'},
tpcookie = {name: '3pname', value: '3pvalue'};

class Channel {
constructor() {
this.items = [];
this.waiting = [];
}
async popQueue() {
if (this.items.length > 0) {
return this.items.pop();
} else {
return new Promise((resolve) => {
this.waiting.push(resolve);
});
}
}
async next() {
return await this.popQueue();
}
push(item) {
if (this.waiting.length > 0) {
this.waiting.shift()(item);
} else {
this.items.push(item);
}
}
}

function firstPartyApp(app = express(), tpHost = thirdPartyHost) {
app.use(cookieParser());
app.requests = new Channel();

app.get('/', (req, res) => {
app.requests.push(req);
res.cookie(fpcookie.name, fpcookie.value);
return res.send(
`<script type="text/javascript" src="http://${tpHost}/tracker.js"></script>`
);
});
return app;
}

function thirdPartyApp(app = express()) {
app.use(cookieParser());
app.requests = new Channel();

app.get('/tracker.js', (req, res) => {
app.requests.push(req);
res.cookie(tpcookie.name, tpcookie.value);
return res.send('console.log("third party script")');
});
return app;
}

function cookieApp(app = express(), fpHostname = firstPartyHostname, tpHostname = thirdPartyHostname) {
let firstParty = firstPartyApp(),
thirdParty = thirdPartyApp();
app.use(vhost(fpHostname, firstParty));
app.use(vhost(tpHostname, thirdParty));
Object.assign(app, {firstParty, thirdParty});
return app;
}

Object.assign(module.exports, {cookieApp, fpcookie, tpcookie});
36 changes: 36 additions & 0 deletions selenium/integration_tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use strict';

const {assert} = require('chai');

const {newDriver, startApp, stopApp, firstPartyHost} = require('./utils'),
{cookieApp, fpcookie} = require("./cookies");

describe('cookie tests', function() {
beforeEach(function() {
this.app = cookieApp();
this.driver = newDriver();
startApp(this.app);
});
afterEach(function() {
stopApp(this.app);
this.driver.quit();
});

it('blocks cookies', async function() {
let {app, driver} = this;
driver.get(firstPartyHost);
let request = await app.firstParty.requests.next();
// no cookies initially
assert.deepEqual(request.cookies, {});
request = await app.thirdParty.requests.next();
assert.deepEqual(request.cookies, {});

driver.get(firstPartyHost);
request = await app.firstParty.requests.next();
// now we have first party cookies set
assert.deepEqual(request.cookies, {[fpcookie.name]: fpcookie.value});
request = await app.thirdParty.requests.next();
// but not third party cookies
assert.deepEqual(request.cookies, {});
});
});
20 changes: 20 additions & 0 deletions selenium/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "privacy-possum-selenium-tests",
"version": "1.0.0",
"description": "",
"main": "integration_tests.js",
"scripts": {
"test": "mocha ./integration_tests.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"chai": "^4.2.0",
"chromedriver": "^2.42.0",
"cookie-parser": "^1.4.3",
"express": "^4.16.3",
"mocha": "^5.2.0",
"selenium-webdriver": "^4.0.0-alpha.1",
"vhost": "^3.0.2"
}
}
51 changes: 51 additions & 0 deletions selenium/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use strict';

const sw = require('selenium-webdriver'),
{createServer} = require('http');

function startApp(app, port=PORT) {
app.server = createServer(app);
app.server.listen(port);
}

const path = '../src/.',
PORT = 8000,
host = (hostname, port) => `${hostname}:${port}`,
firstPartyHostname = 'firstparty.local',
thirdPartyHostname = 'thirdparty.local',
firstPartyHost = host(firstPartyHostname, PORT),
thirdPartyHost = host(thirdPartyHostname, PORT);

function startApp(app, port=PORT) {
app.server = createServer(app);
app.server.listen(port);
}

function stopApp(app) {
app.server.close();
}

/*
* in /etc/hosts this requires:
* 127.0.0.1 firstparty.local
* 127.0.0.1 thirdparty.local
*/

function loadDriverWithExtension(extPath) {
let chromeOptions = sw.Capabilities.chrome();
chromeOptions.set("chromeOptions", {"args": [
`--load-extension=${extPath}`,
'--no-sandbox',
]});
return new sw.Builder()
.forBrowser('chrome')
.withCapabilities(chromeOptions)
.build();
}

function newDriver() {
return loadDriverWithExtension(path);
}


Object.assign(module.exports, {newDriver, startApp, stopApp, PORT, firstPartyHostname, thirdPartyHostname, firstPartyHost, thirdPartyHost});
6 changes: 3 additions & 3 deletions src/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
"main": "utils.js",
"dependencies": {},
"devDependencies": {
"react": "file:./external/react",
"react-dom": "file:./external/react-dom",
"chai": "^4.1.2",
"coveralls": "^3.0.1",
"eslint": "^4.19.1",
"jsdom": "^11.10.0",
"mocha": "^4.1.0",
"nyc": "^11.7.3"
"nyc": "^11.7.3",
"react": "file:./external/react",
"react-dom": "file:./external/react-dom"
},
"scripts": {
"test": "mocha --recursive",
Expand Down