-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.mjs
180 lines (160 loc) · 4.86 KB
/
index.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
import TestRunnerCli from 'test-runner'
import { builtinModules } from 'module'
import currentModulePaths from 'current-module-paths'
import path from 'path'
const { __dirname } = currentModulePaths(import.meta.url)
class WebRunnerCli extends TestRunnerCli {
constructor (options) {
super(options)
this.optionDefinitions.push(
{
name: 'show',
type: Boolean,
description: 'Show the Chromium window'
},
{
name: 'tom',
type: Boolean,
description: 'Show the generated TOM'
}
)
const treeIndex = this.optionDefinitions.findIndex(i => i.name === 'tree')
this.optionDefinitions.splice(treeIndex, 1)
}
async printUsage () {
const commandLineUsage = await this.loadModule('command-line-usage')
this.errorLog(commandLineUsage([
{
header: 'web-runner',
content: 'Run a TOM in Chromium.'
},
{
header: 'Synopsis',
content: '$ web-runner [<options>] {underline file} {underline ...}'
},
{
header: 'Options',
optionList: this.optionDefinitions,
hide: 'files'
},
{
header: 'View options',
optionList: this.viewOptionDefinitions
},
{
content: 'For more information see: {underline https://github.com/test-runner-js/web-runner}'
}
]))
}
async createTomBundle (tomFiles) {
const { rollup } = await import('rollup')
const resolve = (await import('@rollup/plugin-node-resolve')).default
const commonJs = (await import('@rollup/plugin-commonjs')).default
if (tomFiles.length > 1) {
throw new Error('one file at a time first')
}
const bundle = await rollup({
input: tomFiles,
external: [...builtinModules, 'https://www.chaijs.com/chai.js'],
plugins: [
resolve({ preferBuiltins: true }),
commonJs()
]
})
const generated = await bundle.generate({
format: 'esm'
})
return generated.output[0].code
}
async launch (options) {
const puppeteer = (await import('puppeteer')).default
const Lws = (await import('lws')).default
const LwsStatic = (await import('lws-static')).default
const browser = await puppeteer.launch({ headless: !options.show })
const page = (await browser.pages())[0]
const port = 7357
const tomBundle = await this.createTomBundle(options.files)
class TomBundle {
middleware (config) {
return async (ctx, next) => {
if (ctx.request.url === '/tom-bundle.mjs') {
ctx.response.type = 'text/javascript'
ctx.response.body = tomBundle
}
await next()
}
}
}
const lws = await Lws.create({
port,
stack: [TomBundle, LwsStatic],
directory: path.resolve(__dirname, 'ui')
})
await page.goto(`http://localhost:${port}/index.html`)
page.on('console', async msg => {
const text = msg.text()
/* avoid favicon 404s */
if (!/404/.test(text)) {
console.log(text)
}
})
page.on('pageerror', err => {
console.log('PAGEERROR')
console.error(err)
browser.close()
lws.server.close()
})
browser.on('disconnected', () => {
lws.server.close()
})
const state = await page.evaluate(async (show) => {
const TestRunnerCore = (await import('/node_modules/@test-runner/core/dist/index.mjs')).default
const DefaultView = (await import('/node_modules/@test-runner/default-view/dist/index.mjs')).default
let tom = (await import('/tom-bundle.mjs')).default
/* TestRunnerCore will accept a Promise but not a Puppeteer `JSHandle@promise`, so resolve it first. */
tom = await tom
let runner
if (show) {
runner = new TestRunnerCore(tom)
document.querySelector('test-runner').setRunner(runner)
} else {
runner = new TestRunnerCore(tom, { view: new DefaultView() })
}
await runner.start()
return runner.state
}, options.show)
if (state === 'fail') {
process.exitCode = 1
}
if (!options.show) {
await browser.close()
lws.server.close()
}
return state
}
async start () {
await this.getAllOptionDefinitions()
const options = await this.getOptions()
/* --help */
if (options.help) {
return this.printUsage()
/* --version */
} else if (options.version) {
return this.printVersion()
/* --tom */
} else if (options.tom) {
const generated = await this.createTomBundle(options.files)
console.log(generated)
/* --files */
} else {
if (options.files && options.files.length) {
options.files = await this.expandGlobs(options.files)
return this.launch(options)
} else {
this.errorLog('one or more input files required')
return this.printUsage()
}
}
}
}
export default WebRunnerCli