diff --git a/CHANGELOG.md b/CHANGELOG.md
index accab0fc74f8..085cfca36103 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
- `[expect]` Display expectedDiff more carefully in toBeCloseTo ([#8389](https://github.com/facebook/jest/pull/8389))
- `[jest-fake-timers]` `getTimerCount` will not include cancelled immediates ([#8764](https://github.com/facebook/jest/pull/8764))
+- `[jest-snapshot]` Remove only the added newlines in multiline snapshots ([#8859](https://github.com/facebook/jest/pull/8859))
### Chore & Maintenance
diff --git a/packages/jest-snapshot/src/__tests__/utils.test.ts b/packages/jest-snapshot/src/__tests__/utils.test.ts
index 85c757fe10d7..c96db37cc8cd 100644
--- a/packages/jest-snapshot/src/__tests__/utils.test.ts
+++ b/packages/jest-snapshot/src/__tests__/utils.test.ts
@@ -19,9 +19,11 @@ import {
SNAPSHOT_GUIDE_LINK,
SNAPSHOT_VERSION,
SNAPSHOT_VERSION_WARNING,
+ addExtraLineBreaks,
deepMerge,
getSnapshotData,
keyToTestName,
+ removeExtraLineBreaks,
saveSnapshotFile,
serialize,
testNameToKey,
@@ -192,6 +194,78 @@ test('serialize handles \\r\\n', () => {
expect(serializedData).toBe('\n"
\n
"\n');
});
+describe('ExtraLineBreaks', () => {
+ test('0 empty string', () => {
+ const expected = '';
+
+ const added = addExtraLineBreaks(expected);
+ const removed = removeExtraLineBreaks(added);
+
+ expect(added).toBe(expected);
+ expect(removed).toBe(expected);
+ });
+
+ test('1 line has double quote marks at edges', () => {
+ const expected = '" one line "';
+
+ const added = addExtraLineBreaks(expected);
+ const removed = removeExtraLineBreaks(added);
+
+ expect(added).toBe(expected);
+ expect(removed).toBe(expected);
+ });
+
+ test('1 line has spaces at edges', () => {
+ const expected = ' one line ';
+
+ const added = addExtraLineBreaks(expected);
+ const removed = removeExtraLineBreaks(added);
+
+ expect(added).toBe(expected);
+ expect(removed).toBe(expected);
+ });
+
+ test('2 lines both are blank', () => {
+ const expected = '\n';
+
+ const added = addExtraLineBreaks(expected);
+ const removed = removeExtraLineBreaks(added);
+
+ expect(added).toBe('\n' + expected + '\n');
+ expect(removed).toBe(expected);
+ });
+
+ test('2 lines have double quote marks at edges', () => {
+ const expected = '"\n"';
+
+ const added = addExtraLineBreaks(expected);
+ const removed = removeExtraLineBreaks(added);
+
+ expect(added).toBe('\n' + expected + '\n');
+ expect(removed).toBe(expected);
+ });
+
+ test('2 lines first is blank', () => {
+ const expected = '\nsecond line ';
+
+ const added = addExtraLineBreaks(expected);
+ const removed = removeExtraLineBreaks(added);
+
+ expect(added).toBe('\n' + expected + '\n');
+ expect(removed).toBe(expected);
+ });
+
+ test('2 lines last is blank', () => {
+ const expected = ' first line\n';
+
+ const added = addExtraLineBreaks(expected);
+ const removed = removeExtraLineBreaks(added);
+
+ expect(added).toBe('\n' + expected + '\n');
+ expect(removed).toBe(expected);
+ });
+});
+
describe('DeepMerge with property matchers', () => {
const matcher = expect.any(String);
diff --git a/packages/jest-snapshot/src/index.ts b/packages/jest-snapshot/src/index.ts
index 401843374b9f..3526cbb687c6 100644
--- a/packages/jest-snapshot/src/index.ts
+++ b/packages/jest-snapshot/src/index.ts
@@ -349,8 +349,8 @@ const _toMatchSnapshot = ({
`${RECEIVED_COLOR('Received value')} ` +
`${actual}`;
} else {
- expected = (expected || '').trim();
- actual = (actual || '').trim();
+ expected = utils.removeExtraLineBreaks(expected || '');
+ actual = utils.removeExtraLineBreaks(actual || '');
// Assign to local variable because of declaration let expected:
// TypeScript thinks it could change before report function is called.
diff --git a/packages/jest-snapshot/src/utils.ts b/packages/jest-snapshot/src/utils.ts
index 6819e67e85f9..254b1e677d59 100644
--- a/packages/jest-snapshot/src/utils.ts
+++ b/packages/jest-snapshot/src/utils.ts
@@ -123,11 +123,19 @@ export const getSnapshotData = (
return {data, dirty};
};
-// Extra line breaks at the beginning and at the end of the snapshot are useful
-// to make the content of the snapshot easier to read
-const addExtraLineBreaks = (string: string): string =>
+// Add extra line breaks at beginning and end of multiline snapshot
+// to make the content easier to read.
+export const addExtraLineBreaks = (string: string): string =>
string.includes('\n') ? `\n${string}\n` : string;
+// Remove extra line breaks at beginning and end of multiline snapshot.
+// Instead of trim, which can remove additional newlines or spaces
+// at beginning or end of the content from a custom serializer.
+export const removeExtraLineBreaks = (string: string): string =>
+ string.length > 2 && string.startsWith('\n') && string.endsWith('\n')
+ ? string.slice(1, -1)
+ : string;
+
export const serialize = (data: string): string =>
addExtraLineBreaks(
normalizeNewlines(