|
1 | 1 | #!/usr/bin/env node
|
2 | 2 | 'use strict';
|
3 | 3 |
|
| 4 | +const fs = require('node:fs'); |
4 | 5 | const playwright = require('playwright');
|
5 |
| - |
6 | 6 | const { identity, pickBy } = require('lodash');
|
| 7 | +const { SourceMapConsumer } = require('source-map'); |
| 8 | +const stacktraceParser = require('stacktrace-parser'); |
7 | 9 |
|
8 | 10 | var MochaSpecReporter = require('mocha').reporters.Spec;
|
9 | 11 | const createMochaStatsCollector = require('mocha/lib/stats-collector');
|
@@ -61,6 +63,8 @@ const qs = {
|
61 | 63 | testUrl += '?';
|
62 | 64 | testUrl += new URLSearchParams(pickBy(qs, identity));
|
63 | 65 |
|
| 66 | +let stackConsumer; |
| 67 | + |
64 | 68 | class ArrayMap extends Map {
|
65 | 69 | get(key) {
|
66 | 70 | if (!this.has(key)) {
|
@@ -108,6 +112,35 @@ class RemoteRunner {
|
108 | 112 |
|
109 | 113 | this.triggerHandlers(event.name, [ obj, event.err ]);
|
110 | 114 |
|
| 115 | + if (event.err && stackConsumer) { |
| 116 | + let stackMapped; |
| 117 | + const mappedStack = stacktraceParser |
| 118 | + .parse(event.err.stack) |
| 119 | + .map(v => { |
| 120 | + if (v.file === 'http://127.0.0.1:8000/packages/node_modules/pouchdb/dist/pouchdb.min.js') { |
| 121 | + const NON_UGLIFIED_HEADER_LENGTH = 6; // number of lines of header added in build-pouchdb.js |
| 122 | + const target = { line:v.lineNumber-NON_UGLIFIED_HEADER_LENGTH, column:v.column-1 }; |
| 123 | + const mapped = stackConsumer.originalPositionFor(target); |
| 124 | + v.file = 'packages/node_modules/pouchdb/dist/pouchdb.js'; |
| 125 | + v.lineNumber = mapped.line; |
| 126 | + v.column = mapped.column+1; |
| 127 | + if (mapped.name !== null) { |
| 128 | + v.methodName = mapped.name; |
| 129 | + } |
| 130 | + stackMapped = true; |
| 131 | + } |
| 132 | + return v; |
| 133 | + }) |
| 134 | + // NodeJS stack frame format: https://nodejs.org/docs/latest/api/errors.html#errorstack |
| 135 | + .map(v => `at ${v.methodName} (${v.file}:${v.lineNumber}:${v.column})`) |
| 136 | + .join('\n '); |
| 137 | + if (stackMapped) { |
| 138 | + console.log(` [${obj.title}] Minified error stacktrace mapped to:`); |
| 139 | + console.log(` ${event.err.name||'Error'}: ${event.err.message}`); |
| 140 | + console.log(` ${mappedStack}`); |
| 141 | + } |
| 142 | + } |
| 143 | + |
111 | 144 | switch (event.name) {
|
112 | 145 | case 'fail': this.handleFailed(); break;
|
113 | 146 | case 'end': this.handleEnd(); break;
|
@@ -152,19 +185,24 @@ function BenchmarkJsonReporter(runner) {
|
152 | 185 | if (runner.failed) {
|
153 | 186 | console.log('Runner failed; JSON will not be writted.');
|
154 | 187 | } else {
|
155 |
| - const { mkdirSync, writeFileSync } = require('fs'); |
156 |
| - |
157 | 188 | const resultsDir = 'perf-test-results';
|
158 |
| - mkdirSync(resultsDir, { recursive: true }); |
| 189 | + fs.mkdirSync(resultsDir, { recursive: true }); |
159 | 190 |
|
160 | 191 | const jsonPath = `${resultsDir}/${new Date().toISOString()}.json`;
|
161 |
| - writeFileSync(jsonPath, JSON.stringify(results, null, 2)); |
| 192 | + fs.writeFileSync(jsonPath, JSON.stringify(results, null, 2)); |
162 | 193 | console.log('Wrote JSON results to:', jsonPath);
|
163 | 194 | }
|
164 | 195 | });
|
165 | 196 | }
|
166 | 197 |
|
167 | 198 | async function startTest() {
|
| 199 | + if (qs.src === '../../packages/node_modules/pouchdb/dist/pouchdb.min.js') { |
| 200 | + const mapPath = './packages/node_modules/pouchdb/dist/pouchdb.min.js.map'; |
| 201 | + const rawMap = fs.readFileSync(mapPath, { encoding:'utf8' }); |
| 202 | + const jsonMap = JSON.parse(rawMap); |
| 203 | + stackConsumer = await new SourceMapConsumer(jsonMap); |
| 204 | + } |
| 205 | + |
168 | 206 | try {
|
169 | 207 | console.log('Starting', browserName, 'on', testUrl);
|
170 | 208 |
|
|
0 commit comments