@playwright/test 1.35.0-alpha-jun-2-2023 → 1.35.0-alpha-jun-4-2023
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/lib/common/config.js +6 -0
- package/lib/common/configLoader.js +3 -4
- package/lib/common/esmLoaderHost.js +2 -2
- package/lib/common/ipc.js +1 -4
- package/lib/index.js +9 -5
- package/lib/runner/dispatcher.js +15 -6
- package/lib/runner/loaderHost.js +0 -4
- package/lib/runner/tasks.js +7 -8
- package/lib/transform/esmLoader.js +3 -3
- package/lib/transform/transform.js +20 -10
- package/lib/worker/testInfo.js +25 -3
- package/lib/worker/workerMain.js +2 -11
- package/package.json +3 -3
- package/types/test.d.ts +25 -0
package/lib/common/config.js
CHANGED
|
@@ -10,6 +10,7 @@ var _fs = _interopRequireDefault(require("fs"));
|
|
|
10
10
|
var _path = _interopRequireDefault(require("path"));
|
|
11
11
|
var _os = _interopRequireDefault(require("os"));
|
|
12
12
|
var _util = require("../util");
|
|
13
|
+
var _transform = require("../transform/transform");
|
|
13
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
15
|
/**
|
|
15
16
|
* Copyright Microsoft Corporation. All rights reserved.
|
|
@@ -34,6 +35,7 @@ class FullConfigInternal {
|
|
|
34
35
|
return config[configInternalSymbol];
|
|
35
36
|
}
|
|
36
37
|
constructor(configDir, configFile, config, configCLIOverrides) {
|
|
38
|
+
var _build, _config$build;
|
|
37
39
|
this.config = void 0;
|
|
38
40
|
this.globalOutputDir = void 0;
|
|
39
41
|
this.configDir = void 0;
|
|
@@ -118,6 +120,10 @@ class FullConfigInternal {
|
|
|
118
120
|
this.projects = projectConfigs.map(p => new FullProjectInternal(configDir, config, this, p, this.configCLIOverrides, throwawayArtifactsPath));
|
|
119
121
|
resolveProjectDependencies(this.projects);
|
|
120
122
|
this._assignUniqueProjectIds(this.projects);
|
|
123
|
+
(0, _transform.setTransformConfig)({
|
|
124
|
+
babelPlugins: ((_build = config.build) === null || _build === void 0 ? void 0 : _build.babelPlugins) || [],
|
|
125
|
+
external: ((_config$build = config.build) === null || _config$build === void 0 ? void 0 : _config$build.external) || []
|
|
126
|
+
});
|
|
121
127
|
this.config.projects = this.projects.map(p => p.project);
|
|
122
128
|
}
|
|
123
129
|
_assignUniqueProjectIds(projects) {
|
|
@@ -45,12 +45,11 @@ class ConfigLoader {
|
|
|
45
45
|
this._configCLIOverrides = configCLIOverrides || {};
|
|
46
46
|
}
|
|
47
47
|
static async deserialize(data) {
|
|
48
|
-
(0, _transform.setBabelPlugins)(data.babelTransformPlugins);
|
|
49
48
|
(0, _compilationCache.addToCompilationCache)(data.compilationCache);
|
|
50
|
-
await (0, _esmLoaderHost.initializeEsmLoader)();
|
|
51
49
|
const loader = new ConfigLoader(data.configCLIOverrides);
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
const config = data.configFile ? await loader.loadConfigFile(data.configFile) : await loader.loadEmptyConfig(data.configDir);
|
|
51
|
+
await (0, _esmLoaderHost.initializeEsmLoader)();
|
|
52
|
+
return config;
|
|
54
53
|
}
|
|
55
54
|
async loadConfigFile(file, ignoreProjectDependencies = false) {
|
|
56
55
|
if (this._fullConfig) throw new Error('Cannot load two config files');
|
|
@@ -47,8 +47,8 @@ async function incorporateCompilationCache() {
|
|
|
47
47
|
}
|
|
48
48
|
async function initializeEsmLoader() {
|
|
49
49
|
if (!loaderChannel) return;
|
|
50
|
-
await loaderChannel.send('
|
|
51
|
-
|
|
50
|
+
await loaderChannel.send('setTransformConfig', {
|
|
51
|
+
config: (0, _transform.transformConfig)()
|
|
52
52
|
});
|
|
53
53
|
await loaderChannel.send('addToCompilationCache', {
|
|
54
54
|
cache: (0, _compilationCache.serializeCompilationCache)()
|
package/lib/common/ipc.js
CHANGED
|
@@ -22,14 +22,11 @@ var _compilationCache = require("../transform/compilationCache");
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
function serializeConfig(config) {
|
|
25
|
-
const babelTransformPlugins = [];
|
|
26
|
-
for (const plugin of config.plugins) babelTransformPlugins.push(...(plugin.babelPlugins || []));
|
|
27
25
|
const result = {
|
|
28
26
|
configFile: config.config.configFile,
|
|
29
27
|
configDir: config.configDir,
|
|
30
28
|
configCLIOverrides: config.configCLIOverrides,
|
|
31
|
-
compilationCache: (0, _compilationCache.serializeCompilationCache)()
|
|
32
|
-
babelTransformPlugins
|
|
29
|
+
compilationCache: (0, _compilationCache.serializeCompilationCache)()
|
|
33
30
|
};
|
|
34
31
|
return result;
|
|
35
32
|
}
|
package/lib/index.js
CHANGED
|
@@ -417,6 +417,7 @@ const playwrightFixtures = {
|
|
|
417
417
|
..._combinedContextOptions
|
|
418
418
|
};
|
|
419
419
|
playwright.request._defaultContextOptions.tracesDir = path.join(_artifactsDir(), 'traces');
|
|
420
|
+
playwright.request._defaultContextOptions.timeout = actionTimeout || 0;
|
|
420
421
|
await use();
|
|
421
422
|
playwright.request._defaultContextOptions = undefined;
|
|
422
423
|
for (const browserType of [playwright.chromium, playwright.firefox, playwright.webkit]) {
|
|
@@ -778,6 +779,12 @@ class ArtifactsRecorder {
|
|
|
778
779
|
await this._stopTracing(tracing, true);
|
|
779
780
|
})));
|
|
780
781
|
|
|
782
|
+
// Either remove or attach temporary screenshots for contexts closed before
|
|
783
|
+
// collecting the test trace.
|
|
784
|
+
await Promise.all(this._temporaryScreenshots.map(async file => {
|
|
785
|
+
if (captureScreenshots) await fs.promises.rename(file, this._addScreenshotAttachment()).catch(() => {});else await fs.promises.unlink(file).catch(() => {});
|
|
786
|
+
}));
|
|
787
|
+
|
|
781
788
|
// Collect test trace.
|
|
782
789
|
if (this._preserveTrace()) {
|
|
783
790
|
const events = this._testInfo._traceEvents;
|
|
@@ -793,8 +800,8 @@ class ArtifactsRecorder {
|
|
|
793
800
|
}
|
|
794
801
|
}
|
|
795
802
|
|
|
796
|
-
// Either remove or attach temporary traces
|
|
797
|
-
//
|
|
803
|
+
// Either remove or attach temporary traces for contexts closed before the
|
|
804
|
+
// test has finished.
|
|
798
805
|
if (this._preserveTrace() && this._temporaryTraceFiles.length) {
|
|
799
806
|
const tracePath = this._testInfo.outputPath(`trace.zip`);
|
|
800
807
|
// This could be: beforeHooks, or beforeHooks + test, etc.
|
|
@@ -811,9 +818,6 @@ class ArtifactsRecorder {
|
|
|
811
818
|
contentType: 'application/zip'
|
|
812
819
|
});
|
|
813
820
|
}
|
|
814
|
-
await Promise.all(this._temporaryScreenshots.map(async file => {
|
|
815
|
-
if (captureScreenshots) await fs.promises.rename(file, this._addScreenshotAttachment()).catch(() => {});else await fs.promises.unlink(file).catch(() => {});
|
|
816
|
-
}));
|
|
817
821
|
}
|
|
818
822
|
_addScreenshotAttachment() {
|
|
819
823
|
const testFailed = this._testInfo.status !== this._testInfo.expectedStatus;
|
package/lib/runner/dispatcher.js
CHANGED
|
@@ -180,6 +180,7 @@ class Dispatcher {
|
|
|
180
180
|
worker.removeListener('testEnd', onTestEnd);
|
|
181
181
|
worker.removeListener('stepBegin', onStepBegin);
|
|
182
182
|
worker.removeListener('stepEnd', onStepEnd);
|
|
183
|
+
worker.removeListener('attach', onAttach);
|
|
183
184
|
worker.removeListener('done', onDone);
|
|
184
185
|
worker.removeListener('exit', onExit);
|
|
185
186
|
doneCallback();
|
|
@@ -220,12 +221,6 @@ class Dispatcher {
|
|
|
220
221
|
result.duration = params.duration;
|
|
221
222
|
result.errors = params.errors;
|
|
222
223
|
result.error = result.errors[0];
|
|
223
|
-
result.attachments = params.attachments.map(a => ({
|
|
224
|
-
name: a.name,
|
|
225
|
-
path: a.path,
|
|
226
|
-
contentType: a.contentType,
|
|
227
|
-
body: a.body !== undefined ? Buffer.from(a.body, 'base64') : undefined
|
|
228
|
-
}));
|
|
229
224
|
result.status = params.status;
|
|
230
225
|
test.expectedStatus = params.expectedStatus;
|
|
231
226
|
test.annotations = params.annotations;
|
|
@@ -288,6 +283,20 @@ class Dispatcher {
|
|
|
288
283
|
this._reporter.onStepEnd(data.test, result, step);
|
|
289
284
|
};
|
|
290
285
|
worker.on('stepEnd', onStepEnd);
|
|
286
|
+
const onAttach = params => {
|
|
287
|
+
const data = this._testById.get(params.testId);
|
|
288
|
+
const {
|
|
289
|
+
result
|
|
290
|
+
} = data.resultByWorkerIndex.get(worker.workerIndex);
|
|
291
|
+
const attachment = {
|
|
292
|
+
name: params.name,
|
|
293
|
+
path: params.path,
|
|
294
|
+
contentType: params.contentType,
|
|
295
|
+
body: params.body !== undefined ? Buffer.from(params.body, 'base64') : undefined
|
|
296
|
+
};
|
|
297
|
+
result.attachments.push(attachment);
|
|
298
|
+
};
|
|
299
|
+
worker.on('attach', onAttach);
|
|
291
300
|
const onDone = params => {
|
|
292
301
|
this._queuedOrRunningHashCount.set(worker.hash(), this._queuedOrRunningHashCount.get(worker.hash()) - 1);
|
|
293
302
|
let remaining = [...remainingByTestId.values()];
|
package/lib/runner/loaderHost.js
CHANGED
|
@@ -10,7 +10,6 @@ var _test = require("../common/test");
|
|
|
10
10
|
var _testLoader = require("../common/testLoader");
|
|
11
11
|
var _poolBuilder = require("../common/poolBuilder");
|
|
12
12
|
var _compilationCache = require("../transform/compilationCache");
|
|
13
|
-
var _transform = require("../transform/transform");
|
|
14
13
|
var _esmLoaderHost = require("../common/esmLoaderHost");
|
|
15
14
|
/**
|
|
16
15
|
* Copyright Microsoft Corporation. All rights reserved.
|
|
@@ -36,9 +35,6 @@ class InProcessLoaderHost {
|
|
|
36
35
|
this._poolBuilder = _poolBuilder.PoolBuilder.createForLoader();
|
|
37
36
|
}
|
|
38
37
|
async start() {
|
|
39
|
-
const babelTransformPlugins = [];
|
|
40
|
-
for (const plugin of this._config.plugins) babelTransformPlugins.push(...(plugin.babelPlugins || []));
|
|
41
|
-
(0, _transform.setBabelPlugins)(babelTransformPlugins);
|
|
42
38
|
await (0, _esmLoaderHost.initializeEsmLoader)();
|
|
43
39
|
}
|
|
44
40
|
async loadTestFile(file, testErrors) {
|
package/lib/runner/tasks.js
CHANGED
|
@@ -115,13 +115,12 @@ function createPluginSetupTask(plugin) {
|
|
|
115
115
|
config,
|
|
116
116
|
reporter
|
|
117
117
|
}) => {
|
|
118
|
-
var _plugin$instance, _plugin$instance$setu
|
|
118
|
+
var _plugin$instance, _plugin$instance$setu;
|
|
119
119
|
if (typeof plugin.factory === 'function') plugin.instance = await plugin.factory();else plugin.instance = plugin.factory;
|
|
120
120
|
await ((_plugin$instance = plugin.instance) === null || _plugin$instance === void 0 ? void 0 : (_plugin$instance$setu = _plugin$instance.setup) === null || _plugin$instance$setu === void 0 ? void 0 : _plugin$instance$setu.call(_plugin$instance, config.config, config.configDir, reporter));
|
|
121
|
-
plugin.babelPlugins = (await ((_plugin$instance2 = plugin.instance) === null || _plugin$instance2 === void 0 ? void 0 : (_plugin$instance2$bab = _plugin$instance2.babelPlugins) === null || _plugin$instance2$bab === void 0 ? void 0 : _plugin$instance2$bab.call(_plugin$instance2))) || [];
|
|
122
121
|
return () => {
|
|
123
|
-
var _plugin$
|
|
124
|
-
return (_plugin$
|
|
122
|
+
var _plugin$instance2, _plugin$instance2$tea;
|
|
123
|
+
return (_plugin$instance2 = plugin.instance) === null || _plugin$instance2 === void 0 ? void 0 : (_plugin$instance2$tea = _plugin$instance2.teardown) === null || _plugin$instance2$tea === void 0 ? void 0 : _plugin$instance2$tea.call(_plugin$instance2);
|
|
125
124
|
};
|
|
126
125
|
};
|
|
127
126
|
}
|
|
@@ -129,11 +128,11 @@ function createPluginBeginTask(plugin) {
|
|
|
129
128
|
return async ({
|
|
130
129
|
rootSuite
|
|
131
130
|
}) => {
|
|
132
|
-
var _plugin$
|
|
133
|
-
await ((_plugin$
|
|
131
|
+
var _plugin$instance3, _plugin$instance3$beg;
|
|
132
|
+
await ((_plugin$instance3 = plugin.instance) === null || _plugin$instance3 === void 0 ? void 0 : (_plugin$instance3$beg = _plugin$instance3.begin) === null || _plugin$instance3$beg === void 0 ? void 0 : _plugin$instance3$beg.call(_plugin$instance3, rootSuite));
|
|
134
133
|
return () => {
|
|
135
|
-
var _plugin$
|
|
136
|
-
return (_plugin$
|
|
134
|
+
var _plugin$instance4, _plugin$instance4$end;
|
|
135
|
+
return (_plugin$instance4 = plugin.instance) === null || _plugin$instance4 === void 0 ? void 0 : (_plugin$instance4$end = _plugin$instance4.end) === null || _plugin$instance4$end === void 0 ? void 0 : _plugin$instance4$end.call(_plugin$instance4);
|
|
137
136
|
};
|
|
138
137
|
};
|
|
139
138
|
}
|
|
@@ -48,7 +48,7 @@ async function load(moduleUrl, context, defaultLoad) {
|
|
|
48
48
|
if (!moduleUrl.startsWith('file://')) return defaultLoad(moduleUrl, context, defaultLoad);
|
|
49
49
|
const filename = _url.default.fileURLToPath(moduleUrl);
|
|
50
50
|
// Bail for node_modules.
|
|
51
|
-
if ((0,
|
|
51
|
+
if (!(0, _transform.shouldTransform)(filename)) return defaultLoad(moduleUrl, context, defaultLoad);
|
|
52
52
|
const code = _fs.default.readFileSync(filename, 'utf-8');
|
|
53
53
|
const source = (0, _transform.transformHook)(code, filename, moduleUrl);
|
|
54
54
|
|
|
@@ -68,8 +68,8 @@ async function load(moduleUrl, context, defaultLoad) {
|
|
|
68
68
|
let transport;
|
|
69
69
|
function globalPreload(context) {
|
|
70
70
|
transport = new _portTransport.PortTransport(context.port, async (method, params) => {
|
|
71
|
-
if (method === '
|
|
72
|
-
(0, _transform.
|
|
71
|
+
if (method === 'setTransformConfig') {
|
|
72
|
+
(0, _transform.setTransformConfig)(params.config);
|
|
73
73
|
return;
|
|
74
74
|
}
|
|
75
75
|
if (method === 'addToCompilationCache') {
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.getBabelPlugins = getBabelPlugins;
|
|
7
6
|
exports.requireOrImport = requireOrImport;
|
|
8
7
|
exports.resolveHook = resolveHook;
|
|
9
|
-
exports.
|
|
8
|
+
exports.setTransformConfig = setTransformConfig;
|
|
9
|
+
exports.shouldTransform = shouldTransform;
|
|
10
|
+
exports.transformConfig = transformConfig;
|
|
10
11
|
exports.transformHook = transformHook;
|
|
11
12
|
exports.wrapFunctionWithLocation = wrapFunctionWithLocation;
|
|
12
13
|
var _crypto = _interopRequireDefault(require("crypto"));
|
|
@@ -36,12 +37,17 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
36
37
|
|
|
37
38
|
const version = require('../../package.json').version;
|
|
38
39
|
const cachedTSConfigs = new Map();
|
|
39
|
-
let
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
let _transformConfig = {
|
|
41
|
+
babelPlugins: [],
|
|
42
|
+
external: []
|
|
43
|
+
};
|
|
44
|
+
let _externalMatcher = () => false;
|
|
45
|
+
function setTransformConfig(config) {
|
|
46
|
+
_transformConfig = config;
|
|
47
|
+
_externalMatcher = (0, _util.createFileMatcher)(_transformConfig.external);
|
|
42
48
|
}
|
|
43
|
-
function
|
|
44
|
-
return
|
|
49
|
+
function transformConfig() {
|
|
50
|
+
return _transformConfig;
|
|
45
51
|
}
|
|
46
52
|
function validateTsConfig(tsconfig) {
|
|
47
53
|
if (!tsconfig.tsConfigPath || !tsconfig.baseUrl) return;
|
|
@@ -74,7 +80,7 @@ const pathSeparator = process.platform === 'win32' ? ';' : ':';
|
|
|
74
80
|
const builtins = new Set(_module.default.builtinModules);
|
|
75
81
|
function resolveHook(filename, specifier) {
|
|
76
82
|
if (specifier.startsWith('node:') || builtins.has(specifier)) return;
|
|
77
|
-
if ((
|
|
83
|
+
if (!shouldTransform(filename)) return;
|
|
78
84
|
if (isRelativeSpecifier(specifier)) return (0, _util.resolveImportSpecifierExtension)(_path.default.resolve(_path.default.dirname(filename), specifier));
|
|
79
85
|
const isTypeScript = filename.endsWith('.ts') || filename.endsWith('.tsx');
|
|
80
86
|
const tsconfig = loadAndValidateTsconfigForFile(filename);
|
|
@@ -124,10 +130,14 @@ function resolveHook(filename, specifier) {
|
|
|
124
130
|
return (0, _util.resolveImportSpecifierExtension)(specifier);
|
|
125
131
|
}
|
|
126
132
|
}
|
|
133
|
+
function shouldTransform(filename) {
|
|
134
|
+
if (_externalMatcher(filename)) return false;
|
|
135
|
+
return !(0, _compilationCache.belongsToNodeModules)(filename);
|
|
136
|
+
}
|
|
127
137
|
function transformHook(originalCode, filename, moduleUrl) {
|
|
128
138
|
const isTypeScript = filename.endsWith('.ts') || filename.endsWith('.tsx') || filename.endsWith('.mts') || filename.endsWith('.cts');
|
|
129
139
|
const hasPreprocessor = process.env.PW_TEST_SOURCE_TRANSFORM && process.env.PW_TEST_SOURCE_TRANSFORM_SCOPE && process.env.PW_TEST_SOURCE_TRANSFORM_SCOPE.split(pathSeparator).some(f => filename.startsWith(f));
|
|
130
|
-
const pluginsPrologue = babelPlugins;
|
|
140
|
+
const pluginsPrologue = _transformConfig.babelPlugins;
|
|
131
141
|
const pluginsEpilogue = hasPreprocessor ? [[process.env.PW_TEST_SOURCE_TRANSFORM]] : [];
|
|
132
142
|
const hash = calculateHash(originalCode, filename, !!moduleUrl, pluginsPrologue, pluginsEpilogue);
|
|
133
143
|
const {
|
|
@@ -182,7 +192,7 @@ function installTransform() {
|
|
|
182
192
|
}
|
|
183
193
|
_module.default._resolveFilename = resolveFilename;
|
|
184
194
|
const revertPirates = _utilsBundle.pirates.addHook((code, filename) => {
|
|
185
|
-
if ((
|
|
195
|
+
if (!shouldTransform(filename)) return code;
|
|
186
196
|
return transformHook(code, filename);
|
|
187
197
|
}, {
|
|
188
198
|
exts: ['.ts', '.tsx', '.js', '.jsx', '.mjs']
|
package/lib/worker/testInfo.js
CHANGED
|
@@ -42,9 +42,10 @@ class TestInfoImpl {
|
|
|
42
42
|
set timeout(timeout) {
|
|
43
43
|
// Ignored.
|
|
44
44
|
}
|
|
45
|
-
constructor(configInternal, projectInternal, workerParams, test, retry, onStepBegin, onStepEnd) {
|
|
45
|
+
constructor(configInternal, projectInternal, workerParams, test, retry, onStepBegin, onStepEnd, onAttach) {
|
|
46
46
|
this._onStepBegin = void 0;
|
|
47
47
|
this._onStepEnd = void 0;
|
|
48
|
+
this._onAttach = void 0;
|
|
48
49
|
this._test = void 0;
|
|
49
50
|
this._timeoutManager = void 0;
|
|
50
51
|
this._startTime = void 0;
|
|
@@ -84,10 +85,12 @@ class TestInfoImpl {
|
|
|
84
85
|
this.outputDir = void 0;
|
|
85
86
|
this.snapshotDir = void 0;
|
|
86
87
|
this.errors = [];
|
|
88
|
+
this._attachmentsPush = void 0;
|
|
87
89
|
this._test = test;
|
|
88
90
|
this.testId = test.id;
|
|
89
91
|
this._onStepBegin = onStepBegin;
|
|
90
92
|
this._onStepEnd = onStepEnd;
|
|
93
|
+
this._onAttach = onAttach;
|
|
91
94
|
this._startTime = (0, _utils.monotonicTime)();
|
|
92
95
|
this._startWallTime = Date.now();
|
|
93
96
|
this.repeatEachIndex = workerParams.repeatEachIndex;
|
|
@@ -120,6 +123,11 @@ class TestInfoImpl {
|
|
|
120
123
|
const relativeTestFilePath = _path.default.relative(this.project.testDir, test._requireFile);
|
|
121
124
|
return _path.default.join(this.project.snapshotDir, relativeTestFilePath + '-snapshots');
|
|
122
125
|
})();
|
|
126
|
+
this._attachmentsPush = this.attachments.push.bind(this.attachments);
|
|
127
|
+
this.attachments.push = (...attachments) => {
|
|
128
|
+
for (const a of attachments) this._attach(a.name, a);
|
|
129
|
+
return this.attachments.length;
|
|
130
|
+
};
|
|
123
131
|
}
|
|
124
132
|
_modifier(type, modifierArgs) {
|
|
125
133
|
if (typeof modifierArgs[1] === 'function') {
|
|
@@ -283,14 +291,28 @@ class TestInfoImpl {
|
|
|
283
291
|
// ------------ TestInfo methods ------------
|
|
284
292
|
|
|
285
293
|
async attach(name, options = {}) {
|
|
294
|
+
this._attach(name, await (0, _util.normalizeAndSaveAttachment)(this.outputPath(), name, options));
|
|
295
|
+
}
|
|
296
|
+
_attach(name, attachment) {
|
|
286
297
|
const step = this._addStep({
|
|
287
298
|
title: `attach "${name}"`,
|
|
288
299
|
category: 'attach',
|
|
289
300
|
wallTime: Date.now()
|
|
290
301
|
});
|
|
291
|
-
this.
|
|
302
|
+
this._attachWithoutStep(attachment);
|
|
292
303
|
step.complete({});
|
|
293
304
|
}
|
|
305
|
+
_attachWithoutStep(attachment) {
|
|
306
|
+
var _attachment$body;
|
|
307
|
+
this._attachmentsPush(attachment);
|
|
308
|
+
this._onAttach({
|
|
309
|
+
testId: this._test.id,
|
|
310
|
+
name: attachment.name,
|
|
311
|
+
contentType: attachment.contentType,
|
|
312
|
+
path: attachment.path,
|
|
313
|
+
body: (_attachment$body = attachment.body) === null || _attachment$body === void 0 ? void 0 : _attachment$body.toString('base64')
|
|
314
|
+
});
|
|
315
|
+
}
|
|
294
316
|
outputPath(...pathSegments) {
|
|
295
317
|
_fs.default.mkdirSync(this.outputDir, {
|
|
296
318
|
recursive: true
|
|
@@ -331,7 +353,7 @@ class TestInfoImpl {
|
|
|
331
353
|
}
|
|
332
354
|
exports.TestInfoImpl = TestInfoImpl;
|
|
333
355
|
function serializeAttachments(attachments, initialAttachments) {
|
|
334
|
-
return attachments.filter(a => !initialAttachments.has(a)).map(a => {
|
|
356
|
+
return attachments.filter(a => a.name !== 'trace' && !initialAttachments.has(a)).map(a => {
|
|
335
357
|
var _a$body;
|
|
336
358
|
return {
|
|
337
359
|
name: a.name,
|
package/lib/worker/workerMain.js
CHANGED
|
@@ -228,7 +228,7 @@ class WorkerMain extends _process.ProcessRunner {
|
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
230
|
async _runTest(test, retry, nextTest) {
|
|
231
|
-
const testInfo = new _testInfo.TestInfoImpl(this._config, this._project, this._params, test, retry, stepBeginPayload => this.dispatchEvent('stepBegin', stepBeginPayload), stepEndPayload => this.dispatchEvent('stepEnd', stepEndPayload));
|
|
231
|
+
const testInfo = new _testInfo.TestInfoImpl(this._config, this._project, this._params, test, retry, stepBeginPayload => this.dispatchEvent('stepBegin', stepBeginPayload), stepEndPayload => this.dispatchEvent('stepEnd', stepEndPayload), attachment => this.dispatchEvent('attach', attachment));
|
|
232
232
|
const processAnnotation = annotation => {
|
|
233
233
|
testInfo.annotations.push(annotation);
|
|
234
234
|
switch (annotation.type) {
|
|
@@ -595,16 +595,7 @@ function buildTestEndPayload(testInfo) {
|
|
|
595
595
|
errors: testInfo.errors,
|
|
596
596
|
expectedStatus: testInfo.expectedStatus,
|
|
597
597
|
annotations: testInfo.annotations,
|
|
598
|
-
timeout: testInfo.timeout
|
|
599
|
-
attachments: testInfo.attachments.map(a => {
|
|
600
|
-
var _a$body;
|
|
601
|
-
return {
|
|
602
|
-
name: a.name,
|
|
603
|
-
contentType: a.contentType,
|
|
604
|
-
path: a.path,
|
|
605
|
-
body: (_a$body = a.body) === null || _a$body === void 0 ? void 0 : _a$body.toString('base64')
|
|
606
|
-
};
|
|
607
|
-
})
|
|
598
|
+
timeout: testInfo.timeout
|
|
608
599
|
};
|
|
609
600
|
}
|
|
610
601
|
function getSuites(test) {
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playwright/test",
|
|
3
|
-
"version": "1.35.0-alpha-jun-
|
|
3
|
+
"version": "1.35.0-alpha-jun-4-2023",
|
|
4
4
|
"description": "A high-level API to automate web browsers",
|
|
5
5
|
"repository": "github:Microsoft/playwright",
|
|
6
6
|
"homepage": "https://playwright.dev",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": ">=
|
|
8
|
+
"node": ">=16"
|
|
9
9
|
},
|
|
10
10
|
"main": "index.js",
|
|
11
11
|
"exports": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"license": "Apache-2.0",
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@types/node": "*",
|
|
44
|
-
"playwright-core": "1.35.0-alpha-jun-
|
|
44
|
+
"playwright-core": "1.35.0-alpha-jun-4-2023"
|
|
45
45
|
},
|
|
46
46
|
"optionalDependencies": {
|
|
47
47
|
"fsevents": "2.3.2"
|
package/types/test.d.ts
CHANGED
|
@@ -569,6 +569,31 @@ interface TestConfig {
|
|
|
569
569
|
*
|
|
570
570
|
*/
|
|
571
571
|
webServer?: TestConfigWebServer | TestConfigWebServer[];
|
|
572
|
+
/**
|
|
573
|
+
* Transpiler configuration.
|
|
574
|
+
*
|
|
575
|
+
* **Usage**
|
|
576
|
+
*
|
|
577
|
+
* ```js
|
|
578
|
+
* // playwright.config.ts
|
|
579
|
+
* import { defineConfig } from '@playwright/test';
|
|
580
|
+
*
|
|
581
|
+
* export default defineConfig({
|
|
582
|
+
* build: {
|
|
583
|
+
* external: '**\/*bundle.js',
|
|
584
|
+
* },
|
|
585
|
+
* });
|
|
586
|
+
* ```
|
|
587
|
+
*
|
|
588
|
+
*/
|
|
589
|
+
build?: {
|
|
590
|
+
/**
|
|
591
|
+
* Paths to exclude from the transpilation expressed as glob patterns. Typically heavy JS bundles your tests
|
|
592
|
+
* reference.
|
|
593
|
+
*/
|
|
594
|
+
external?: Array<string>;
|
|
595
|
+
};
|
|
596
|
+
|
|
572
597
|
/**
|
|
573
598
|
* Configuration for the `expect` assertion library. Learn more about [various timeouts](https://playwright.dev/docs/test-timeouts).
|
|
574
599
|
*
|