UNPKG

3.7 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3'use strict'
4
5const program = require('commander')
6
7function collectPath(val, paths) {
8 paths.push(val)
9 return paths
10}
11
12program
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
19program.on('--help', function() {
20 console.log(' Examples:')
21 console.log('')
22 console.log(' $ ocean serve --port 4000')
23 console.log('')
24})
25
26program.parse(process.argv)
27
28// const debug = require('debug')('porter')
29const fs = require('fs')
30const http = require('http')
31const Koa = require('koa')
32const path = require('path')
33const puppeteer = require('puppeteer')
34
35const exists = fs.existsSync
36
37const cwd = process.cwd()
38const pkgPath = path.join(cwd, 'package.json')
39
40if (!exists(pkgPath)) {
41 console.error('Failed to find package.json')
42 process.exit()
43}
44
45serve().catch(err => console.error(err.stack))
46
47async 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
108async 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 source: { serve: true }
120 })
121 app.use(porter.async())
122
123 const server = http.createServer(app.callback())
124 const port = program.headless ? 0 : program.port
125 await new Promise((resolve, reject) => {
126 server.listen({ port }, resolve)
127 server.on('error', reject)
128 })
129 console.log('Server started at', server.address().port)
130 if (program.headless) {
131 server.unref()
132 await test({ port: server.address().port })
133 }
134}