Skip to content

Commit 7985e05

Browse files
committed
Add automated tests for chrome app
1 parent b9cabf7 commit 7985e05

12 files changed

+505
-3
lines changed

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"test": "npm run lint && npm run unit && npm run integration",
2424
"unit": "npx mocha './src/*-unit.js' --reporter spec --require babel-register --require babel-polyfill testutils.js",
2525
"integration": "npm run integration-ws",
26-
"integration-ws": "npm run build && npx webpack --config webpack.config.test.js -p && npx wdio wdio.conf.js"
26+
"integration-ws": "npm run build && npx webpack --config webpack.config.test.js -p && npx wdio wdio.conf.js",
27+
"integration-chrome": "cp node_modules/chai/chai.js node_modules/mocha/mocha.js node_modules/mocha/mocha.css test/chrome/ && npm run build && npx webpack --config webpack.config.chrome.js && npx babel-node test/chrome/run.js"
2728
},
2829
"bugs": {
2930
"url": "https://github.com/emailjs/emailjs-tcp-socket/issues"
@@ -42,18 +43,20 @@
4243
"babel-preset-env": "^1.6.1",
4344
"babel-register": "^6.26.0",
4445
"chai": "^4.1.2",
46+
"chrome-launcher": "^0.10.0",
4547
"emailjs-tcp-proxy": "^1.0.2",
4648
"hoodiecrow-imap": "^2.1.0",
4749
"mocha": "^4.0.1",
4850
"nodemon": "^1.12.5",
4951
"pre-commit": "^1.2.2",
52+
"shelljs": "^0.7.8",
5053
"sinon": "^4.1.3",
5154
"standard": "^10.0.3",
52-
"starttls": "https://github.com/felixhammerl/starttls/tarball/master",
5355
"wdio-chromedriver-service": "^0.1.1",
5456
"wdio-mocha-framework": "^0.5.11",
5557
"webdriverio": "^4.9.11",
56-
"webpack": "^3.10.0"
58+
"webpack": "^3.10.0",
59+
"ws": "^3.3.2"
5760
},
5861
"standard": {
5962
"globals": [

test/chrome/background.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
'use strict'
2+
3+
chrome.app.runtime.onLaunched.addListener(function () {
4+
chrome.app.window.create('index.html', { width: 1024, height: 650 })
5+
})

test/chrome/chrome-integration.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* eslint-ignore no-unused-expressions */
2+
3+
import TCPSocket from '../../'
4+
import { PORT_NET, PORT_STARTTLS, PORT_TLS } from './constants'
5+
const { expect } = window.chai
6+
7+
const a2s = arr => String.fromCharCode.apply(null, new Uint8Array(arr))
8+
const s2a = str => new Uint8Array(str.split('').map(char => char.charCodeAt(0))).buffer
9+
10+
describe('TCP chrome shim integration tests', function () {
11+
const payload = 'the.payload.woopwoop!'
12+
let received
13+
14+
beforeEach(done => {
15+
received = ''
16+
setTimeout(done, 500)
17+
})
18+
19+
describe('tcp', function () {
20+
it('should open, read, write, and close', function (done) {
21+
const socket = TCPSocket.open('localhost', PORT_NET)
22+
socket.onopen = () => { socket.send(s2a(payload)) }
23+
socket.onclose = () => {
24+
expect(received).to.equal(payload)
25+
done()
26+
}
27+
socket.ondata = ({ data }) => {
28+
received += a2s(data)
29+
if (received === payload) {
30+
socket.close()
31+
}
32+
}
33+
})
34+
})
35+
36+
describe('tls', function () {
37+
it('should open, read, write, and close', function (done) {
38+
const useSecureTransport = true
39+
var socket = TCPSocket.open('localhost', PORT_TLS, { useSecureTransport })
40+
socket.onopen = () => { socket.send(s2a(payload)) }
41+
socket.onclose = () => {
42+
expect(received).to.equal(payload)
43+
done()
44+
}
45+
socket.ondata = ({ data }) => {
46+
received += a2s(data)
47+
if (received === payload) {
48+
socket.close()
49+
}
50+
}
51+
})
52+
})
53+
54+
describe.skip('starttls', function () {
55+
it('should open, read, write, and close', function (done) {
56+
var socket = TCPSocket.open('localhost', PORT_STARTTLS)
57+
socket.onopen = () => {
58+
socket.upgradeToSecure()
59+
socket.send(s2a(payload))
60+
}
61+
socket.onclose = () => {
62+
expect(received).to.equal(payload)
63+
done()
64+
}
65+
socket.ondata = ({ data }) => {
66+
received += a2s(data)
67+
if (received === payload) {
68+
socket.close()
69+
}
70+
}
71+
})
72+
})
73+
})

test/chrome/constants.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const PORT_NET = 8000
2+
export const PORT_TLS = 8001
3+
export const PORT_STARTTLS = 8002

test/chrome/index.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html>
2+
<html style="overflow-y: auto">
3+
4+
<head>
5+
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
6+
<link href="mocha.css" rel="stylesheet" />
7+
</head>
8+
9+
<body>
10+
<div id="mocha"></div>
11+
12+
<script src="mocha.js"></script>
13+
<script src="chai.js"></script>
14+
<script src="mocha-prepare.js"></script>
15+
<script src="chrome-integration.comp.js"></script>
16+
<script src="mocha-run.js"></script>
17+
</body>
18+
19+
</html>

test/chrome/manifest.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "tcp-socket with chrome.sockets",
3+
"description": "Example of a TCPSocket shim for Chrome Packaged Apps",
4+
"version": "0.0.1",
5+
"manifest_version": 2,
6+
"offline_enabled": false,
7+
"permissions": [
8+
{
9+
"socket": [
10+
"tcp-connect"
11+
]
12+
}
13+
],
14+
// "sockets": {
15+
// "tcp": {
16+
// "connect": ""
17+
// }
18+
// },
19+
"app": {
20+
"background": {
21+
"scripts": [
22+
"background.js"
23+
]
24+
}
25+
}
26+
}

test/chrome/mocha-prepare.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
(function () {
2+
'use strict'
3+
window.mocha.setup('bdd')
4+
})()

test/chrome/mocha-run.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
(function () {
2+
'use strict'
3+
window.mocha.run(function (failureCount) {
4+
if (!failureCount) {
5+
console.log('All tests passed!')
6+
} else {
7+
console.log('Failure count: ' + failureCount)
8+
}
9+
})
10+
})()

test/chrome/remote-debugger.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// taken from https://github.com/tejohnso/chrome-app-test-runner
2+
3+
import WebSocket from 'ws'
4+
import { get } from 'http'
5+
6+
let ws
7+
let messageHandler
8+
let intervalHandler
9+
let evalPromiseResolverObject = { resolve: 0 }
10+
11+
function createConnectionResponse (resolver, intervalHandler) {
12+
return function (resp) {
13+
var chunks = ''
14+
15+
resp.on('data', function (data) {
16+
chunks += data
17+
})
18+
resp.on('end', function () {
19+
var inspectables
20+
21+
inspectables = JSON.parse(chunks).filter(function (tabData) {
22+
return tabData.type === 'app'
23+
})[0]
24+
25+
if (inspectables && inspectables.webSocketDebuggerUrl) {
26+
clearInterval(intervalHandler.handle)
27+
ws = new WebSocket(inspectables.webSocketDebuggerUrl)
28+
ws.onopen = function () {
29+
ws.send(JSON.stringify({ 'id': 1, 'method': 'Console.enable' }))
30+
}
31+
ws.onmessage = function (event) {
32+
var data = JSON.parse(event.data)
33+
34+
if (data.id === 9) {
35+
return evalPromiseResolverObject.resolver(data.result.result.value)
36+
}
37+
messageHandler(data)
38+
}
39+
resolver()
40+
}
41+
})
42+
}
43+
}
44+
45+
function createErrorResponse (rejecter) {
46+
return function (resp) {
47+
console.log(resp)
48+
clearInterval(intervalHandler.handle)
49+
rejecter()
50+
}
51+
}
52+
53+
export function attachDebugger () {
54+
return new Promise(function (resolve, reject) {
55+
intervalHandler = { handle: 0 }
56+
let connectionResponse = createConnectionResponse(resolve, intervalHandler)
57+
let errorResponse = createErrorResponse(reject)
58+
59+
intervalHandler.handle = setInterval(function () {
60+
get('http://localhost:9222/json/list', connectionResponse)
61+
.on('error', errorResponse)
62+
}, 500)
63+
})
64+
}
65+
66+
export function setDebugHandler (handler) {
67+
messageHandler = handler
68+
}

test/chrome/run.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import fs from 'fs'
2+
import net from 'net'
3+
import tls from 'tls'
4+
import startTls from './starttls'
5+
import { pathOr } from 'ramda'
6+
import { join } from 'path'
7+
import { attachDebugger, setDebugHandler } from './remote-debugger.js'
8+
import { PORT_NET, PORT_STARTTLS, PORT_TLS } from './constants'
9+
import { launch } from 'chrome-launcher'
10+
11+
function createServers () {
12+
const key = fs.readFileSync(join(__dirname, '..', '..', 'crt', 'server.key'), 'utf8')
13+
const cert = fs.readFileSync(join(__dirname, '..', '..', 'crt', 'server.crt'), 'utf8')
14+
const s1 = net.createServer(socket => { socket.pipe(socket) })
15+
const s2 = tls.createServer({ key, cert }, socket => { socket.pipe(socket) })
16+
const s3 = startTls.createServer(socket => {
17+
socket.upgrade({ key, cert, requestCert: false, rejectUnauthorized: false }, () => {
18+
socket.pipe(socket)
19+
})
20+
})
21+
22+
const servers = [[s1, PORT_NET], [s2, PORT_TLS], [s3, PORT_STARTTLS]]
23+
const startServers = () => Promise.all(servers.map(([server, port]) => new Promise((resolve, reject) => { server.listen(port, resolve) })))
24+
const stopServers = () => Promise.all(servers.map(([s, _]) => new Promise((resolve, reject) => { s.close(resolve) })))
25+
return { startServers, stopServers }
26+
}
27+
28+
const { startServers, stopServers } = createServers()
29+
let chrome
30+
31+
startServers()
32+
.then(() => launch({ port: 9222, chromeFlags: [`--load-and-launch-app=${__dirname}`], enableExtensions: true }))
33+
.then(child => { chrome = child })
34+
.then(() => attachDebugger())
35+
.then(() => new Promise((resolve, reject) => {
36+
setDebugHandler(data => {
37+
var message = pathOr('', ['params', 'message', 'text'])(data)
38+
if (message === 'All tests passed!') {
39+
resolve(message)
40+
} else if (/Failure count: [\d]+/.test(message)) {
41+
reject(message)
42+
}
43+
})
44+
}))
45+
.then(msg => {
46+
console.log(msg)
47+
chrome.kill()
48+
stopServers()
49+
process.exit(0)
50+
})
51+
.catch(e => {
52+
console.error(e)
53+
chrome.kill()
54+
stopServers()
55+
process.exit(1)
56+
})

0 commit comments

Comments
 (0)