@browsermation/test 0.0.16 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cli.js +2 -2
- package/dist/index.js +561 -0
- package/dist/reporter/reporter.d.ts +6 -5
- package/dist/reporter.js +25 -7
- package/dist/tunnel.d.ts +2 -2
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -42871,7 +42871,7 @@ var {
|
|
|
42871
42871
|
// package.json
|
|
42872
42872
|
var package_default = {
|
|
42873
42873
|
name: "@browsermation/test",
|
|
42874
|
-
version: "0.0.
|
|
42874
|
+
version: "0.0.17",
|
|
42875
42875
|
description: "The testing platform for Playwright by Browsermation.",
|
|
42876
42876
|
main: "./dist/index.js",
|
|
42877
42877
|
types: "./dist/index.d.ts",
|
|
@@ -48248,7 +48248,7 @@ async function upload(zipBuffer, shardNumber, totalShards, playwrightConfig, opt
|
|
|
48248
48248
|
|
|
48249
48249
|
// src/tunnel.ts
|
|
48250
48250
|
var import_node_child_process = require("node:child_process");
|
|
48251
|
-
|
|
48251
|
+
function startTunnel(tunnelProcess, options) {
|
|
48252
48252
|
const tunnelDomain = `${options.subdomain || crypto.randomUUID()}.browsermationtunnel.com`;
|
|
48253
48253
|
tunnelProcess = (0, import_node_child_process.spawn)("ssh", [
|
|
48254
48254
|
"-o",
|
package/dist/index.js
CHANGED
|
@@ -53,6 +53,546 @@ function invariant(condition, message) {
|
|
|
53
53
|
throw new Error(value);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
57
|
+
var ANSI_BACKGROUND_OFFSET = 10;
|
|
58
|
+
var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
|
|
59
|
+
var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
|
|
60
|
+
var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
|
|
61
|
+
var styles = {
|
|
62
|
+
modifier: {
|
|
63
|
+
reset: [0, 0],
|
|
64
|
+
// 21 isn't widely supported and 22 does the same thing
|
|
65
|
+
bold: [1, 22],
|
|
66
|
+
dim: [2, 22],
|
|
67
|
+
italic: [3, 23],
|
|
68
|
+
underline: [4, 24],
|
|
69
|
+
overline: [53, 55],
|
|
70
|
+
inverse: [7, 27],
|
|
71
|
+
hidden: [8, 28],
|
|
72
|
+
strikethrough: [9, 29]
|
|
73
|
+
},
|
|
74
|
+
color: {
|
|
75
|
+
black: [30, 39],
|
|
76
|
+
red: [31, 39],
|
|
77
|
+
green: [32, 39],
|
|
78
|
+
yellow: [33, 39],
|
|
79
|
+
blue: [34, 39],
|
|
80
|
+
magenta: [35, 39],
|
|
81
|
+
cyan: [36, 39],
|
|
82
|
+
white: [37, 39],
|
|
83
|
+
// Bright color
|
|
84
|
+
blackBright: [90, 39],
|
|
85
|
+
gray: [90, 39],
|
|
86
|
+
// Alias of `blackBright`
|
|
87
|
+
grey: [90, 39],
|
|
88
|
+
// Alias of `blackBright`
|
|
89
|
+
redBright: [91, 39],
|
|
90
|
+
greenBright: [92, 39],
|
|
91
|
+
yellowBright: [93, 39],
|
|
92
|
+
blueBright: [94, 39],
|
|
93
|
+
magentaBright: [95, 39],
|
|
94
|
+
cyanBright: [96, 39],
|
|
95
|
+
whiteBright: [97, 39]
|
|
96
|
+
},
|
|
97
|
+
bgColor: {
|
|
98
|
+
bgBlack: [40, 49],
|
|
99
|
+
bgRed: [41, 49],
|
|
100
|
+
bgGreen: [42, 49],
|
|
101
|
+
bgYellow: [43, 49],
|
|
102
|
+
bgBlue: [44, 49],
|
|
103
|
+
bgMagenta: [45, 49],
|
|
104
|
+
bgCyan: [46, 49],
|
|
105
|
+
bgWhite: [47, 49],
|
|
106
|
+
// Bright color
|
|
107
|
+
bgBlackBright: [100, 49],
|
|
108
|
+
bgGray: [100, 49],
|
|
109
|
+
// Alias of `bgBlackBright`
|
|
110
|
+
bgGrey: [100, 49],
|
|
111
|
+
// Alias of `bgBlackBright`
|
|
112
|
+
bgRedBright: [101, 49],
|
|
113
|
+
bgGreenBright: [102, 49],
|
|
114
|
+
bgYellowBright: [103, 49],
|
|
115
|
+
bgBlueBright: [104, 49],
|
|
116
|
+
bgMagentaBright: [105, 49],
|
|
117
|
+
bgCyanBright: [106, 49],
|
|
118
|
+
bgWhiteBright: [107, 49]
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
var modifierNames = Object.keys(styles.modifier);
|
|
122
|
+
var foregroundColorNames = Object.keys(styles.color);
|
|
123
|
+
var backgroundColorNames = Object.keys(styles.bgColor);
|
|
124
|
+
var colorNames = [...foregroundColorNames, ...backgroundColorNames];
|
|
125
|
+
function assembleStyles() {
|
|
126
|
+
const codes = /* @__PURE__ */ new Map();
|
|
127
|
+
for (const [groupName, group] of Object.entries(styles)) {
|
|
128
|
+
for (const [styleName, style] of Object.entries(group)) {
|
|
129
|
+
styles[styleName] = {
|
|
130
|
+
open: `\x1B[${style[0]}m`,
|
|
131
|
+
close: `\x1B[${style[1]}m`
|
|
132
|
+
};
|
|
133
|
+
group[styleName] = styles[styleName];
|
|
134
|
+
codes.set(style[0], style[1]);
|
|
135
|
+
}
|
|
136
|
+
Object.defineProperty(styles, groupName, {
|
|
137
|
+
value: group,
|
|
138
|
+
enumerable: false
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
Object.defineProperty(styles, "codes", {
|
|
142
|
+
value: codes,
|
|
143
|
+
enumerable: false
|
|
144
|
+
});
|
|
145
|
+
styles.color.close = "\x1B[39m";
|
|
146
|
+
styles.bgColor.close = "\x1B[49m";
|
|
147
|
+
styles.color.ansi = wrapAnsi16();
|
|
148
|
+
styles.color.ansi256 = wrapAnsi256();
|
|
149
|
+
styles.color.ansi16m = wrapAnsi16m();
|
|
150
|
+
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
|
|
151
|
+
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
|
|
152
|
+
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
|
|
153
|
+
Object.defineProperties(styles, {
|
|
154
|
+
rgbToAnsi256: {
|
|
155
|
+
value(red, green, blue) {
|
|
156
|
+
if (red === green && green === blue) {
|
|
157
|
+
if (red < 8) {
|
|
158
|
+
return 16;
|
|
159
|
+
}
|
|
160
|
+
if (red > 248) {
|
|
161
|
+
return 231;
|
|
162
|
+
}
|
|
163
|
+
return Math.round((red - 8) / 247 * 24) + 232;
|
|
164
|
+
}
|
|
165
|
+
return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
|
|
166
|
+
},
|
|
167
|
+
enumerable: false
|
|
168
|
+
},
|
|
169
|
+
hexToRgb: {
|
|
170
|
+
value(hex) {
|
|
171
|
+
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
|
|
172
|
+
if (!matches) {
|
|
173
|
+
return [0, 0, 0];
|
|
174
|
+
}
|
|
175
|
+
let [colorString] = matches;
|
|
176
|
+
if (colorString.length === 3) {
|
|
177
|
+
colorString = [...colorString].map((character) => character + character).join("");
|
|
178
|
+
}
|
|
179
|
+
const integer = Number.parseInt(colorString, 16);
|
|
180
|
+
return [
|
|
181
|
+
/* eslint-disable no-bitwise */
|
|
182
|
+
integer >> 16 & 255,
|
|
183
|
+
integer >> 8 & 255,
|
|
184
|
+
integer & 255
|
|
185
|
+
/* eslint-enable no-bitwise */
|
|
186
|
+
];
|
|
187
|
+
},
|
|
188
|
+
enumerable: false
|
|
189
|
+
},
|
|
190
|
+
hexToAnsi256: {
|
|
191
|
+
value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
|
|
192
|
+
enumerable: false
|
|
193
|
+
},
|
|
194
|
+
ansi256ToAnsi: {
|
|
195
|
+
value(code) {
|
|
196
|
+
if (code < 8) {
|
|
197
|
+
return 30 + code;
|
|
198
|
+
}
|
|
199
|
+
if (code < 16) {
|
|
200
|
+
return 90 + (code - 8);
|
|
201
|
+
}
|
|
202
|
+
let red;
|
|
203
|
+
let green;
|
|
204
|
+
let blue;
|
|
205
|
+
if (code >= 232) {
|
|
206
|
+
red = ((code - 232) * 10 + 8) / 255;
|
|
207
|
+
green = red;
|
|
208
|
+
blue = red;
|
|
209
|
+
} else {
|
|
210
|
+
code -= 16;
|
|
211
|
+
const remainder = code % 36;
|
|
212
|
+
red = Math.floor(code / 36) / 5;
|
|
213
|
+
green = Math.floor(remainder / 6) / 5;
|
|
214
|
+
blue = remainder % 6 / 5;
|
|
215
|
+
}
|
|
216
|
+
const value = Math.max(red, green, blue) * 2;
|
|
217
|
+
if (value === 0) {
|
|
218
|
+
return 30;
|
|
219
|
+
}
|
|
220
|
+
let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
|
|
221
|
+
if (value === 2) {
|
|
222
|
+
result += 60;
|
|
223
|
+
}
|
|
224
|
+
return result;
|
|
225
|
+
},
|
|
226
|
+
enumerable: false
|
|
227
|
+
},
|
|
228
|
+
rgbToAnsi: {
|
|
229
|
+
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
|
|
230
|
+
enumerable: false
|
|
231
|
+
},
|
|
232
|
+
hexToAnsi: {
|
|
233
|
+
value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
|
|
234
|
+
enumerable: false
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
return styles;
|
|
238
|
+
}
|
|
239
|
+
var ansiStyles = assembleStyles();
|
|
240
|
+
var ansi_styles_default = ansiStyles;
|
|
241
|
+
|
|
242
|
+
// node_modules/chalk/source/vendor/supports-color/index.js
|
|
243
|
+
var import_node_process = __toESM(require("node:process"), 1);
|
|
244
|
+
var import_node_os = __toESM(require("node:os"), 1);
|
|
245
|
+
var import_node_tty = __toESM(require("node:tty"), 1);
|
|
246
|
+
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : import_node_process.default.argv) {
|
|
247
|
+
const prefix2 = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
|
|
248
|
+
const position = argv.indexOf(prefix2 + flag);
|
|
249
|
+
const terminatorPosition = argv.indexOf("--");
|
|
250
|
+
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
|
|
251
|
+
}
|
|
252
|
+
var { env } = import_node_process.default;
|
|
253
|
+
var flagForceColor;
|
|
254
|
+
if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
|
|
255
|
+
flagForceColor = 0;
|
|
256
|
+
} else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
|
|
257
|
+
flagForceColor = 1;
|
|
258
|
+
}
|
|
259
|
+
function envForceColor() {
|
|
260
|
+
if ("FORCE_COLOR" in env) {
|
|
261
|
+
if (env.FORCE_COLOR === "true") {
|
|
262
|
+
return 1;
|
|
263
|
+
}
|
|
264
|
+
if (env.FORCE_COLOR === "false") {
|
|
265
|
+
return 0;
|
|
266
|
+
}
|
|
267
|
+
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
function translateLevel(level) {
|
|
271
|
+
if (level === 0) {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
level,
|
|
276
|
+
hasBasic: true,
|
|
277
|
+
has256: level >= 2,
|
|
278
|
+
has16m: level >= 3
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
|
|
282
|
+
const noFlagForceColor = envForceColor();
|
|
283
|
+
if (noFlagForceColor !== void 0) {
|
|
284
|
+
flagForceColor = noFlagForceColor;
|
|
285
|
+
}
|
|
286
|
+
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
|
|
287
|
+
if (forceColor === 0) {
|
|
288
|
+
return 0;
|
|
289
|
+
}
|
|
290
|
+
if (sniffFlags) {
|
|
291
|
+
if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
|
|
292
|
+
return 3;
|
|
293
|
+
}
|
|
294
|
+
if (hasFlag("color=256")) {
|
|
295
|
+
return 2;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if ("TF_BUILD" in env && "AGENT_NAME" in env) {
|
|
299
|
+
return 1;
|
|
300
|
+
}
|
|
301
|
+
if (haveStream && !streamIsTTY && forceColor === void 0) {
|
|
302
|
+
return 0;
|
|
303
|
+
}
|
|
304
|
+
const min = forceColor || 0;
|
|
305
|
+
if (env.TERM === "dumb") {
|
|
306
|
+
return min;
|
|
307
|
+
}
|
|
308
|
+
if (import_node_process.default.platform === "win32") {
|
|
309
|
+
const osRelease = import_node_os.default.release().split(".");
|
|
310
|
+
if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
311
|
+
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
312
|
+
}
|
|
313
|
+
return 1;
|
|
314
|
+
}
|
|
315
|
+
if ("CI" in env) {
|
|
316
|
+
if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => key in env)) {
|
|
317
|
+
return 3;
|
|
318
|
+
}
|
|
319
|
+
if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
|
|
320
|
+
return 1;
|
|
321
|
+
}
|
|
322
|
+
return min;
|
|
323
|
+
}
|
|
324
|
+
if ("TEAMCITY_VERSION" in env) {
|
|
325
|
+
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
|
|
326
|
+
}
|
|
327
|
+
if (env.COLORTERM === "truecolor") {
|
|
328
|
+
return 3;
|
|
329
|
+
}
|
|
330
|
+
if (env.TERM === "xterm-kitty") {
|
|
331
|
+
return 3;
|
|
332
|
+
}
|
|
333
|
+
if (env.TERM === "xterm-ghostty") {
|
|
334
|
+
return 3;
|
|
335
|
+
}
|
|
336
|
+
if (env.TERM === "wezterm") {
|
|
337
|
+
return 3;
|
|
338
|
+
}
|
|
339
|
+
if ("TERM_PROGRAM" in env) {
|
|
340
|
+
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
|
|
341
|
+
switch (env.TERM_PROGRAM) {
|
|
342
|
+
case "iTerm.app": {
|
|
343
|
+
return version >= 3 ? 3 : 2;
|
|
344
|
+
}
|
|
345
|
+
case "Apple_Terminal": {
|
|
346
|
+
return 2;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (/-256(color)?$/i.test(env.TERM)) {
|
|
351
|
+
return 2;
|
|
352
|
+
}
|
|
353
|
+
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
|
|
354
|
+
return 1;
|
|
355
|
+
}
|
|
356
|
+
if ("COLORTERM" in env) {
|
|
357
|
+
return 1;
|
|
358
|
+
}
|
|
359
|
+
return min;
|
|
360
|
+
}
|
|
361
|
+
function createSupportsColor(stream, options = {}) {
|
|
362
|
+
const level = _supportsColor(stream, {
|
|
363
|
+
streamIsTTY: stream && stream.isTTY,
|
|
364
|
+
...options
|
|
365
|
+
});
|
|
366
|
+
return translateLevel(level);
|
|
367
|
+
}
|
|
368
|
+
var supportsColor = {
|
|
369
|
+
stdout: createSupportsColor({ isTTY: import_node_tty.default.isatty(1) }),
|
|
370
|
+
stderr: createSupportsColor({ isTTY: import_node_tty.default.isatty(2) })
|
|
371
|
+
};
|
|
372
|
+
var supports_color_default = supportsColor;
|
|
373
|
+
|
|
374
|
+
// node_modules/chalk/source/utilities.js
|
|
375
|
+
function stringReplaceAll(string, substring, replacer) {
|
|
376
|
+
let index = string.indexOf(substring);
|
|
377
|
+
if (index === -1) {
|
|
378
|
+
return string;
|
|
379
|
+
}
|
|
380
|
+
const substringLength = substring.length;
|
|
381
|
+
let endIndex = 0;
|
|
382
|
+
let returnValue = "";
|
|
383
|
+
do {
|
|
384
|
+
returnValue += string.slice(endIndex, index) + substring + replacer;
|
|
385
|
+
endIndex = index + substringLength;
|
|
386
|
+
index = string.indexOf(substring, endIndex);
|
|
387
|
+
} while (index !== -1);
|
|
388
|
+
returnValue += string.slice(endIndex);
|
|
389
|
+
return returnValue;
|
|
390
|
+
}
|
|
391
|
+
function stringEncaseCRLFWithFirstIndex(string, prefix2, postfix, index) {
|
|
392
|
+
let endIndex = 0;
|
|
393
|
+
let returnValue = "";
|
|
394
|
+
do {
|
|
395
|
+
const gotCR = string[index - 1] === "\r";
|
|
396
|
+
returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix2 + (gotCR ? "\r\n" : "\n") + postfix;
|
|
397
|
+
endIndex = index + 1;
|
|
398
|
+
index = string.indexOf("\n", endIndex);
|
|
399
|
+
} while (index !== -1);
|
|
400
|
+
returnValue += string.slice(endIndex);
|
|
401
|
+
return returnValue;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// node_modules/chalk/source/index.js
|
|
405
|
+
var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
|
|
406
|
+
var GENERATOR = Symbol("GENERATOR");
|
|
407
|
+
var STYLER = Symbol("STYLER");
|
|
408
|
+
var IS_EMPTY = Symbol("IS_EMPTY");
|
|
409
|
+
var levelMapping = [
|
|
410
|
+
"ansi",
|
|
411
|
+
"ansi",
|
|
412
|
+
"ansi256",
|
|
413
|
+
"ansi16m"
|
|
414
|
+
];
|
|
415
|
+
var styles2 = /* @__PURE__ */ Object.create(null);
|
|
416
|
+
var applyOptions = (object, options = {}) => {
|
|
417
|
+
if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
|
|
418
|
+
throw new Error("The `level` option should be an integer from 0 to 3");
|
|
419
|
+
}
|
|
420
|
+
const colorLevel = stdoutColor ? stdoutColor.level : 0;
|
|
421
|
+
object.level = options.level === void 0 ? colorLevel : options.level;
|
|
422
|
+
};
|
|
423
|
+
var chalkFactory = (options) => {
|
|
424
|
+
const chalk2 = (...strings) => strings.join(" ");
|
|
425
|
+
applyOptions(chalk2, options);
|
|
426
|
+
Object.setPrototypeOf(chalk2, createChalk.prototype);
|
|
427
|
+
return chalk2;
|
|
428
|
+
};
|
|
429
|
+
function createChalk(options) {
|
|
430
|
+
return chalkFactory(options);
|
|
431
|
+
}
|
|
432
|
+
Object.setPrototypeOf(createChalk.prototype, Function.prototype);
|
|
433
|
+
for (const [styleName, style] of Object.entries(ansi_styles_default)) {
|
|
434
|
+
styles2[styleName] = {
|
|
435
|
+
get() {
|
|
436
|
+
const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
|
|
437
|
+
Object.defineProperty(this, styleName, { value: builder });
|
|
438
|
+
return builder;
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
styles2.visible = {
|
|
443
|
+
get() {
|
|
444
|
+
const builder = createBuilder(this, this[STYLER], true);
|
|
445
|
+
Object.defineProperty(this, "visible", { value: builder });
|
|
446
|
+
return builder;
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
var getModelAnsi = (model, level, type, ...arguments_) => {
|
|
450
|
+
if (model === "rgb") {
|
|
451
|
+
if (level === "ansi16m") {
|
|
452
|
+
return ansi_styles_default[type].ansi16m(...arguments_);
|
|
453
|
+
}
|
|
454
|
+
if (level === "ansi256") {
|
|
455
|
+
return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
|
|
456
|
+
}
|
|
457
|
+
return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
|
|
458
|
+
}
|
|
459
|
+
if (model === "hex") {
|
|
460
|
+
return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
|
|
461
|
+
}
|
|
462
|
+
return ansi_styles_default[type][model](...arguments_);
|
|
463
|
+
};
|
|
464
|
+
var usedModels = ["rgb", "hex", "ansi256"];
|
|
465
|
+
for (const model of usedModels) {
|
|
466
|
+
styles2[model] = {
|
|
467
|
+
get() {
|
|
468
|
+
const { level } = this;
|
|
469
|
+
return function(...arguments_) {
|
|
470
|
+
const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
|
|
471
|
+
return createBuilder(this, styler, this[IS_EMPTY]);
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
|
|
476
|
+
styles2[bgModel] = {
|
|
477
|
+
get() {
|
|
478
|
+
const { level } = this;
|
|
479
|
+
return function(...arguments_) {
|
|
480
|
+
const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
|
|
481
|
+
return createBuilder(this, styler, this[IS_EMPTY]);
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
var proto = Object.defineProperties(() => {
|
|
487
|
+
}, {
|
|
488
|
+
...styles2,
|
|
489
|
+
level: {
|
|
490
|
+
enumerable: true,
|
|
491
|
+
get() {
|
|
492
|
+
return this[GENERATOR].level;
|
|
493
|
+
},
|
|
494
|
+
set(level) {
|
|
495
|
+
this[GENERATOR].level = level;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
var createStyler = (open, close, parent) => {
|
|
500
|
+
let openAll;
|
|
501
|
+
let closeAll;
|
|
502
|
+
if (parent === void 0) {
|
|
503
|
+
openAll = open;
|
|
504
|
+
closeAll = close;
|
|
505
|
+
} else {
|
|
506
|
+
openAll = parent.openAll + open;
|
|
507
|
+
closeAll = close + parent.closeAll;
|
|
508
|
+
}
|
|
509
|
+
return {
|
|
510
|
+
open,
|
|
511
|
+
close,
|
|
512
|
+
openAll,
|
|
513
|
+
closeAll,
|
|
514
|
+
parent
|
|
515
|
+
};
|
|
516
|
+
};
|
|
517
|
+
var createBuilder = (self, _styler, _isEmpty) => {
|
|
518
|
+
const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
|
|
519
|
+
Object.setPrototypeOf(builder, proto);
|
|
520
|
+
builder[GENERATOR] = self;
|
|
521
|
+
builder[STYLER] = _styler;
|
|
522
|
+
builder[IS_EMPTY] = _isEmpty;
|
|
523
|
+
return builder;
|
|
524
|
+
};
|
|
525
|
+
var applyStyle = (self, string) => {
|
|
526
|
+
if (self.level <= 0 || !string) {
|
|
527
|
+
return self[IS_EMPTY] ? "" : string;
|
|
528
|
+
}
|
|
529
|
+
let styler = self[STYLER];
|
|
530
|
+
if (styler === void 0) {
|
|
531
|
+
return string;
|
|
532
|
+
}
|
|
533
|
+
const { openAll, closeAll } = styler;
|
|
534
|
+
if (string.includes("\x1B")) {
|
|
535
|
+
while (styler !== void 0) {
|
|
536
|
+
string = stringReplaceAll(string, styler.close, styler.open);
|
|
537
|
+
styler = styler.parent;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
const lfIndex = string.indexOf("\n");
|
|
541
|
+
if (lfIndex !== -1) {
|
|
542
|
+
string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
|
|
543
|
+
}
|
|
544
|
+
return openAll + string + closeAll;
|
|
545
|
+
};
|
|
546
|
+
Object.defineProperties(createChalk.prototype, styles2);
|
|
547
|
+
var chalk = createChalk();
|
|
548
|
+
var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
549
|
+
var source_default = chalk;
|
|
550
|
+
|
|
551
|
+
// src/tunnel.ts
|
|
552
|
+
var import_node_child_process = require("node:child_process");
|
|
553
|
+
function startTunnel(tunnelProcess2, options) {
|
|
554
|
+
const tunnelDomain = `${options.subdomain || crypto.randomUUID()}.browsermationtunnel.com`;
|
|
555
|
+
tunnelProcess2 = (0, import_node_child_process.spawn)("ssh", [
|
|
556
|
+
"-o",
|
|
557
|
+
"StrictHostKeyChecking=no",
|
|
558
|
+
"-o",
|
|
559
|
+
"UserKnownHostsFile=/dev/null",
|
|
560
|
+
"-R",
|
|
561
|
+
`:80:localhost:${options.tunnel}`,
|
|
562
|
+
"v0@browsermationtunnel.com",
|
|
563
|
+
"-p",
|
|
564
|
+
"2200",
|
|
565
|
+
"http",
|
|
566
|
+
"--proxy_name",
|
|
567
|
+
tunnelDomain,
|
|
568
|
+
"--custom_domain",
|
|
569
|
+
tunnelDomain,
|
|
570
|
+
"--token",
|
|
571
|
+
process.env.TUNNEL_TOKEN || ""
|
|
572
|
+
]);
|
|
573
|
+
process.on("SIGINT", function() {
|
|
574
|
+
console.log("\nGracefully shutting down from SIGINT (Ctrl+C)");
|
|
575
|
+
if (tunnelProcess2) {
|
|
576
|
+
console.log("Killing proxy process...");
|
|
577
|
+
tunnelProcess2.kill();
|
|
578
|
+
}
|
|
579
|
+
process.exit();
|
|
580
|
+
});
|
|
581
|
+
tunnelProcess2?.stdout?.on("data", (data) => {
|
|
582
|
+
console.log(`stdout: ${data}`);
|
|
583
|
+
});
|
|
584
|
+
tunnelProcess2?.stderr?.on("data", (data) => {
|
|
585
|
+
console.error(`stderr: ${data}`);
|
|
586
|
+
});
|
|
587
|
+
const tunnelUrl = `https://${tunnelDomain}`;
|
|
588
|
+
console.log(
|
|
589
|
+
source_default.green.bold(
|
|
590
|
+
`\u2705 Tunnel setup complete. You can now access your project at: ${tunnelUrl}`
|
|
591
|
+
)
|
|
592
|
+
);
|
|
593
|
+
return { tunnelProcess: tunnelProcess2, tunnelUrl };
|
|
594
|
+
}
|
|
595
|
+
|
|
56
596
|
// src/defineConfig.ts
|
|
57
597
|
async function fetchEndpoint() {
|
|
58
598
|
invariant(
|
|
@@ -76,8 +616,17 @@ async function fetchEndpoint() {
|
|
|
76
616
|
});
|
|
77
617
|
});
|
|
78
618
|
}
|
|
619
|
+
var tunnelProcess = null;
|
|
620
|
+
process.on("exit", () => {
|
|
621
|
+
tunnelProcess?.kill();
|
|
622
|
+
});
|
|
79
623
|
async function defineConfig(config) {
|
|
80
624
|
const endpointUrl = await fetchEndpoint();
|
|
625
|
+
if (config.webServer && (Array.isArray(config.webServer) ? config.webServer.some((server) => server.port) : config.webServer.port)) {
|
|
626
|
+
await startTunnel(tunnelProcess, {
|
|
627
|
+
tunnel: Array.isArray(config.webServer) ? config.webServer.find((server) => server.port)?.port : config.webServer.port
|
|
628
|
+
});
|
|
629
|
+
}
|
|
81
630
|
return {
|
|
82
631
|
...config,
|
|
83
632
|
use: {
|
|
@@ -104,6 +653,7 @@ async function fetchEndpoint2() {
|
|
|
104
653
|
process.env.SERVER_URL,
|
|
105
654
|
"SERVER_URL environment variable is not set"
|
|
106
655
|
);
|
|
656
|
+
invariant(process.env.API_TOKEN, "API_TOKEN environment variable is not set");
|
|
107
657
|
return new Promise((resolve, reject) => {
|
|
108
658
|
import_node_https2.default.get(process.env.SERVER_URL, (res) => {
|
|
109
659
|
res.on("data", (chunk) => {
|
|
@@ -120,8 +670,18 @@ async function fetchEndpoint2() {
|
|
|
120
670
|
});
|
|
121
671
|
});
|
|
122
672
|
}
|
|
673
|
+
function checkIfBrowsermationTestReporterIsUsed() {
|
|
674
|
+
if (!test.info().config.reporter.some(
|
|
675
|
+
(reporter) => typeof reporter === "string" ? reporter === "@browsermation/test/reporter" : reporter[0] === "@browsermation/test/reporter"
|
|
676
|
+
)) {
|
|
677
|
+
throw new Error(
|
|
678
|
+
"The @browsermation/test/reporter reporter must be configured to use the page fixture."
|
|
679
|
+
);
|
|
680
|
+
}
|
|
681
|
+
}
|
|
123
682
|
var test = test_exports.test.extend({
|
|
124
683
|
page: async ({ page }, use) => {
|
|
684
|
+
checkIfBrowsermationTestReporterIsUsed();
|
|
125
685
|
const endpointUrl = await fetchEndpoint2();
|
|
126
686
|
let isConnected = false;
|
|
127
687
|
while (!isConnected) {
|
|
@@ -146,6 +706,7 @@ var test = test_exports.test.extend({
|
|
|
146
706
|
await browser.close();
|
|
147
707
|
},
|
|
148
708
|
browser: async ({}, use) => {
|
|
709
|
+
checkIfBrowsermationTestReporterIsUsed();
|
|
149
710
|
const endpointUrl = await fetchEndpoint2();
|
|
150
711
|
let isConnected = false;
|
|
151
712
|
while (!isConnected) {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { FullConfig, FullResult, Reporter, Suite, TestCase, TestError, TestResult } from '@playwright/test/reporter';
|
|
2
2
|
export default class BrowsermationReporter implements Reporter {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
sendData(data: Record<string, any>): Promise<void>;
|
|
4
|
+
onBegin(_config: FullConfig, suite: Suite): Promise<void>;
|
|
5
|
+
onEnd(result: FullResult): Promise<void>;
|
|
6
|
+
onTestBegin(test: TestCase): Promise<void>;
|
|
7
|
+
onTestEnd(test: TestCase, result: TestResult): Promise<void>;
|
|
8
|
+
onError(error: TestError): Promise<void>;
|
|
8
9
|
onExit(): Promise<void>;
|
|
9
10
|
}
|
package/dist/reporter.js
CHANGED
|
@@ -32,7 +32,20 @@ var regex = (({ onlyFirst = false } = {}) => {
|
|
|
32
32
|
})();
|
|
33
33
|
var stripAnsi = (str) => str.replace(regex, "");
|
|
34
34
|
var BrowsermationReporter = class {
|
|
35
|
-
|
|
35
|
+
async sendData(data) {
|
|
36
|
+
await fetch(
|
|
37
|
+
process.env.SERVER_URL || "https://browsermation.com/api/v1/playwright/reporting",
|
|
38
|
+
{
|
|
39
|
+
method: "POST",
|
|
40
|
+
headers: {
|
|
41
|
+
"Content-Type": "application/json",
|
|
42
|
+
Authorization: `Bearer ${process.env.API_TOKEN}`
|
|
43
|
+
},
|
|
44
|
+
body: JSON.stringify(data)
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
async onBegin(_config, suite) {
|
|
36
49
|
const data = {
|
|
37
50
|
type: "begin",
|
|
38
51
|
title: suite.title,
|
|
@@ -41,8 +54,9 @@ var BrowsermationReporter = class {
|
|
|
41
54
|
};
|
|
42
55
|
console.log(`${JSON.stringify(data)}
|
|
43
56
|
`);
|
|
57
|
+
await this.sendData(data);
|
|
44
58
|
}
|
|
45
|
-
onEnd(result) {
|
|
59
|
+
async onEnd(result) {
|
|
46
60
|
const data = {
|
|
47
61
|
type: "end",
|
|
48
62
|
startTime: result.startTime,
|
|
@@ -52,8 +66,9 @@ var BrowsermationReporter = class {
|
|
|
52
66
|
};
|
|
53
67
|
console.log(`${JSON.stringify(data)}
|
|
54
68
|
`);
|
|
69
|
+
await this.sendData(data);
|
|
55
70
|
}
|
|
56
|
-
onTestBegin(test) {
|
|
71
|
+
async onTestBegin(test) {
|
|
57
72
|
const data = {
|
|
58
73
|
id: test.id,
|
|
59
74
|
type: "test-start",
|
|
@@ -63,8 +78,9 @@ var BrowsermationReporter = class {
|
|
|
63
78
|
};
|
|
64
79
|
console.log(`${JSON.stringify(data)}
|
|
65
80
|
`);
|
|
81
|
+
await this.sendData(data);
|
|
66
82
|
}
|
|
67
|
-
onTestEnd(test, result) {
|
|
83
|
+
async onTestEnd(test, result) {
|
|
68
84
|
const data = {
|
|
69
85
|
id: test.id,
|
|
70
86
|
type: "test-end",
|
|
@@ -77,8 +93,9 @@ var BrowsermationReporter = class {
|
|
|
77
93
|
};
|
|
78
94
|
console.log(`${JSON.stringify(data)}
|
|
79
95
|
`);
|
|
96
|
+
await this.sendData(data);
|
|
80
97
|
}
|
|
81
|
-
onError(error) {
|
|
98
|
+
async onError(error) {
|
|
82
99
|
const data = {
|
|
83
100
|
type: "error",
|
|
84
101
|
message: error.message,
|
|
@@ -87,14 +104,15 @@ var BrowsermationReporter = class {
|
|
|
87
104
|
};
|
|
88
105
|
console.error(`${JSON.stringify(data)}
|
|
89
106
|
`);
|
|
107
|
+
await this.sendData(data);
|
|
90
108
|
}
|
|
91
|
-
onExit() {
|
|
109
|
+
async onExit() {
|
|
92
110
|
const data = {
|
|
93
111
|
type: "exit",
|
|
94
112
|
timestamp: Date.now()
|
|
95
113
|
};
|
|
96
114
|
console.log(`${JSON.stringify(data)}
|
|
97
115
|
`);
|
|
98
|
-
|
|
116
|
+
await this.sendData(data);
|
|
99
117
|
}
|
|
100
118
|
};
|
package/dist/tunnel.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
-
export declare function startTunnel(tunnelProcess: ReturnType<typeof spawn> | null, options: any):
|
|
2
|
+
export declare function startTunnel(tunnelProcess: ReturnType<typeof spawn> | null, options: any): {
|
|
3
3
|
tunnelProcess: import("child_process").ChildProcess;
|
|
4
4
|
tunnelUrl: string;
|
|
5
|
-
}
|
|
5
|
+
};
|