Compare commits

...

9 Commits

Author SHA1 Message Date
34be93b0f0 add missing chai dep 2018-07-01 15:02:42 +00:00
e95ea80c4f merge master 2018-07-01 15:00:53 +00:00
44412f6217 remove prettier 2018-07-01 14:57:52 +00:00
08362a4b2d Remove unused deps 2018-06-30 17:32:57 +00:00
10de559a0c Try karmatic! +test reorg 2018-06-29 20:12:40 +00:00
e9dad3d884 Use Puppeteer's chrome install 2018-06-29 01:43:13 +00:00
668acf2698 Add karma to run unit tests 2018-05-29 23:11:43 +01:00
7042491257 Add Dockerfile for Travis 2018-05-29 22:39:43 +01:00
307e1f9356 Implement e2e tests 2018-05-29 22:39:15 +01:00
8 changed files with 16595 additions and 1 deletions

20
Dockerfile Normal file
View File

@ -0,0 +1,20 @@
FROM selenium/node-chrome:latest
USER root
RUN apt-get update -qqy \
&& apt-get -qqy install python git build-essential \
&& rm -rf /var/lib/apt/lists/* /var/cache/apt/* \
&& rm /bin/sh && ln -s /bin/bash /bin/sh \
&& chown seluser /usr/local
ENV NVM_DIR /usr/local/nvm
RUN wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash \
&& source $NVM_DIR/nvm.sh \
&& nvm install v8
ENV CHROME_BIN /opt/google/chrome/chrome
ENV INSIDE_DOCKER=1
WORKDIR /usr/src
ENTRYPOINT source $NVM_DIR/nvm.sh && npm i && npm test

16392
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,10 @@
"start": "webpack serve --host 0.0.0.0 --hot",
"build": "webpack -p",
"lint": "tslint -c tslint.json -t verbose 'src/**/*.{ts,js}'",
"lintfix": "tslint -c tslint.json -t verbose --fix 'src/**/*.{ts,js}'"
"lintfix": "tslint -c tslint.json -t verbose --fix 'src/**/*.{ts,js}'",
"test": "npm run lint && npm run build && npm run test:e2e && npm run test:unit",
"test:e2e": "mocha -R spec test/e2e",
"test:unit": "karmatic"
},
"husky": {
"hooks": {
@ -17,6 +20,9 @@
}
},
"devDependencies": {
"@types/chai": "^4.1.3",
"@types/karma": "^1.7.3",
"@types/mocha": "^5.2.0",
"@types/node": "^9.4.7",
"@types/webassembly-js-api": "0.0.1",
"babel-loader": "^7.1.4",
@ -30,19 +36,24 @@
"babel-plugin-transform-react-remove-prop-types": "^0.4.13",
"babel-preset-env": "^1.6.1",
"babel-register": "^6.26.0",
"chai": "^4.1.2",
"clean-webpack-plugin": "^0.1.19",
"copy-webpack-plugin": "^4.5.1",
"css-loader": "^0.28.11",
"exports-loader": "^0.7.0",
"express": "^4.16.3",
"file-loader": "^1.1.11",
"html-webpack-plugin": "^3.0.6",
"husky": "^1.0.0-rc.9",
"if-env": "^1.0.4",
"karmatic": "^1.1.7",
"loader-utils": "^1.1.0",
"mini-css-extract-plugin": "^0.3.0",
"mocha": "^5.2.0",
"node-sass": "^4.7.2",
"optimize-css-assets-webpack-plugin": "^4.0.0",
"progress-bar-webpack-plugin": "^1.11.0",
"puppeteer": "^1.3.0",
"raw-loader": "^0.5.1",
"sass-loader": "^6.0.7",
"script-ext-html-webpack-plugin": "^2.0.1",

68
test/e2e/index.js Normal file
View File

@ -0,0 +1,68 @@
/* eslint-env mocha */
const path = require('path');
const express = require('express');
const http = require('http');
const puppeteer = require('puppeteer');
const { fingerDown } = require('../lib/finger');
const { expect } = require('chai');
async function staticWebServer (path) {
// Start a static web server
const app = express();
app.use(express.static(path));
// Port 0 means let the OS select a port
const server = http.createServer(app).listen(0, 'localhost');
await new Promise(resolve => server.on('listening', resolve));
// Read back the bound address
const address = server.address();
return { server, address };
}
describe('some e2e test', function () {
before(async function () {
// Start webserver
const { address, server } = await staticWebServer(path.resolve(__dirname, '../fixtures'));
this.address = `http://${address.address}:${address.port}`;
this.server = server;
// Start browser
this.browser = await puppeteer.launch();
this.page = await this.browser.newPage();
await this.page.goto(`${this.address}/sample.html`, {
waitUntil: 'networkidle2'
});
});
it('can tap', async function () {
const btn = await this.page.$('button');
await btn.tap();
const result = await this.page.evaluate(_ => {
return window.lol;
});
expect(result).to.equal(true);
});
it('can tap manually', async function () {
const btn = await this.page.$('button');
const box = await btn.boundingBox();
const finger = fingerDown(
this.page,
box.x + box.width / 2,
box.y + box.height / 2
);
finger.up();
const result = await this.page.evaluate(_ => {
return window.lol;
});
expect(result).to.equal(true);
});
it('does some taps', async function () {});
after(async function () {
this.server.close();
await this.browser.close();
});
});

6
test/fixtures/sample.html vendored Normal file
View File

@ -0,0 +1,6 @@
<!doctype html>
<button>Test me</button>
<script>
document.querySelector('button').onclick = _ => window.lol = true;
</script>

61
test/lib/finger.js Normal file
View File

@ -0,0 +1,61 @@
let touchPoints = [];
let idCnt = 0;
class Finger {
constructor (point, page) {
this._point = point;
this._page = page;
}
move (x, y) {
if (!this._point) return;
Object.assign(this._point, {
x: Math.floor(x),
y: Math.floor(y)
});
this._page.touchscreen._client.send('Input.dispatchTouchEvent', {
type: 'touchMove',
touchPoints,
modifiers: this._page._keyboard._modifiers
});
}
up () {
if (!this._point) return;
const idx = touchPoints.indexOf(this._point);
touchPoints = touchPoints.splice(idx, 1);
this._point = null;
if (touchPoints.length === 0) {
this._page.touchscreen._client.send('Input.dispatchTouchEvent', {
type: 'touchEnd',
modifiers: this._page._keyboard._modifiers
});
} else {
this._page.touchscreen._client.send('Input.dispatchTouchEvent', {
type: 'touchMove',
touchPoints,
modifiers: this._page._keyboard._modifiers
});
}
}
}
function fingerDown (page, x, y) {
const id = idCnt++;
const point = {
x: Math.round(x),
y: Math.round(y),
id
};
touchPoints.push(point);
page.touchscreen._client.send('Input.dispatchTouchEvent', {
type: 'touchStart',
touchPoints,
modifiers: page._keyboard._modifiers
});
return new Finger(point, page);
}
module.exports = {
fingerDown
};

9
test/lib/util.ts Normal file
View File

@ -0,0 +1,9 @@
import {bitmapToImageData} from "../../src/lib/util";
const expect = chai.expect;
describe("util.bitmapToImageData", function () {
it("is a function", function () {
expect(bitmapToImageData).to.be.a('function');
});
});

27
test/unit/index.test.js Normal file
View File

@ -0,0 +1,27 @@
/* eslint-env jest */
import { h, Component, render } from 'preact';
import App from '../../src/components/app';
describe('<App />', () => {
let scratch;
beforeEach(() => {
scratch = document.createElement('div');
document.body.appendChild(scratch);
});
afterEach(() => {
render(<span />, scratch, scratch.firstChild);
scratch.remove();
});
it('should render', () => {
let app;
render(<App ref={c => { app = c; }} />, scratch);
expect(app instanceof Component).toBe(true);
expect(scratch.innerHTML).toBe(
`<div id="app" class="app__1wROX"><div><h1>Select an image</h1><input type="file"></div></div>`
);
});
});