Skip to content

Commit 2545955

Browse files
committed
Add test failure screenshot option.
1 parent 9ad16c7 commit 2545955

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

test/helpers/webdriver/index.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,35 @@ export async function debugPause() {
215215
await new Promise(() => {});
216216
}
217217

218+
/**
219+
* Screenshot the app as it stands when a test fails.
220+
*
221+
* @remarks Must opt-in by setting the screenshot directory with `SLOBS_FAIL_SCREENSHOT_DIR`, so a normal test run
222+
* does not capture screenshots for every test. The file is named after the test (`<kebab-test-name>.png`) limited to 80 chars.
223+
*
224+
* Called from `afterEach.always` before the teardown stops the app, which is the last moment the failing UI still exists.
225+
* This should never throw so a failed capture does not register as real failure.
226+
*/
227+
async function saveFailureScreenshot(t: TExecutionContext) {
228+
const dir = process.env.SLOBS_FAIL_SCREENSHOT_DIR;
229+
if (!dir) return;
230+
231+
try {
232+
const imgTitle = t.title
233+
.toLowerCase()
234+
.replace(/[^a-z0-9]+/g, '-')
235+
.replace(/^-+|-+$/g, '')
236+
.slice(0, 80);
237+
238+
fs.mkdirSync(dir, { recursive: true });
239+
const filePath = path.join(dir, `${imgTitle}.png`);
240+
await t.context.app.client.saveScreenshot(filePath);
241+
console.log(`Failure screenshot: ${filePath}`);
242+
} catch (e: unknown) {
243+
console.log(`Could not capture a failure screenshot for test ${t.title}:`, e);
244+
}
245+
}
246+
218247
export function useWebdriver(options: ITestRunnerOptions = {}) {
219248
// tslint:disable-next-line:no-parameter-reassignment TODO
220249
options = Object.assign({}, DEFAULT_OPTIONS, options);
@@ -456,6 +485,10 @@ export function useWebdriver(options: ITestRunnerOptions = {}) {
456485

457486
test.afterEach.always(async t => {
458487
await checkErrorsInLogFile(t);
488+
489+
// Capture the failing UI before the teardown below stops the app. Off unless SLOBS_FAIL_SCREENSHOT_DIR is set.
490+
if (!testPassed && appIsRunning) await saveFailureScreenshot(t);
491+
459492
if (!testPassed && options.pauseIfFailed) {
460493
console.log('Test execution has been paused due `pauseIfFailed` enabled');
461494
await sleep(ALMOST_INFINITY);

0 commit comments

Comments
 (0)