Skip to content

Commit d4d348f

Browse files
author
Aleksandr Nefedov
committed
includeObsoleteSnapshots option
1 parent 9743316 commit d4d348f

File tree

6 files changed

+197
-41
lines changed

6 files changed

+197
-41
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ Please note that all configuration properties are optional.
7979
| `includeConsoleLog` | `BOOLEAN` | If set to true, this will output all triggered console logs for each test suite. Please note that you have to run Jest together with `--verbose=false` in order to have Jest catch any logs during the tests. | `false` |
8080
| `includeFailureMsg` | `BOOLEAN` | If this setting is set to true, this will output the detailed failure message for each failed test. | `false` |
8181
| `includeSuiteFailure` | `BOOLEAN` | If set to true, this will output the detailed failure message for complete suite failures. | `false` |
82+
| `includeObsoleteSnapshots` | `BOOLEAN` | If set to true, this will output obsolete snapshot names. | `false` |
8283
| `logo` | `STRING` | Path to a logo that will be included in the header of the report | `null` |
8384
| `outputPath` | `STRING` | The path to where the plugin will output the HTML report. The path must include the filename and end with .html | `"./test-report.html"` |
8485
| `pageTitle` | `STRING` | The title of the document. This string will also be outputted on the top of the page. | `"Test Suite"` |

src/htmlreporter.ts

Lines changed: 88 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,18 @@ class HTMLReporter {
258258
`${this.testData.numPendingTestSuites} pending`
259259
);
260260

261+
if (
262+
this.testData.snapshot.unchecked > 0 &&
263+
this.getConfigValue("includeObsoleteSnapshots")
264+
) {
265+
suiteSummary.ele(
266+
"div",
267+
{
268+
class: "summary-obsolete-snapshots",
269+
},
270+
`${this.testData.snapshot.unchecked} obsolete snapshots`
271+
);
272+
}
261273
// Test Summary
262274
const testSummary = summaryContainer.ele("div", { id: "test-summary" });
263275
testSummary.ele(
@@ -403,38 +415,14 @@ class HTMLReporter {
403415
this.consoleLogList.length > 0 &&
404416
this.getConfigValue("includeConsoleLog")
405417
) {
406-
// Filter out the logs for this test file path
407-
const filteredConsoleLogs = this.consoleLogList.find(
408-
(logs) => logs.filePath === suite.testFilePath
409-
);
410-
if (filteredConsoleLogs && filteredConsoleLogs.logs.length > 0) {
411-
// Console Log Container
412-
const consoleLogContainer = suiteContainer.ele("div", {
413-
class: "suite-consolelog",
414-
});
415-
// Console Log Header
416-
consoleLogContainer.ele(
417-
"div",
418-
{ class: "suite-consolelog-header" },
419-
"Console Log"
420-
);
421-
// Apply the logs to the body
422-
filteredConsoleLogs.logs.forEach((log) => {
423-
const logElement = consoleLogContainer.ele("div", {
424-
class: "suite-consolelog-item",
425-
});
426-
logElement.ele(
427-
"pre",
428-
{ class: "suite-consolelog-item-origin" },
429-
stripAnsi(log.origin)
430-
);
431-
logElement.ele(
432-
"pre",
433-
{ class: "suite-consolelog-item-message" },
434-
stripAnsi(log.message)
435-
);
436-
});
437-
}
418+
this.renderSuiteConsoleLogs(suite, suiteContainer);
419+
}
420+
421+
if (
422+
suite.snapshot.unchecked > 0 &&
423+
this.getConfigValue("includeObsoleteSnapshots")
424+
) {
425+
this.renderSuiteObsoleteSnapshots(suiteContainer, suite);
438426
}
439427
});
440428
}
@@ -445,6 +433,68 @@ class HTMLReporter {
445433
}
446434
}
447435

436+
public renderSuiteConsoleLogs(
437+
suite: TestResult,
438+
suiteContainer: xmlbuilder.XMLElement
439+
) {
440+
// Filter out the logs for this test file path
441+
const filteredConsoleLogs = this.consoleLogList.find(
442+
(logs) => logs.filePath === suite.testFilePath
443+
);
444+
if (filteredConsoleLogs && filteredConsoleLogs.logs.length > 0) {
445+
// Console Log Container
446+
const consoleLogContainer = suiteContainer.ele("div", {
447+
class: "suite-consolelog",
448+
});
449+
// Console Log Header
450+
consoleLogContainer.ele(
451+
"div",
452+
{ class: "suite-consolelog-header" },
453+
"Console Log"
454+
);
455+
// Apply the logs to the body
456+
filteredConsoleLogs.logs.forEach((log) => {
457+
const logElement = consoleLogContainer.ele("div", {
458+
class: "suite-consolelog-item",
459+
});
460+
logElement.ele(
461+
"pre",
462+
{ class: "suite-consolelog-item-origin" },
463+
stripAnsi(log.origin)
464+
);
465+
logElement.ele(
466+
"pre",
467+
{ class: "suite-consolelog-item-message" },
468+
stripAnsi(log.message)
469+
);
470+
});
471+
}
472+
}
473+
474+
public renderSuiteObsoleteSnapshots(
475+
suiteContainer: xmlbuilder.XMLElement,
476+
suite: TestResult
477+
) {
478+
// Obsolete snapshots Container
479+
const snapshotContainer = suiteContainer.ele("div", {
480+
class: "suite-obsolete-snapshots",
481+
});
482+
// Obsolete snapshots Header
483+
snapshotContainer.ele(
484+
"div",
485+
{ class: "suite-obsolete-snapshots-header" },
486+
"Obsolete snapshots"
487+
);
488+
const keysElement = snapshotContainer.ele("div", {
489+
class: "suite-obsolete-snapshots-item",
490+
});
491+
keysElement.ele(
492+
"pre",
493+
{ class: "suite-obsolete-snapshots-item-message" },
494+
suite.snapshot.uncheckedKeys.join("\n")
495+
);
496+
}
497+
448498
/**
449499
* Fetch and setup configuration
450500
*/
@@ -462,6 +512,7 @@ class HTMLReporter {
462512
includeConsoleLog,
463513
includeFailureMsg,
464514
includeSuiteFailure,
515+
includeObsoleteSnapshots,
465516
outputPath,
466517
pageTitle,
467518
theme,
@@ -513,6 +564,11 @@ class HTMLReporter {
513564
environmentVariable: "JEST_HTML_REPORTER_INCLUDE_SUITE_FAILURE",
514565
configValue: includeSuiteFailure,
515566
},
567+
includeObsoleteSnapshots: {
568+
defaultValue: false,
569+
environmentVariable: "JEST_HTML_REPORTER_INCLUDE_OBSOLETE_SNAPSHOTS",
570+
configValue: includeObsoleteSnapshots,
571+
},
516572
includeConsoleLog: {
517573
defaultValue: false,
518574
environmentVariable: "JEST_HTML_REPORTER_INCLUDE_CONSOLE_LOG",

src/types/index.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface IJestHTMLReporterConfigOptions {
99
includeConsoleLog?: boolean;
1010
includeFailureMsg?: boolean;
1111
includeSuiteFailure?: boolean;
12+
includeObsoleteSnapshots?: boolean;
1213
logo?: string;
1314
outputPath?: string;
1415
pageTitle?: string;
@@ -50,6 +51,9 @@ export interface IJestHTMLReporterConfig {
5051
includeSuiteFailure: IJestHTMLReporterConfigOption<
5152
IJestHTMLReporterConfigOptions["includeSuiteFailure"]
5253
>;
54+
includeObsoleteSnapshots: IJestHTMLReporterConfigOption<
55+
IJestHTMLReporterConfigOptions["includeObsoleteSnapshots"]
56+
>;
5357
logo: IJestHTMLReporterConfigOption<IJestHTMLReporterConfigOptions["logo"]>;
5458
outputPath: IJestHTMLReporterConfigOption<
5559
IJestHTMLReporterConfigOptions["outputPath"]

style/defaultTheme.css

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ header {
6969
border-left: 0.4rem solid #4f8a10;
7070
padding-left: 0.5rem;
7171
}
72-
.summary-failed {
72+
.summary-failed,
73+
.summary-obsolete-snapshots {
7374
color: #d8000c;
7475
border-left: 0.4rem solid #d8000c;
7576
padding-left: 0.5rem;
@@ -174,7 +175,7 @@ header {
174175

175176
/* CONSOLE LOGS */
176177
.suite-consolelog {
177-
margin-bottom: 2rem;
178+
margin-bottom: 0.25rem;
178179
padding: 1rem;
179180
background-color: #efefef;
180181
}
@@ -201,3 +202,30 @@ header {
201202
font-size: 1rem;
202203
padding: 0 0.5rem;
203204
}
205+
206+
/* OBSOLETE SNAPSHOTS */
207+
.suite-obsolete-snapshots {
208+
margin-bottom: 0.25rem;
209+
padding: 1rem;
210+
background-color: #ffbaba;
211+
color: #d8000c;
212+
}
213+
.suite-obsolete-snapshots-header {
214+
font-weight: bold;
215+
}
216+
.suite-obsolete-snapshots-item {
217+
padding: 0.5rem;
218+
}
219+
.suite-obsolete-snapshots-item pre {
220+
margin: 0.5rem 0;
221+
white-space: pre-wrap;
222+
white-space: -moz-pre-wrap;
223+
white-space: -pre-wrap;
224+
white-space: -o-pre-wrap;
225+
word-wrap: break-word;
226+
}
227+
.suite-obsolete-snapshots-item-message {
228+
color: #000;
229+
font-size: 1rem;
230+
padding: 0 0.5rem;
231+
}

test/htmlreporter.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,28 @@ describe("HTMLReporter", () => {
210210
});
211211
});
212212

213+
describe("includeObsoleteSnapshots", () => {
214+
it("should include obsolete snapshots", async () => {
215+
const reporter = new HTMLReporter(
216+
mockedJestResponseMultipleTestResult,
217+
{
218+
includeObsoleteSnapshots: true,
219+
},
220+
null
221+
);
222+
const reportContent = (
223+
await reporter.renderTestReportContent()
224+
).toString();
225+
226+
expect(
227+
reportContent.indexOf('<div class="summary-obsolete-snapshots">')
228+
).toBeGreaterThan(-1);
229+
expect(
230+
reportContent.indexOf('<div class="suite-obsolete-snapshots">')
231+
).toBeGreaterThan(-1);
232+
});
233+
});
234+
213235
describe("logo", () => {
214236
it("should add a logo to the report", async () => {
215237
const reporter = new HTMLReporter(

test/mockdata/index.ts

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,13 @@ const mockedJestResponseBase: AggregatedResult = {
2424
filesUpdated: 0,
2525
matched: 0,
2626
total: 0,
27-
unchecked: 0,
28-
uncheckedKeysByFile: [],
27+
unchecked: 2,
28+
uncheckedKeysByFile: [
29+
{
30+
filePath: "index-a.js",
31+
keys: ["test", "test2"],
32+
},
33+
],
2934
unmatched: 0,
3035
updated: 0,
3136
},
@@ -50,7 +55,15 @@ export const mockedJestResponseSingleTestResult: AggregatedResult = {
5055
start: 1498476492,
5156
end: 1498476650,
5257
},
53-
snapshot: undefined,
58+
snapshot: {
59+
added: 0,
60+
fileDeleted: false,
61+
matched: 0,
62+
unmatched: 0,
63+
updated: 0,
64+
unchecked: 0,
65+
uncheckedKeys: [],
66+
},
5467
testFilePath: "/mocked/path/to/test.ts",
5568
skipped: false,
5669
displayName: undefined,
@@ -104,7 +117,15 @@ export const mockedJestResponseMultipleTestResult: AggregatedResult = {
104117
console: undefined,
105118
failureMessage: null,
106119
numTodoTests: 0,
107-
snapshot: undefined,
120+
snapshot: {
121+
added: 0,
122+
fileDeleted: false,
123+
matched: 0,
124+
unmatched: 0,
125+
updated: 0,
126+
unchecked: 2,
127+
uncheckedKeys: ["test", "test2"],
128+
},
108129
skipped: false,
109130
displayName: undefined,
110131
leaks: false,
@@ -156,7 +177,15 @@ export const mockedJestResponseMultipleTestResult: AggregatedResult = {
156177
console: undefined,
157178
failureMessage: null,
158179
numTodoTests: 0,
159-
snapshot: undefined,
180+
snapshot: {
181+
added: 0,
182+
fileDeleted: false,
183+
matched: 0,
184+
unmatched: 0,
185+
updated: 0,
186+
unchecked: 0,
187+
uncheckedKeys: [],
188+
},
160189
skipped: false,
161190
displayName: undefined,
162191
leaks: false,
@@ -208,7 +237,15 @@ export const mockedJestResponseMultipleTestResult: AggregatedResult = {
208237
console: undefined,
209238
failureMessage: null,
210239
numTodoTests: 0,
211-
snapshot: undefined,
240+
snapshot: {
241+
added: 0,
242+
fileDeleted: false,
243+
matched: 0,
244+
unmatched: 0,
245+
updated: 0,
246+
unchecked: 0,
247+
uncheckedKeys: [],
248+
},
212249
skipped: false,
213250
displayName: undefined,
214251
leaks: false,
@@ -261,7 +298,15 @@ export const mockedJestResponseMultipleTestResult: AggregatedResult = {
261298
failureMessage:
262299
" \u001b[1m● \u001b[22mTest suite failed to run\n\n SyntaxError",
263300
numTodoTests: 0,
264-
snapshot: undefined,
301+
snapshot: {
302+
added: 0,
303+
fileDeleted: false,
304+
matched: 0,
305+
unmatched: 0,
306+
updated: 0,
307+
unchecked: 0,
308+
uncheckedKeys: [],
309+
},
265310
skipped: false,
266311
displayName: undefined,
267312
leaks: false,

0 commit comments

Comments
 (0)