Skip to content

Commit 6a8f7e1

Browse files
authored
save videos for sessions (#3505)
* save videos for sessions * fixed bad commit
1 parent 9983586 commit 6a8f7e1

File tree

4 files changed

+61
-19
lines changed

4 files changed

+61
-19
lines changed

lib/codecept.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,13 @@ class Codecept {
9595
runHooks() {
9696
// default hooks
9797
runHook(require('./listener/steps'));
98+
runHook(require('./listener/artifacts'));
9899
runHook(require('./listener/config'));
99100
runHook(require('./listener/helpers'));
100101
runHook(require('./listener/timeout'));
101102
runHook(require('./listener/exit'));
102103

103-
// custom hooks
104+
// custom hooks (previous iteration of plugins)
104105
this.config.hooks.forEach(hook => runHook(hook));
105106
}
106107

lib/helper/Playwright.js

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -518,10 +518,11 @@ class Playwright extends Helper {
518518
browserContext = browser.context();
519519
page = await browser.firstWindow();
520520
} else {
521-
browserContext = await this.browser.newContext(config);
521+
browserContext = await this.browser.newContext(Object.assign(this.options, config));
522522
page = await browserContext.newPage();
523523
}
524524

525+
if (this.options.trace) await browserContext.tracing.start({ screenshots: true, snapshots: true });
525526
await targetCreatedHandler.call(this, page);
526527
await this._setPage(page);
527528
// Create a new page inside context.
@@ -2071,37 +2072,42 @@ class Playwright extends Helper {
20712072
}
20722073

20732074
if (this.options.recordVideo && this.page && this.page.video()) {
2074-
test.artifacts.video = `${global.output_dir}${pathSeparator}videos${pathSeparator}${clearString(test.title)}_${Date.now()}.failed.webm`;
2075-
this.page.video().saveAs(test.artifacts.video).then(() => {
2076-
this.page.video().delete().catch(e => {});
2077-
});
2075+
test.artifacts.video = await saveVideoForPage(this.page, `${test.title}.failed`);
2076+
for (const sessionName in this.sessionPages) {
2077+
test.artifacts[`video_${sessionName}`] = await saveVideoForPage(this.sessionPages[sessionName], `${test.title}_${sessionName}.failed`);
2078+
}
20782079
}
20792080

20802081
if (this.options.trace) {
2081-
const path = `${`${global.output_dir}${pathSeparator}trace${pathSeparator}${clearString(test.title)}`.slice(0, 251)}.zip`;
2082-
await this.browserContext.tracing.stop({ path });
2083-
test.artifacts.trace = path;
2082+
test.artifacts.trace = await saveTraceForContext(this.browserContext, `${test.title}.failed`);
2083+
for (const sessionName in this.sessionPages) {
2084+
if (!this.sessionPages[sessionName].context) continue;
2085+
test.artifacts[`trace_${sessionName}`] = await saveTraceForContext(this.sessionPages[sessionName].context(), `${test.title}_${sessionName}.failed`);
2086+
}
20842087
}
20852088
}
20862089

20872090
async _passed(test) {
20882091
if (this.options.recordVideo && this.page && this.page.video()) {
2089-
test.artifacts.video = `${global.output_dir}${pathSeparator}videos${pathSeparator}${clearString(test.title)}_${Date.now()}.passed.webm`;
2090-
20912092
if (this.options.keepVideoForPassedTests) {
2092-
this.page.video().saveAs(test.artifacts.video).then(() => {
2093-
this.page.video().delete().catch(e => {});
2094-
});
2093+
test.artifacts.video = await saveVideoForPage(this.page, `${test.title}.passed`);
2094+
for (const sessionName of Object.keys(this.sessionPages)) {
2095+
test.artifacts[`video_${sessionName}`] = await saveVideoForPage(this.sessionPages[sessionName], `${test.title}_${sessionName}.passed`);
2096+
}
20952097
} else {
20962098
this.page.video().delete().catch(e => {});
20972099
}
20982100
}
20992101

21002102
if (this.options.trace) {
21012103
if (this.options.keepTraceForPassedTests) {
2102-
const path = `${global.output_dir}${pathSeparator}trace${pathSeparator}${clearString(test.title)}.zip`;
2103-
await this.browserContext.tracing.stop({ path });
2104-
test.artifacts.trace = path;
2104+
if (this.options.trace) {
2105+
test.artifacts.trace = await saveTraceForContext(this.browserContext, `${test.title}.passed`);
2106+
for (const sessionName in this.sessionPages) {
2107+
if (!this.sessionPages[sessionName].context) continue;
2108+
test.artifacts[`trace_${sessionName}`] = await saveTraceForContext(this.sessionPages[sessionName].context(), `${test.title}_${sessionName}.passed`);
2109+
}
2110+
}
21052111
} else {
21062112
await this.browserContext.tracing.stop();
21072113
}
@@ -2972,3 +2978,21 @@ async function refreshContextSession() {
29722978
});
29732979
}
29742980
}
2981+
2982+
async function saveVideoForPage(page, name) {
2983+
if (!page.video()) return null;
2984+
const fileName = `${global.output_dir}${pathSeparator}videos${pathSeparator}${Date.now()}_${clearString(name).slice(0, 245)}.webm`;
2985+
page.video().saveAs(fileName).then(() => {
2986+
if (!page) return;
2987+
page.video().delete().catch(e => {});
2988+
});
2989+
return fileName;
2990+
}
2991+
2992+
async function saveTraceForContext(context, name) {
2993+
if (!context) return;
2994+
if (!context.tracing) return;
2995+
const fileName = `${`${global.output_dir}${pathSeparator}trace${pathSeparator}${Date.now()}_${clearString(name)}`.slice(0, 245)}.zip`;
2996+
await context.tracing.stop({ path: fileName });
2997+
return fileName;
2998+
}

lib/helper/extras/PlaywrightRestartOpts.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ module.exports = {
1818

1919
restarts = Object.keys(RESTART_OPTS).find(key => RESTART_OPTS[key] === restart);
2020

21-
console.log(restarts);
22-
2321
if (restarts === null || restarts === undefined) throw new Error('No restart strategy set, use the following values for restart: session, context, browser');
2422
},
2523

lib/listener/artifacts.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const event = require('../event');
2+
const recorder = require('../recorder');
3+
4+
/**
5+
* Create and clean up empty artifacts
6+
*/
7+
module.exports = function () {
8+
event.dispatcher.on(event.test.before, (test) => {
9+
test.artifacts = {};
10+
});
11+
12+
event.dispatcher.on(event.test.after, (test) => {
13+
recorder.add('clean up empty artifacts', () => {
14+
for (const key in (test.artifacts || {})) {
15+
if (!test.artifacts[key]) delete test.artifacts[key];
16+
}
17+
});
18+
});
19+
};

0 commit comments

Comments
 (0)