Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
34be93b0f0 | |||
e95ea80c4f | |||
44412f6217 | |||
08362a4b2d | |||
10de559a0c | |||
e9dad3d884 | |||
668acf2698 | |||
7042491257 | |||
307e1f9356 |
20
Dockerfile
Normal file
20
Dockerfile
Normal 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
16392
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
@ -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
68
test/e2e/index.js
Normal 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
6
test/fixtures/sample.html
vendored
Normal 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
61
test/lib/finger.js
Normal 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
9
test/lib/util.ts
Normal 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
27
test/unit/index.test.js
Normal 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>`
|
||||
);
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user