1 | #!/usr/bin/env node
|
2 |
|
3 | 'use strict'
|
4 |
|
5 | const program = require('commander')
|
6 |
|
7 | function collectPath(val, paths) {
|
8 | paths.push(val)
|
9 | return paths
|
10 | }
|
11 |
|
12 | program
|
13 | .option('-H --headless [headless]', 'run headless tests right after server is started', false)
|
14 | .option('-p --port [port]', 'port to listen on', 5000)
|
15 | .option('-P --paths [paths]', 'components load path', collectPath, [])
|
16 | .option('-s --suite [suite]', 'run suites right after server is started', 'test/suite')
|
17 | .option('-t --timeout [timeout]', 'timeout on headless tests', 15000)
|
18 |
|
19 | program.on('--help', function() {
|
20 | console.log(' Examples:')
|
21 | console.log('')
|
22 | console.log(' $ ocean serve --port 4000')
|
23 | console.log('')
|
24 | })
|
25 |
|
26 | program.parse(process.argv)
|
27 |
|
28 |
|
29 | const fs = require('fs')
|
30 | const http = require('http')
|
31 | const Koa = require('koa')
|
32 | const path = require('path')
|
33 | const puppeteer = require('puppeteer')
|
34 |
|
35 | const exists = fs.existsSync
|
36 |
|
37 | const cwd = process.cwd()
|
38 | const pkgPath = path.join(cwd, 'package.json')
|
39 |
|
40 | if (!exists(pkgPath)) {
|
41 | console.error('Failed to find package.json')
|
42 | process.exit()
|
43 | }
|
44 |
|
45 | serve().catch(err => console.error(err.stack))
|
46 |
|
47 | async function test({ port }) {
|
48 | const browser = await puppeteer.launch()
|
49 | const page = await browser.newPage()
|
50 |
|
51 | const report = result => {
|
52 | const [status, { fullTitle, duration, failures, tests }] = result
|
53 | switch (status) {
|
54 | case 'start':
|
55 | console.log('')
|
56 | break
|
57 | case 'pass':
|
58 | console.log(` ✔ ${fullTitle} (${duration}ms)`)
|
59 | break
|
60 | case 'fail':
|
61 | console.log(` ✗ ${fullTitle} (${duration}ms)`)
|
62 | break
|
63 | case 'end':
|
64 | console.log('')
|
65 | if (failures > 0) {
|
66 | console.log(` ✘ ${failures} of ${tests} test${tests > 1 ? 's' : ''} failed.`)
|
67 | } else {
|
68 | console.log(` ${tests} test${tests > 1 ? 's' : ''} completed (${duration}ms)`)
|
69 | }
|
70 | process.exit(failures)
|
71 | break
|
72 | default:
|
73 | throw new Error(`unknown status '${status}'`)
|
74 | }
|
75 | }
|
76 |
|
77 | const onConsoleMessage = async msg => {
|
78 | const args = await Promise.all(msg.args().map(arg => arg.jsonValue()))
|
79 | switch (msg.type()) {
|
80 | case 'warning':
|
81 | console.warn(...args)
|
82 | break
|
83 | case 'log':
|
84 | const text = args[0] == 'stdout:' ? args[1] : args[0]
|
85 | let result
|
86 | try { result = JSON.parse(text) } catch (err) {}
|
87 | if (result) {
|
88 | report(result)
|
89 | } else {
|
90 | console.log(...args)
|
91 | }
|
92 | break
|
93 | default:
|
94 | console[msg.type()](...args)
|
95 | }
|
96 | }
|
97 |
|
98 | page.on('console', onConsoleMessage)
|
99 | await page.goto(`http://localhost:${port}/runner.html?reporter=json-stream&suite=${program.suite}`, {
|
100 | timeout: program.timeout
|
101 | })
|
102 | await new Promise((resolve, reject) => {
|
103 | page.on('error', reject)
|
104 | page.on('pageerror', reject)
|
105 | })
|
106 | }
|
107 |
|
108 | async function serve() {
|
109 | const app = new Koa()
|
110 |
|
111 | const serveStatic = require('koa-static')
|
112 | app.use(serveStatic(path.join(cwd, 'tmp')))
|
113 | app.use(serveStatic(path.join(__dirname, '../public')))
|
114 |
|
115 | if (program.paths.length == 0) program.paths.push('.')
|
116 | const Porter = require('@cara/porter')
|
117 | const porter = new Porter({
|
118 | paths: [...program.paths, path.join(__dirname, '../public')],
|
119 | serveSource: true,
|
120 |
|
121 | cacheExcept: '*',
|
122 |
|
123 | cacheDest: program.headless ? '/tmp/noop' : 'tmp'
|
124 | })
|
125 | app.use(porter.async())
|
126 |
|
127 | const server = http.createServer(app.callback())
|
128 | const port = program.headless ? 0 : program.port
|
129 | await new Promise((resolve, reject) => {
|
130 | server.listen({ port }, resolve)
|
131 | server.on('error', reject)
|
132 | })
|
133 | console.log('Server started at', server.address().port)
|
134 | if (program.headless) {
|
135 | server.unref()
|
136 | await test({ port: server.address().port })
|
137 | }
|
138 | }
|