Skip to content

Commit 5ebf998

Browse files
authored
Merge pull request #2603 from artilleryio/feat/playwright-tracing
2 parents e1e7d9a + fc494a1 commit 5ebf998

File tree

5 files changed

+282
-100
lines changed

5 files changed

+282
-100
lines changed

package-lock.json

+35-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/artillery-engine-playwright/index.js

+48-4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,25 @@ class PlaywrightEngine {
3939
this.processor.$rewriteMetricName = function (name, _type) { return name; }
4040
}
4141

42+
//
43+
// Tracing:
44+
// Note that these variables are shared across VUs *within* a single worker thread, as each
45+
// worker creates its own instance of the engine.
46+
this.tracesRecordedCount = 0; // total count of traces recorded so far
47+
this.MAX_TRACE_RECORDINGS = 5; // total limit on traces we'll record
48+
49+
this.enablePlaywrightTracing = typeof process.env.ENABLE_PLAYWRIGHT_TRACING !== 'undefined';
50+
51+
// We use this to make sure only one VU is recording at one time:
52+
this.playwrightRecordTraceForNextVU = this.enablePlaywrightTracing;
53+
54+
// We use this to limit the number of recordings that we save:
55+
this.lastTraceRecordedTime = 0; // timestamp of last saved recording
56+
this.TRACE_RECORDING_INTERVAL_MSEC = 1000 * 60 * 5; // minimum interval between saving new recordings
57+
58+
this.tracePaths = [];
59+
this.traceOutputDir = process.env.PLAYWRIGHT_TRACING_OUTPUT_DIR || '/tmp';
60+
4261
return this;
4362
}
4463

@@ -98,6 +117,12 @@ class PlaywrightEngine {
98117

99118
const context = await browser.newContext(contextOptions);
100119

120+
if (self.playwrightRecordTraceForNextVU) {
121+
self.playwrightRecordTraceForNextVU = false;
122+
initialContext.vars.isRecording = true; // used by the VU to discard the trace if needed
123+
await context.tracing.start({ screenshots: true, snapshots: true });
124+
}
125+
101126
context.setDefaultNavigationTimeout(self.defaultNavigationTimeout);
102127
context.setDefaultTimeout(self.defaultTimeout);
103128
if (self.testIdAttribute) {
@@ -248,22 +273,41 @@ class PlaywrightEngine {
248273
await traceScenario(page, initialContext, events, fn, spec.name)
249274
} else {
250275
await fn(page, initialContext, events, test);
251-
}
252-
276+
}
253277
await page.close();
254-
278+
255279
if (cb) {
256280
cb(null, initialContext);
257281
}
258282
return initialContext;
259283
} catch (err) {
260-
console.error(err);
284+
if (initialContext.vars.isRecording) {
285+
if (Date.now() - self.lastTraceRecordedTime > self.TRACE_RECORDING_INTERVAL_MSEC) {
286+
const tracePath = `${self.traceOutputDir}/trace-${initialContext.vars.$testId}-${initialContext.vars.$uuid}-${Date.now()}.zip`;
287+
await context.tracing.stop({ path: tracePath});
288+
self.lastTraceRecordedTime = Date.now();
289+
self.tracesRecordedCount++;
290+
self.tracePaths.push(tracePath);
291+
initialContext.vars.isRecording = false; // for finally{} block
292+
}
293+
}
294+
261295
if (cb) {
262296
cb(err, initialContext);
263297
} else {
264298
throw err;
265299
}
300+
266301
} finally {
302+
if (self.enablePlaywrightTracing && self.tracesRecordedCount < self.MAX_TRACE_RECORDINGS) {
303+
self.playwrightRecordTraceForNextVU = true;
304+
}
305+
306+
if (initialContext.vars.isRecording) {
307+
// This VU was recording but completed successfully, drop the recording
308+
await context.tracing.stop();
309+
}
310+
267311
await context.close();
268312

269313
if (self.useSeparateBrowserPerVU) {

packages/artillery/lib/platform/aws-ecs/legacy/run-cluster.js

+11
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,17 @@ async function tryRunCluster(scriptPath, options, artilleryReporter) {
235235
context.dotenv = dotenv.parse(contents);
236236
}
237237

238+
// Explicitly make ARTILLERY_CLOUD_API_KEY available to workers (if set)
239+
// Relying on the fact that contents of context.dotenv gets passed onto workers
240+
// for it
241+
if (process.env.ARTILLERY_CLOUD_API_KEY) {
242+
if (!context.dotenv) {
243+
context.dotenv = {};
244+
}
245+
context.dotenv.ARTILLERY_CLOUD_API_KEY =
246+
process.env.ARTILLERY_CLOUD_API_KEY;
247+
}
248+
238249
if (options.bundle) {
239250
context.namedTest = true;
240251
}

0 commit comments

Comments
 (0)