1 | 'use strict'
|
2 |
|
3 | const { screenshot, stop } = require('./browsers')
|
4 | const { collect } = require('./coverage')
|
5 | const { UTRError } = require('./error')
|
6 | const { getOutput } = require('./output')
|
7 | const { basename } = require('path')
|
8 | const { filename, stripUrlHash } = require('./tools')
|
9 |
|
10 | function error (job, url, details = '') {
|
11 | stop(job, url)
|
12 | job.failed = true
|
13 | throw UTRError.QUNIT_ERROR(details)
|
14 | }
|
15 |
|
16 | function invalidTestId (job, url, testId) {
|
17 | error(job, url, `No QUnit unit test found with id ${testId}`)
|
18 | }
|
19 |
|
20 | function merge (targetModules, modules) {
|
21 | let count = 0
|
22 | modules.forEach(module => {
|
23 | const { name } = module
|
24 | const targetModule = targetModules.filter(({ name: targetName }) => name === targetName)[0]
|
25 | if (targetModule === undefined) {
|
26 | targetModules.push(module)
|
27 | } else {
|
28 | module.tests.forEach(test => {
|
29 | const targetTest = targetModule.tests.filter(({ testId }) => test.testId === testId)[0]
|
30 | if (!targetTest) {
|
31 | targetModule.tests.push(test)
|
32 | }
|
33 | })
|
34 | }
|
35 | count += module.tests.length
|
36 | })
|
37 | return count
|
38 | }
|
39 |
|
40 | function get (job, urlWithHash, { testId, modules, isOpa } = {}) {
|
41 | const url = stripUrlHash(urlWithHash)
|
42 | const page = job.qunitPages && job.qunitPages[url]
|
43 | if (!page) {
|
44 | error(job, url, `No QUnit page found for ${urlWithHash}`)
|
45 | }
|
46 | if (modules && modules.length) {
|
47 | page.count = merge(page.modules, modules)
|
48 | }
|
49 | if (!page.isOpa && isOpa) {
|
50 | page.isOpa = true
|
51 | }
|
52 | let testModule
|
53 | let test
|
54 | if (testId !== undefined) {
|
55 | page.modules.every(module => {
|
56 | test = module.tests.find(test => test.testId === testId)
|
57 | if (test === undefined) {
|
58 | return true
|
59 | } else {
|
60 | testModule = module
|
61 | return false
|
62 | }
|
63 | })
|
64 | if (!test) {
|
65 | invalidTestId(job, url, testId)
|
66 | }
|
67 | }
|
68 | return { url, page, testModule, test }
|
69 | }
|
70 |
|
71 | async function done (job, urlWithHash, report) {
|
72 | const { url, page } = get(job, urlWithHash)
|
73 | if (page.count === 0) {
|
74 | return
|
75 | }
|
76 | if (job.browserCapabilities.screenshot) {
|
77 | try {
|
78 | await screenshot(job, url, 'done')
|
79 | } catch (error) {
|
80 | getOutput(job).genericError(error, url)
|
81 | }
|
82 | }
|
83 | page.end = new Date()
|
84 | if (report.__coverage__) {
|
85 | await collect(job, url, report.__coverage__)
|
86 | delete report.__coverage__
|
87 | }
|
88 | page.report = report
|
89 | stop(job, url)
|
90 | }
|
91 |
|
92 | module.exports = {
|
93 | get,
|
94 |
|
95 | async begin (job, urlWithHash, details) {
|
96 | getOutput(job).debug('qunit', 'begin', urlWithHash, details)
|
97 | const { isOpa, totalTests, modules } = details
|
98 | const url = stripUrlHash(urlWithHash)
|
99 | if (!job.qunitPages) {
|
100 | job.qunitPages = {}
|
101 | }
|
102 | const qunitPage = {
|
103 | id: filename(url),
|
104 | start: new Date(),
|
105 | isOpa: !!isOpa,
|
106 | failed: 0,
|
107 | passed: 0,
|
108 | count: totalTests,
|
109 | modules
|
110 | }
|
111 | job.qunitPages[url] = qunitPage
|
112 | },
|
113 |
|
114 | async testStart (job, urlWithHash, details) {
|
115 | getOutput(job).debug('qunit', 'testStart', urlWithHash, details)
|
116 | const { test } = get(job, urlWithHash, details)
|
117 | test.start = new Date()
|
118 | },
|
119 |
|
120 | async log (job, urlWithHash, details) {
|
121 | getOutput(job).debug('qunit', 'log', urlWithHash, details)
|
122 | const { url, page, test } = get(job, urlWithHash, details)
|
123 | const { isOpa, modules, module, name, testId, ...log } = details
|
124 | if (!test) {
|
125 | invalidTestId(job, url, testId)
|
126 | }
|
127 | if (!test.logs) {
|
128 | test.logs = []
|
129 | }
|
130 | test.logs.push(log)
|
131 | if (page.isOpa && job.browserCapabilities.screenshot && job.screenshot) {
|
132 | try {
|
133 | const absoluteName = await screenshot(job, url, `${testId}-${log.runtime}`)
|
134 | log.screenshot = basename(absoluteName)
|
135 | } catch (error) {
|
136 | getOutput(job).genericError(error, url)
|
137 | }
|
138 | }
|
139 | },
|
140 |
|
141 | async testDone (job, urlWithHash, details) {
|
142 | getOutput(job).debug('qunit', 'testDone', urlWithHash, details)
|
143 | const { name, module, testId, assertions, ...report } = details
|
144 | const { failed } = report
|
145 | const { url, page, test } = get(job, urlWithHash, { testId })
|
146 | if (!test) {
|
147 | invalidTestId(job, url, testId)
|
148 | }
|
149 | if (failed) {
|
150 | if (job.browserCapabilities.screenshot) {
|
151 | try {
|
152 | const absoluteName = await screenshot(job, url, testId)
|
153 | test.screenshot = basename(absoluteName)
|
154 | } catch (error) {
|
155 | getOutput(job).genericError(error, url)
|
156 | }
|
157 | }
|
158 | ++page.failed
|
159 | job.failed = true
|
160 | } else {
|
161 | ++page.passed
|
162 | }
|
163 | test.end = new Date()
|
164 | test.report = report
|
165 | if (job.failOpaFast && failed) {
|
166 |
|
167 | page.modules.forEach(module => {
|
168 | module.tests.forEach(test => {
|
169 | if (!test.report) {
|
170 | test.skip = true
|
171 | }
|
172 | })
|
173 | })
|
174 | await done(job, urlWithHash, {
|
175 | failed: page.failed,
|
176 | passed: page.passed,
|
177 | total: page.count,
|
178 | runtime: 0
|
179 | })
|
180 | }
|
181 | },
|
182 |
|
183 | done
|
184 | }
|