Skip to content

Commit c5997c8

Browse files
Connor ClarkDevtools-frontend LUCI CQ
authored andcommitted
Require --on-diff=update even for newly added snapshots
This was done to auto-accept snapshots for new tests (like jest does), but that resulted in new tests accidentally merging with no snapshot entry. Bug: 434252192 Change-Id: I7c8538af64c4ee8b97cd0389a368479180af9789 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6916862 Reviewed-by: Paul Irish <paulirish@chromium.org> Commit-Queue: Connor Clark <cjamcl@chromium.org> Auto-Submit: Connor Clark <cjamcl@chromium.org>
1 parent dafa576 commit c5997c8

4 files changed

Lines changed: 33 additions & 17 deletions

File tree

front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ no origins were preconnected.
843843
- https://developer.chrome.com/docs/lighthouse/performance/uses-rel-preconnect/
844844
=== end content
845845

846-
Title: PerformanceInsightFormatter Third Parties Insight serializes correctly when there are no results
846+
Title: PerformanceInsightFormatter ThirdParties serializes correctly when there are no results
847847
Content:
848848
## Insight Title: 3rd parties
849849

@@ -859,7 +859,7 @@ No 3rd party scripts were found on this page.
859859
- https://web.dev/articles/optimizing-content-efficiency-loading-third-party-javascript/
860860
=== end content
861861

862-
Title: PerformanceInsightFormatter Third Parties Insight serializes 3rd party scripts correctly
862+
Title: PerformanceInsightFormatter ThirdParties serializes 3rd party scripts correctly
863863
Content:
864864
## Insight Title: 3rd parties
865865

front_end/testing/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ The above test will fail if any DOM mutations are detected.
9292

9393
For Karma unit tests, you can add regression tests for string output (similar to Jest snapshots) via SnapshotTester.
9494

95-
> Note: Prefer unit tests that test behavior more directly when possible. Some good candidates for snapshot tests is code the formats long strings. A bad candidate would be a `JSON.stringify` of a complex object structure (prefer explicit asserts instead).
95+
> Note: Prefer unit tests that test behavior more directly when possible. Some good candidates for snapshot tests is code that formats long strings. A bad candidate would be a `JSON.stringify` of a complex object structure (prefer explicit asserts instead).
9696
9797
Results for all snapshots for a test file `MyFile.test.ts` are written to `MyFile.snapshot.txt`.
9898

front_end/testing/SnapshotTester.ts

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,15 @@ export class SnapshotTester {
7474
this.#actual.set(title, actual);
7575

7676
const expected = this.#expected.get(title);
77-
if (!expected) {
78-
// New tests always pass on the first run.
77+
if (expected === undefined) {
7978
this.#newTests = true;
80-
return;
79+
if (SnapshotTester.#updateMode) {
80+
return;
81+
}
82+
83+
this.#anyFailures = true;
84+
throw new Error(`snapshot assertion failed! new snapshot found (${
85+
title}), must run \`npm run test -- --on-diff=update ...\` to accept it.`);
8186
}
8287

8388
if (!SnapshotTester.#updateMode && actual !== expected) {
@@ -86,6 +91,16 @@ export class SnapshotTester {
8691
}
8792
}
8893

94+
async #postUpdate(): Promise<void> {
95+
const url = new URL('/update-snapshot', import.meta.url);
96+
url.searchParams.set('snapshotUrl', this.#snapshotUrl);
97+
const content = this.#serializeSnapshotFileContent();
98+
const response = await fetch(url, {method: 'POST', body: content});
99+
if (response.status !== 200) {
100+
throw new Error(`Unable to update snapshot ${url}`);
101+
}
102+
}
103+
89104
async finish() {
90105
let didAnyTestNotRun = false;
91106
for (const title of this.#expected.keys()) {
@@ -95,21 +110,22 @@ export class SnapshotTester {
95110
}
96111
}
97112

98-
let shouldPostUpdate = SnapshotTester.#updateMode;
99-
if (!this.#anyFailures && (didAnyTestNotRun || this.#newTests)) {
100-
shouldPostUpdate = true;
113+
const hasChanges = this.#anyFailures || didAnyTestNotRun || this.#newTests;
114+
if (!hasChanges) {
115+
return;
101116
}
102117

103-
if (!shouldPostUpdate) {
118+
// If the update flag is on, post any and all changes (failures, new tests, removals).
119+
if (SnapshotTester.#updateMode) {
120+
await this.#postUpdate();
104121
return;
105122
}
106123

107-
const url = new URL('/update-snapshot', import.meta.url);
108-
url.searchParams.set('snapshotUrl', this.#snapshotUrl);
109-
const content = this.#serializeSnapshotFileContent();
110-
const response = await fetch(url, {method: 'POST', body: content});
111-
if (response.status !== 200) {
112-
throw new Error(`Unable to update snapshot ${url}`);
124+
// Note: this does not handle test filtering (.only, --grep). Need a reliable way
125+
// to distinguish a deleted test from a test that was filtered out.
126+
if (didAnyTestNotRun) {
127+
throw new Error(
128+
'Snapshots are out of sync (a test was likely deleted or renamed). Run with `--on-diff=update` to fix.');
113129
}
114130
}
115131

test/unit/karma.conf.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ function snapshotTesterFactory() {
279279
res.writeHead(200, {'Content-Type': 'application/json'});
280280
const updateMode = TestConfig.onDiff.update === true;
281281
res.end(JSON.stringify({updateMode}));
282-
return res.end();
282+
return;
283283
}
284284

285285
if (req.url.startsWith('/update-snapshot')) {

0 commit comments

Comments
 (0)