diff --git a/lib/logger/__snapshots__/err-serializer.spec.ts.snap b/lib/logger/__snapshots__/err-serializer.spec.ts.snap
index ce8133fcf296e86c5c2bc5057a72b9b453015da5..3dd9cc3211e6c7811c1727059be495165d746099 100644
--- a/lib/logger/__snapshots__/err-serializer.spec.ts.snap
+++ b/lib/logger/__snapshots__/err-serializer.spec.ts.snap
@@ -1,22 +1,5 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`logger/err-serializer expands errors 1`] = `
-Object {
-  "a": 1,
-  "b": 2,
-  "message": "some message",
-  "options": Object {
-    "headers": Object {
-      "authorization": "Bearer testtoken",
-    },
-  },
-  "response": Object {
-    "body": "some response body",
-    "url": "some/path",
-  },
-}
-`;
-
 exports[`logger/err-serializer got handles http error 1`] = `
 Array [
   Object {
@@ -82,11 +65,3 @@ Object {
   },
 }
 `;
-
-exports[`logger/err-serializer handles missing fields 1`] = `
-Object {
-  "a": 1,
-  "body": "some body",
-  "stack": "foo",
-}
-`;
diff --git a/lib/logger/err-serializer.spec.ts b/lib/logger/err-serializer.spec.ts
index 870deadc2a1c7e1970da626de4f4b590e9a1b05e..df42167ff4e3cd47b2d49c70675c825e02e5ee06 100644
--- a/lib/logger/err-serializer.spec.ts
+++ b/lib/logger/err-serializer.spec.ts
@@ -21,8 +21,20 @@ describe('logger/err-serializer', () => {
         },
       },
     });
-    // FIXME: explicit assert condition
-    expect(errSerializer(err)).toMatchSnapshot();
+    expect(errSerializer(err)).toEqual({
+      a: 1,
+      b: 2,
+      message: 'some message',
+      response: {
+        body: 'some response body',
+        url: 'some/path',
+      },
+      options: {
+        headers: {
+          authorization: 'Bearer testtoken',
+        },
+      },
+    });
   });
   it('handles missing fields', () => {
     const err = partial<Error & Record<string, unknown>>({
@@ -30,8 +42,11 @@ describe('logger/err-serializer', () => {
       stack: 'foo',
       body: 'some body',
     });
-    // FIXME: explicit assert condition
-    expect(errSerializer(err)).toMatchSnapshot();
+    expect(errSerializer(err)).toEqual({
+      a: 1,
+      stack: 'foo',
+      body: 'some body',
+    });
   });
 
   describe('got', () => {
diff --git a/lib/manager/nvm/__snapshots__/extract.spec.ts.snap b/lib/manager/nvm/__snapshots__/extract.spec.ts.snap
deleted file mode 100644
index ad4977d39a410884a8a37cd03cda956a81e6b508..0000000000000000000000000000000000000000
--- a/lib/manager/nvm/__snapshots__/extract.spec.ts.snap
+++ /dev/null
@@ -1,34 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`manager/nvm/extract extractPackageFile() returns a result 1`] = `
-Array [
-  Object {
-    "currentValue": "8.4.0",
-    "datasource": "github-tags",
-    "depName": "node",
-    "lookupName": "nodejs/node",
-  },
-]
-`;
-
-exports[`manager/nvm/extract extractPackageFile() skips non ranges 1`] = `
-Array [
-  Object {
-    "currentValue": "latestn",
-    "datasource": "github-tags",
-    "depName": "node",
-    "lookupName": "nodejs/node",
-  },
-]
-`;
-
-exports[`manager/nvm/extract extractPackageFile() supports ranges 1`] = `
-Array [
-  Object {
-    "currentValue": "8.4",
-    "datasource": "github-tags",
-    "depName": "node",
-    "lookupName": "nodejs/node",
-  },
-]
-`;
diff --git a/lib/manager/nvm/extract.spec.ts b/lib/manager/nvm/extract.spec.ts
index 6cd92c8dbadea17cf7f3b86f1139871b045cb369..01a90ababb9b4222ad7426b8903cefabd8902fa2 100644
--- a/lib/manager/nvm/extract.spec.ts
+++ b/lib/manager/nvm/extract.spec.ts
@@ -4,18 +4,36 @@ describe('manager/nvm/extract', () => {
   describe('extractPackageFile()', () => {
     it('returns a result', () => {
       const res = extractPackageFile('8.4.0\n');
-      // FIXME: explicit assert condition
-      expect(res.deps).toMatchSnapshot();
+      expect(res.deps).toEqual([
+        {
+          currentValue: '8.4.0',
+          datasource: 'github-tags',
+          depName: 'node',
+          lookupName: 'nodejs/node',
+        },
+      ]);
     });
     it('supports ranges', () => {
       const res = extractPackageFile('8.4\n');
-      // FIXME: explicit assert condition
-      expect(res.deps).toMatchSnapshot();
+      expect(res.deps).toEqual([
+        {
+          currentValue: '8.4',
+          datasource: 'github-tags',
+          depName: 'node',
+          lookupName: 'nodejs/node',
+        },
+      ]);
     });
     it('skips non ranges', () => {
       const res = extractPackageFile('latestn');
-      // FIXME: explicit assert condition
-      expect(res.deps).toMatchSnapshot();
+      expect(res.deps).toEqual([
+        {
+          currentValue: 'latestn',
+          datasource: 'github-tags',
+          depName: 'node',
+          lookupName: 'nodejs/node',
+        },
+      ]);
     });
   });
 });
diff --git a/lib/manager/pipenv/extract.spec.ts b/lib/manager/pipenv/extract.spec.ts
index 1e5b711304d6a5e1bf3ac3bfcc35db95a7f5774d..c29ee9823ff715cd9e5ab524cea29e25252b4555 100644
--- a/lib/manager/pipenv/extract.spec.ts
+++ b/lib/manager/pipenv/extract.spec.ts
@@ -18,7 +18,7 @@ describe('manager/pipenv/extract', () => {
       expect(await extractPackageFile('nothing here', 'Pipfile')).toBeNull();
     });
     it('extracts dependencies', async () => {
-      fsutil.localPathExists.mockResolvedValue(true);
+      fsutil.localPathExists.mockResolvedValueOnce(true);
       const res = await extractPackageFile(pipfile1, 'Pipfile');
       expect(res).toMatchSnapshot();
       expect(res.deps).toHaveLength(6);
@@ -30,6 +30,7 @@ describe('manager/pipenv/extract', () => {
       expect(res.deps.filter((r) => r.skipReason)).toHaveLength(6);
     });
     it('extracts multiple dependencies', async () => {
+      fsutil.localPathExists.mockResolvedValueOnce(true);
       const res = await extractPackageFile(pipfile2, 'Pipfile');
       expect(res).toMatchSnapshot();
       expect(res.deps).toHaveLength(5);
@@ -66,11 +67,37 @@ describe('manager/pipenv/extract', () => {
       expect(res.registryUrls).toEqual(['source-url', 'other-source-url']);
     });
     it('extracts example pipfile', async () => {
+      fsutil.localPathExists.mockResolvedValueOnce(true);
       const res = await extractPackageFile(pipfile4, 'Pipfile');
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toMatchSnapshot({
+        constraints: { python: '== 2.7.*' },
+        deps: [
+          { depName: 'requests', skipReason: 'any-version' },
+          {
+            currentValue: '>0.5.0',
+            datasource: 'pypi',
+            depName: 'records',
+            depType: 'packages',
+          },
+          { depName: 'django', skipReason: 'git-dependency' },
+          { depName: 'e682b37', skipReason: 'file-dependency' },
+          { depName: 'e1839a8', skipReason: 'local-dependency' },
+          { depName: 'pywinusb', skipReason: 'any-version' },
+          { currentValue: '*', skipReason: 'any-version' },
+          {
+            currentValue: '>=1.0,<3.0',
+            datasource: 'pypi',
+            depName: 'unittest2',
+            depType: 'dev-packages',
+            managerData: { nestedVersion: true },
+          },
+        ],
+        lockFiles: ['Pipfile.lock'],
+        registryUrls: ['https://pypi.python.org/simple'],
+      });
     });
     it('supports custom index', async () => {
+      fsutil.localPathExists.mockResolvedValueOnce(true);
       const res = await extractPackageFile(pipfile5, 'Pipfile');
       expect(res).toMatchSnapshot();
       expect(res.registryUrls).toBeDefined();
diff --git a/lib/manager/pre-commit/__snapshots__/extract.spec.ts.snap b/lib/manager/pre-commit/__snapshots__/extract.spec.ts.snap
index 4970a455159c1b85cf704184f3efd4ec641d0736..74652734eba2763d86e7a859d51c675c061bb99b 100644
--- a/lib/manager/pre-commit/__snapshots__/extract.spec.ts.snap
+++ b/lib/manager/pre-commit/__snapshots__/extract.spec.ts.snap
@@ -1,56 +1,5 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`manager/pre-commit/extract extractPackageFile() can handle invalid private git repos 1`] = `
-Object {
-  "deps": Array [
-    Object {
-      "currentValue": "v1.0.0",
-      "depName": "pre-commit/pre-commit-hooks",
-      "depType": "repository",
-      "lookupName": "pre-commit/pre-commit-hooks",
-      "registryUrls": Array [
-        "enterprise.com",
-      ],
-      "skipReason": "unknown-registry",
-    },
-  ],
-}
-`;
-
-exports[`manager/pre-commit/extract extractPackageFile() can handle private git repos 1`] = `
-Object {
-  "deps": Array [
-    Object {
-      "currentValue": "v1.0.0",
-      "datasource": "gitlab-tags",
-      "depName": "pre-commit/pre-commit-hooks",
-      "depType": "repository",
-      "lookupName": "pre-commit/pre-commit-hooks",
-      "registryUrls": Array [
-        "enterprise.com",
-      ],
-    },
-  ],
-}
-`;
-
-exports[`manager/pre-commit/extract extractPackageFile() can handle unknown private git repos 1`] = `
-Object {
-  "deps": Array [
-    Object {
-      "currentValue": "v1.0.0",
-      "depName": "pre-commit/pre-commit-hooks",
-      "depType": "repository",
-      "lookupName": "pre-commit/pre-commit-hooks",
-      "registryUrls": Array [
-        "enterprise.com",
-      ],
-      "skipReason": "unknown-registry",
-    },
-  ],
-}
-`;
-
 exports[`manager/pre-commit/extract extractPackageFile() extracts from complex config file correctly 1`] = `
 Object {
   "deps": Array [
@@ -107,24 +56,3 @@ Object {
   ],
 }
 `;
-
-exports[`manager/pre-commit/extract extractPackageFile() extracts from values.yaml correctly with same structure as "pre-commit sample-config" 1`] = `
-Object {
-  "deps": Array [
-    Object {
-      "currentValue": "v2.4.0",
-      "datasource": "github-tags",
-      "depName": "pre-commit/pre-commit-hooks",
-      "depType": "repository",
-      "lookupName": "pre-commit/pre-commit-hooks",
-    },
-    Object {
-      "currentValue": "v2.1.0",
-      "datasource": "github-tags",
-      "depName": "pre-commit/pre-commit-hooks",
-      "depType": "repository",
-      "lookupName": "pre-commit/pre-commit-hooks",
-    },
-  ],
-}
-`;
diff --git a/lib/manager/pre-commit/extract.spec.ts b/lib/manager/pre-commit/extract.spec.ts
index 78dd6eb41c9cebb9fb4986bae98fd19c84d86db9..9be8d8dbc12af41686a51fad84d80c655e253ce1 100644
--- a/lib/manager/pre-commit/extract.spec.ts
+++ b/lib/manager/pre-commit/extract.spec.ts
@@ -50,25 +50,70 @@ describe('manager/pre-commit/extract', () => {
     });
     it('extracts from values.yaml correctly with same structure as "pre-commit sample-config"', () => {
       const result = extractPackageFile(examplePrecommitConfig, filename);
-      // FIXME: explicit assert condition
-      expect(result).toMatchSnapshot();
+      expect(result).toEqual({
+        deps: [
+          {
+            currentValue: 'v2.4.0',
+            datasource: 'github-tags',
+            depName: 'pre-commit/pre-commit-hooks',
+            depType: 'repository',
+            lookupName: 'pre-commit/pre-commit-hooks',
+          },
+          {
+            currentValue: 'v2.1.0',
+            datasource: 'github-tags',
+            depName: 'pre-commit/pre-commit-hooks',
+            depType: 'repository',
+            lookupName: 'pre-commit/pre-commit-hooks',
+          },
+        ],
+      });
     });
     it('extracts from complex config file correctly', () => {
       const result = extractPackageFile(complexPrecommitConfig, filename);
-      // FIXME: explicit assert condition
-      expect(result).toMatchSnapshot();
+      expect(result).toMatchSnapshot({
+        deps: [
+          { depName: 'pre-commit/pre-commit-hooks', currentValue: 'v3.3.0' },
+          { depName: 'psf/black', currentValue: '19.3b0' },
+          { depName: 'psf/black', currentValue: '19.3b0' },
+          { depName: 'psf/black', currentValue: '19.3b0' },
+          { depName: 'prettier/pre-commit', currentValue: 'v2.1.2' },
+          { depName: 'prettier/pre-commit', currentValue: 'v2.1.2' },
+          { skipReason: 'invalid-url' },
+        ],
+      });
     });
     it('can handle private git repos', () => {
       hostRules.find.mockReturnValue({ token: 'value' });
       const result = extractPackageFile(enterpriseGitPrecommitConfig, filename);
-      // FIXME: explicit assert condition
-      expect(result).toMatchSnapshot();
+      expect(result).toEqual({
+        deps: [
+          {
+            currentValue: 'v1.0.0',
+            datasource: 'gitlab-tags',
+            depName: 'pre-commit/pre-commit-hooks',
+            depType: 'repository',
+            lookupName: 'pre-commit/pre-commit-hooks',
+            registryUrls: ['enterprise.com'],
+          },
+        ],
+      });
     });
     it('can handle invalid private git repos', () => {
       hostRules.find.mockReturnValue({});
       const result = extractPackageFile(enterpriseGitPrecommitConfig, filename);
-      // FIXME: explicit assert condition
-      expect(result).toMatchSnapshot();
+      expect(result).toEqual({
+        deps: [
+          {
+            currentValue: 'v1.0.0',
+            depName: 'pre-commit/pre-commit-hooks',
+            depType: 'repository',
+            lookupName: 'pre-commit/pre-commit-hooks',
+            registryUrls: ['enterprise.com'],
+            skipReason: 'unknown-registry',
+          },
+        ],
+      });
     });
     it('can handle unknown private git repos', () => {
       // First attemp returns a result
@@ -76,8 +121,18 @@ describe('manager/pre-commit/extract', () => {
       // But all subsequent checks (those with hostType), then fail:
       hostRules.find.mockReturnValue({});
       const result = extractPackageFile(enterpriseGitPrecommitConfig, filename);
-      // FIXME: explicit assert condition
-      expect(result).toMatchSnapshot();
+      expect(result).toEqual({
+        deps: [
+          {
+            currentValue: 'v1.0.0',
+            depName: 'pre-commit/pre-commit-hooks',
+            depType: 'repository',
+            lookupName: 'pre-commit/pre-commit-hooks',
+            registryUrls: ['enterprise.com'],
+            skipReason: 'unknown-registry',
+          },
+        ],
+      });
     });
   });
 });
diff --git a/lib/manager/pub/__snapshots__/extract.spec.ts.snap b/lib/manager/pub/__snapshots__/extract.spec.ts.snap
deleted file mode 100644
index 92b9235505a8f19028c3d07f27262f0a58ae90bc..0000000000000000000000000000000000000000
--- a/lib/manager/pub/__snapshots__/extract.spec.ts.snap
+++ /dev/null
@@ -1,40 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`manager/pub/extract extractPackageFile should return valid dependencies 1`] = `
-Object {
-  "datasource": "dart",
-  "deps": Array [
-    Object {
-      "currentValue": "1",
-      "depName": "foo",
-      "depType": "dependencies",
-    },
-    Object {
-      "currentValue": "1",
-      "depName": "bar",
-      "depType": "dependencies",
-    },
-    Object {
-      "currentValue": null,
-      "depName": "baz",
-      "depType": "dependencies",
-    },
-    Object {
-      "currentValue": null,
-      "depName": "qux",
-      "depType": "dependencies",
-    },
-    Object {
-      "currentValue": "^0.1",
-      "depName": "test",
-      "depType": "dev_dependencies",
-    },
-    Object {
-      "currentValue": "0.1",
-      "depName": "build",
-      "depType": "dev_dependencies",
-    },
-  ],
-  "packageFile": "pubspec.yaml",
-}
-`;
diff --git a/lib/manager/pub/extract.spec.ts b/lib/manager/pub/extract.spec.ts
index 7af68440e3fb83fa19382ea09da971484af303bf..abcb0b9a9c6b2ba5928becb467301637c253f153 100644
--- a/lib/manager/pub/extract.spec.ts
+++ b/lib/manager/pub/extract.spec.ts
@@ -16,8 +16,26 @@ describe('manager/pub/extract', () => {
     });
     it('should return valid dependencies', () => {
       const res = extractPackageFile(packageFile, 'pubspec.yaml');
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toEqual({
+        datasource: 'dart',
+        deps: [
+          { currentValue: '1', depName: 'foo', depType: 'dependencies' },
+          { currentValue: '1', depName: 'bar', depType: 'dependencies' },
+          { currentValue: null, depName: 'baz', depType: 'dependencies' },
+          { currentValue: null, depName: 'qux', depType: 'dependencies' },
+          {
+            currentValue: '^0.1',
+            depName: 'test',
+            depType: 'dev_dependencies',
+          },
+          {
+            currentValue: '0.1',
+            depName: 'build',
+            depType: 'dev_dependencies',
+          },
+        ],
+        packageFile: 'pubspec.yaml',
+      });
     });
   });
 });
diff --git a/lib/manager/pyenv/__snapshots__/extract.spec.ts.snap b/lib/manager/pyenv/__snapshots__/extract.spec.ts.snap
deleted file mode 100644
index a81be83ad9211c91ce2d97a37440462413bd1250..0000000000000000000000000000000000000000
--- a/lib/manager/pyenv/__snapshots__/extract.spec.ts.snap
+++ /dev/null
@@ -1,31 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`manager/pyenv/extract extractPackageFile() returns a result 1`] = `
-Array [
-  Object {
-    "currentValue": "3.7.1",
-    "datasource": "docker",
-    "depName": "python",
-  },
-]
-`;
-
-exports[`manager/pyenv/extract extractPackageFile() skips non ranges 1`] = `
-Array [
-  Object {
-    "currentValue": "latestn",
-    "datasource": "docker",
-    "depName": "python",
-  },
-]
-`;
-
-exports[`manager/pyenv/extract extractPackageFile() supports ranges 1`] = `
-Array [
-  Object {
-    "currentValue": "3.8",
-    "datasource": "docker",
-    "depName": "python",
-  },
-]
-`;
diff --git a/lib/manager/pyenv/extract.spec.ts b/lib/manager/pyenv/extract.spec.ts
index 1131abc0ece3b898c6564c504dfc26923ce216b4..f25eb5634343c0a5b9c1b698307ca8daf3d174e0 100644
--- a/lib/manager/pyenv/extract.spec.ts
+++ b/lib/manager/pyenv/extract.spec.ts
@@ -4,18 +4,21 @@ describe('manager/pyenv/extract', () => {
   describe('extractPackageFile()', () => {
     it('returns a result', () => {
       const res = extractPackageFile('3.7.1\n');
-      // FIXME: explicit assert condition
-      expect(res.deps).toMatchSnapshot();
+      expect(res.deps).toEqual([
+        { depName: 'python', currentValue: '3.7.1', datasource: 'docker' },
+      ]);
     });
     it('supports ranges', () => {
       const res = extractPackageFile('3.8\n');
-      // FIXME: explicit assert condition
-      expect(res.deps).toMatchSnapshot();
+      expect(res.deps).toEqual([
+        { depName: 'python', currentValue: '3.8', datasource: 'docker' },
+      ]);
     });
     it('skips non ranges', () => {
       const res = extractPackageFile('latestn');
-      // FIXME: explicit assert condition
-      expect(res.deps).toMatchSnapshot();
+      expect(res.deps).toEqual([
+        { depName: 'python', currentValue: 'latestn', datasource: 'docker' },
+      ]);
     });
   });
 });
diff --git a/lib/manager/regex/index.spec.ts b/lib/manager/regex/index.spec.ts
index 480af832794e1135d0b4b9a01891645a7234bbbe..78c651f43a25d88419569c42485350c9cf6661ca 100644
--- a/lib/manager/regex/index.spec.ts
+++ b/lib/manager/regex/index.spec.ts
@@ -106,8 +106,16 @@ describe('manager/regex/index', () => {
       'Dockerfile',
       config
     );
-    // FIXME: explicit assert condition
-    expect(res).toMatchSnapshot();
+    expect(res).toMatchSnapshot({
+      deps: [
+        {
+          currentValue: '8.12.13',
+          datasource: 'helm',
+          depName: 'prometheus-operator',
+          registryUrls: ['https://charts.helm.sh/stable'],
+        },
+      ],
+    });
   });
   it('extracts and applies a registryUrlTemplate', async () => {
     const config = {
@@ -140,8 +148,16 @@ describe('manager/regex/index', () => {
       'Dockerfile',
       config
     );
-    // FIXME: explicit assert condition
-    expect(res).toMatchSnapshot();
+    expect(res).toMatchSnapshot({
+      deps: [
+        {
+          currentValue: '6.2',
+          datasource: 'gradle-version',
+          depName: 'gradle',
+          versioning: 'maven',
+        },
+      ],
+    });
     expect(logger.warn).toHaveBeenCalledWith(
       { value: 'this-is-not-a-valid-url-gradle' },
       'Invalid regex manager registryUrl'
diff --git a/lib/manager/ruby-version/__snapshots__/extract.spec.ts.snap b/lib/manager/ruby-version/__snapshots__/extract.spec.ts.snap
deleted file mode 100644
index 99f5dec244bfac9ac7f95199e07a2819553e81ca..0000000000000000000000000000000000000000
--- a/lib/manager/ruby-version/__snapshots__/extract.spec.ts.snap
+++ /dev/null
@@ -1,31 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`manager/ruby-version/extract extractPackageFile() returns a result 1`] = `
-Array [
-  Object {
-    "currentValue": "8.4.0",
-    "datasource": "ruby-version",
-    "depName": "ruby",
-  },
-]
-`;
-
-exports[`manager/ruby-version/extract extractPackageFile() skips non ranges 1`] = `
-Array [
-  Object {
-    "currentValue": "latestn",
-    "datasource": "ruby-version",
-    "depName": "ruby",
-  },
-]
-`;
-
-exports[`manager/ruby-version/extract extractPackageFile() supports ranges 1`] = `
-Array [
-  Object {
-    "currentValue": "8.4",
-    "datasource": "ruby-version",
-    "depName": "ruby",
-  },
-]
-`;
diff --git a/lib/manager/ruby-version/extract.spec.ts b/lib/manager/ruby-version/extract.spec.ts
index dbec0235de46109487f6eea4ea00c3739cde5329..74245981e5be5fe4b569751878a9a7c49c4d3baf 100644
--- a/lib/manager/ruby-version/extract.spec.ts
+++ b/lib/manager/ruby-version/extract.spec.ts
@@ -4,18 +4,33 @@ describe('manager/ruby-version/extract', () => {
   describe('extractPackageFile()', () => {
     it('returns a result', () => {
       const res = extractPackageFile('8.4.0\n');
-      // FIXME: explicit assert condition
-      expect(res.deps).toMatchSnapshot();
+      expect(res.deps).toEqual([
+        {
+          currentValue: '8.4.0',
+          datasource: 'ruby-version',
+          depName: 'ruby',
+        },
+      ]);
     });
     it('supports ranges', () => {
       const res = extractPackageFile('8.4\n');
-      // FIXME: explicit assert condition
-      expect(res.deps).toMatchSnapshot();
+      expect(res.deps).toEqual([
+        {
+          currentValue: '8.4',
+          datasource: 'ruby-version',
+          depName: 'ruby',
+        },
+      ]);
     });
     it('skips non ranges', () => {
       const res = extractPackageFile('latestn');
-      // FIXME: explicit assert condition
-      expect(res.deps).toMatchSnapshot();
+      expect(res.deps).toEqual([
+        {
+          currentValue: 'latestn',
+          datasource: 'ruby-version',
+          depName: 'ruby',
+        },
+      ]);
     });
   });
 });
diff --git a/lib/manager/sbt/__snapshots__/extract.spec.ts.snap b/lib/manager/sbt/__snapshots__/extract.spec.ts.snap
index 38bb61b805732a27f9c1371a158be64412f12272..6ef285b041f564e351638afbbc211904d6c2be87 100644
--- a/lib/manager/sbt/__snapshots__/extract.spec.ts.snap
+++ b/lib/manager/sbt/__snapshots__/extract.spec.ts.snap
@@ -471,32 +471,3 @@ Object {
   "packageFileVersion": undefined,
 }
 `;
-
-exports[`manager/sbt/extract extractPackageFile() skips deps when scala version is missing 1`] = `
-Object {
-  "deps": Array [
-    Object {
-      "currentValue": "3.0.0",
-      "datasource": "sbt-package",
-      "depName": "org.scalatest:scalatest",
-      "lookupName": "org.scalatest:scalatest",
-      "registryUrls": Array [
-        "https://repo.maven.apache.org/maven2",
-      ],
-    },
-    Object {
-      "currentValue": "1.0.11",
-      "datasource": "sbt-plugin",
-      "depName": "com.github.gseitz:sbt-release",
-      "depType": "plugin",
-      "groupName": "sbtReleaseVersion for com.github.gseitz",
-      "lookupName": "com.github.gseitz:sbt-release",
-      "registryUrls": Array [
-        "https://repo.maven.apache.org/maven2",
-        "https://dl.bintray.com/sbt/sbt-plugin-releases",
-      ],
-    },
-  ],
-  "packageFileVersion": "1.0.1",
-}
-`;
diff --git a/lib/manager/sbt/__snapshots__/update.spec.ts.snap b/lib/manager/sbt/__snapshots__/update.spec.ts.snap
deleted file mode 100644
index 80a2cea3664d379acee55fe2ab0c4d83e9cfdd2e..0000000000000000000000000000000000000000
--- a/lib/manager/sbt/__snapshots__/update.spec.ts.snap
+++ /dev/null
@@ -1,15 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`manager/sbt/update .bumpPackageVersion() increments 1`] = `
-"name := \\"test\\"
-organization := \\"test-org\\"
-version := \\"0.0.3\\"
-"
-`;
-
-exports[`manager/sbt/update .bumpPackageVersion() updates 1`] = `
-"name := \\"test\\"
-organization := \\"test-org\\"
-version := \\"0.1.0\\"
-"
-`;
diff --git a/lib/manager/sbt/extract.spec.ts b/lib/manager/sbt/extract.spec.ts
index 0c5d436bad9ea4b05188a4d4512e7dd3ab039ddf..3ec5df24960ec27ba8e7d3d0861efdf73c120af7 100644
--- a/lib/manager/sbt/extract.spec.ts
+++ b/lib/manager/sbt/extract.spec.ts
@@ -37,20 +37,90 @@ describe('manager/sbt/extract', () => {
       ).toBeNull();
     });
     it('extracts deps for generic use-cases', () => {
-      // FIXME: explicit assert condition
-      expect(extractPackageFile(sbt)).toMatchSnapshot();
+      expect(extractPackageFile(sbt)).toMatchSnapshot({
+        deps: [
+          {
+            lookupName: 'org.scala-lang:scala-library',
+            currentValue: '2.9.10',
+          },
+          { lookupName: 'org.example:foo', currentValue: '0.0.1' },
+          { lookupName: 'org.example:bar_2.9.10', currentValue: '0.0.2' },
+          { lookupName: 'org.example:baz_2.9.10', currentValue: '0.0.3' },
+          { lookupName: 'org.example:qux', currentValue: '0.0.4' },
+          {
+            lookupName: 'org.scala-lang:scala-library',
+            currentValue: '2.13.3',
+          },
+          { lookupName: 'org.example:quux', currentValue: '0.0.5' },
+          { lookupName: 'org.example:quuz_2.9.10', currentValue: '0.0.6' },
+          { lookupName: 'org.example:corge', currentValue: '0.0.7' },
+          { lookupName: 'org.example:grault', currentValue: '0.0.8' },
+          { lookupName: 'org.example:waldo', currentValue: '0.0.9' },
+          { lookupName: 'org.example:fred', currentValue: '(,8.4.0]' },
+        ],
+        packageFileVersion: '1.0',
+      });
     });
     it('extracts deps when scala version is defined in a variable', () => {
-      // FIXME: explicit assert condition
-      expect(extractPackageFile(sbtScalaVersionVariable)).toMatchSnapshot();
+      expect(extractPackageFile(sbtScalaVersionVariable)).toMatchSnapshot({
+        deps: [
+          { lookupName: 'org.example:foo', currentValue: '0.0.1' },
+          { lookupName: 'org.example:bar_2.12', currentValue: '0.0.2' },
+          { lookupName: 'org.example:baz_2.12', currentValue: '0.0.3' },
+          { lookupName: 'org.example:qux', currentValue: '0.0.4' },
+          { lookupName: 'org.example:quux', currentValue: '0.0.5' },
+          { lookupName: 'org.example:quuz_2.12', currentValue: '0.0.6' },
+          { lookupName: 'org.example:corge', currentValue: '0.0.7' },
+          { lookupName: 'org.example:grault', currentValue: '0.0.8' },
+          { lookupName: 'org.example:waldo', currentValue: '0.0.9' },
+        ],
+
+        packageFileVersion: '3.2.1',
+      });
     });
     it('skips deps when scala version is missing', () => {
-      // FIXME: explicit assert condition
-      expect(extractPackageFile(sbtMissingScalaVersion)).toMatchSnapshot();
+      expect(extractPackageFile(sbtMissingScalaVersion)).toEqual({
+        deps: [
+          {
+            currentValue: '3.0.0',
+            datasource: 'sbt-package',
+            depName: 'org.scalatest:scalatest',
+            lookupName: 'org.scalatest:scalatest',
+            registryUrls: ['https://repo.maven.apache.org/maven2'],
+          },
+          {
+            currentValue: '1.0.11',
+            datasource: 'sbt-plugin',
+            depName: 'com.github.gseitz:sbt-release',
+            depType: 'plugin',
+            groupName: 'sbtReleaseVersion for com.github.gseitz',
+            lookupName: 'com.github.gseitz:sbt-release',
+            registryUrls: [
+              'https://repo.maven.apache.org/maven2',
+              'https://dl.bintray.com/sbt/sbt-plugin-releases',
+            ],
+          },
+        ],
+        packageFileVersion: '1.0.1',
+      });
     });
     it('extract deps from native scala file with variables', () => {
-      // FIXME: explicit assert condition
-      expect(extractPackageFile(sbtDependencyFile)).toMatchSnapshot();
+      expect(extractPackageFile(sbtDependencyFile)).toMatchSnapshot({
+        deps: [
+          {
+            lookupName: 'org.scala-lang:scala-library',
+            currentValue: '2.13.0-RC5',
+          },
+          {
+            lookupName: 'com.example:foo_2.13.0-RC5',
+            currentValue: '0.7.1',
+          },
+          { lookupName: 'com.abc:abc', currentValue: '1.2.3' },
+          { lookupName: 'com.abc:abc-a', currentValue: '1.2.3' },
+          { lookupName: 'com.abc:abc-b', currentValue: '1.2.3' },
+          { lookupName: 'com.abc:abc-c', currentValue: '1.2.3' },
+        ],
+      });
     });
     it('extracts deps when scala version is defined with a trailing comma', () => {
       const content = `
@@ -59,8 +129,18 @@ describe('manager/sbt/extract', () => {
         )
         libraryDependencies += "org.example" %% "bar" % "0.0.2"
       `;
-      // FIXME: explicit assert condition
-      expect(extractPackageFile(content)).toMatchSnapshot();
+      expect(extractPackageFile(content)).toMatchSnapshot({
+        deps: [
+          {
+            lookupName: 'org.scala-lang:scala-library',
+            currentValue: '2.12.10',
+          },
+          {
+            lookupName: 'org.example:bar_2.12',
+            currentValue: '0.0.2',
+          },
+        ],
+      });
     });
     it('extracts deps when scala version is defined in a variable with a trailing comma', () => {
       const content = `
@@ -70,14 +150,30 @@ describe('manager/sbt/extract', () => {
         )
         libraryDependencies += "org.example" %% "bar" % "0.0.2"
       `;
-      // FIXME: explicit assert condition
-      expect(extractPackageFile(content)).toMatchSnapshot();
+      expect(extractPackageFile(content)).toMatchSnapshot({
+        deps: [{ lookupName: 'org.example:bar_2.12', currentValue: '0.0.2' }],
+      });
     });
     it('extract deps from native scala file with private variables', () => {
-      // FIXME: explicit assert condition
       expect(
         extractPackageFile(sbtPrivateVariableDependencyFile)
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        deps: [
+          {
+            lookupName: 'org.scala-lang:scala-library',
+            currentValue: '2.13.0-RC5',
+          },
+          {
+            lookupName: 'com.example:foo_2.13.0-RC5',
+            currentValue: '0.7.1',
+          },
+          {
+            lookupName: 'com.abc:abc',
+            currentValue: '1.2.3',
+          },
+        ],
+        packageFileVersion: undefined,
+      });
     });
   });
 });
diff --git a/lib/manager/sbt/update.spec.ts b/lib/manager/sbt/update.spec.ts
index c23e93fbfc4d45326f8a2f9ae8de418ba47040c9..7cc52c8255b5a58561f70d0ce4edd2548625ca01 100644
--- a/lib/manager/sbt/update.spec.ts
+++ b/lib/manager/sbt/update.spec.ts
@@ -14,8 +14,7 @@ describe('manager/sbt/update', () => {
         'patch'
       );
 
-      // FIXME: explicit assert condition
-      expect(bumpedContent).toMatchSnapshot();
+      expect(bumpedContent).toEqual(content.replace('0.0.2', '0.0.3'));
       expect(bumpedContent).not.toEqual(content);
     });
     it('no ops', () => {
@@ -33,8 +32,7 @@ describe('manager/sbt/update', () => {
         '0.0.1',
         'minor'
       );
-      // FIXME: explicit assert condition
-      expect(bumpedContent).toMatchSnapshot();
+      expect(bumpedContent).toEqual(content.replace('0.0.2', '0.1.0'));
       expect(bumpedContent).not.toEqual(content);
     });
     it('returns content if bumping errors', () => {
diff --git a/lib/manager/setup-cfg/extract.spec.ts b/lib/manager/setup-cfg/extract.spec.ts
index d7978e6a20fb81117d38ab1f83be631e27996d53..5a4d54a0325e031de4f220b2a21517e68ad10bbc 100644
--- a/lib/manager/setup-cfg/extract.spec.ts
+++ b/lib/manager/setup-cfg/extract.spec.ts
@@ -10,8 +10,36 @@ describe('manager/setup-cfg/extract', () => {
     });
     it('extracts dependencies', () => {
       const res = extractPackageFile(content);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toMatchSnapshot({
+        deps: [
+          { depName: 'qux', currentValue: '>=4.4.4' },
+          { depName: 'coloredlogs', currentValue: '~=14.0' },
+          { depName: 'python-dateutil', currentValue: '~=2.1' },
+          { depName: 'docopt', currentValue: '~=0.4' },
+          { depName: 'fs', currentValue: '~=2.1' },
+          { depName: 'requests', currentValue: '~=2.18' },
+          { depName: 'six', currentValue: '~=1.4' },
+          { depName: 'tqdm', currentValue: '~=4.19' },
+          { depName: 'tenacity', currentValue: '~=6.0' },
+          { depName: 'typing', currentValue: '~=3.6' },
+          { depName: 'verboselogs', currentValue: '~=1.7' },
+          { depName: 'contexter', currentValue: '~=0.1' },
+          { depName: 'mock', currentValue: '~=2.0' },
+          { depName: 'parameterized', currentValue: '~=0.6' },
+          { depName: 'green', currentValue: '~=2.12' },
+          { depName: 'sphinx', currentValue: '~=1.7' },
+          { depName: 'sphinx-bootstrap-theme', currentValue: '~=0.6' },
+          { depName: 'semantic-version', currentValue: '~=2.6' },
+          { depName: 'aiortc', currentValue: '>=0.9' },
+          { depName: 'websockets', currentValue: '>=8.1' },
+          { depName: 'aiohttp', currentValue: '>=3.6' },
+          { depName: 'pyee', currentValue: '>=6.0' },
+          { depName: 'websockets', currentValue: '>=8.1' },
+          { depName: 'dataclasses_json', currentValue: '>=0.3' },
+          { depName: 'coloredlogs', currentValue: '>=10.0' },
+          { depName: 'av', currentValue: '~=8.0.0' },
+        ],
+      });
     });
   });
 });
diff --git a/lib/manager/terraform-version/__snapshots__/extract.spec.ts.snap b/lib/manager/terraform-version/__snapshots__/extract.spec.ts.snap
deleted file mode 100644
index 364e18dfac9cf0249075b3c6939866c570147ba9..0000000000000000000000000000000000000000
--- a/lib/manager/terraform-version/__snapshots__/extract.spec.ts.snap
+++ /dev/null
@@ -1,21 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`manager/terraform-version/extract extractPackageFile() returns a result 1`] = `
-Array [
-  Object {
-    "currentValue": "12.0.0",
-    "datasource": "github-releases",
-    "depName": "hashicorp/terraform",
-  },
-]
-`;
-
-exports[`manager/terraform-version/extract extractPackageFile() skips non ranges 1`] = `
-Array [
-  Object {
-    "currentValue": "latest",
-    "datasource": "github-releases",
-    "depName": "hashicorp/terraform",
-  },
-]
-`;
diff --git a/lib/manager/terraform-version/extract.spec.ts b/lib/manager/terraform-version/extract.spec.ts
index 7bc0d51f2cfe5f4afbc63ab0e29da04591b9a609..cf86670bd34d7cb5a3a5a1179f8cf90f131e3842 100644
--- a/lib/manager/terraform-version/extract.spec.ts
+++ b/lib/manager/terraform-version/extract.spec.ts
@@ -4,13 +4,27 @@ describe('manager/terraform-version/extract', () => {
   describe('extractPackageFile()', () => {
     it('returns a result', () => {
       const res = extractPackageFile('12.0.0\n');
-      // FIXME: explicit assert condition
-      expect(res.deps).toMatchSnapshot();
+      expect(res).toEqual({
+        deps: [
+          {
+            depName: 'hashicorp/terraform',
+            currentValue: '12.0.0',
+            datasource: 'github-releases',
+          },
+        ],
+      });
     });
     it('skips non ranges', () => {
       const res = extractPackageFile('latest');
-      // FIXME: explicit assert condition
-      expect(res.deps).toMatchSnapshot();
+      expect(res).toEqual({
+        deps: [
+          {
+            depName: 'hashicorp/terraform',
+            currentValue: 'latest',
+            datasource: 'github-releases',
+          },
+        ],
+      });
     });
   });
 });
diff --git a/lib/manager/terragrunt-version/__snapshots__/extract.spec.ts.snap b/lib/manager/terragrunt-version/__snapshots__/extract.spec.ts.snap
deleted file mode 100644
index ccbcee586c813adfe9a2f57e8b98595bf4a93385..0000000000000000000000000000000000000000
--- a/lib/manager/terragrunt-version/__snapshots__/extract.spec.ts.snap
+++ /dev/null
@@ -1,11 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`manager/terragrunt-version/extract extractPackageFile() returns a result 1`] = `
-Array [
-  Object {
-    "currentValue": "12.0.0",
-    "datasource": "github-releases",
-    "depName": "gruntwork-io/terragrunt",
-  },
-]
-`;
diff --git a/lib/manager/terragrunt-version/extract.spec.ts b/lib/manager/terragrunt-version/extract.spec.ts
index ee1e62e8ace65c8006ec66ea7324b4c30cb79a75..00fafd302a23c9d04641cae249029ad33cf35bf2 100644
--- a/lib/manager/terragrunt-version/extract.spec.ts
+++ b/lib/manager/terragrunt-version/extract.spec.ts
@@ -4,8 +4,13 @@ describe('manager/terragrunt-version/extract', () => {
   describe('extractPackageFile()', () => {
     it('returns a result', () => {
       const res = extractPackageFile('12.0.0\n');
-      // FIXME: explicit assert condition
-      expect(res.deps).toMatchSnapshot();
+      expect(res.deps).toEqual([
+        {
+          depName: 'gruntwork-io/terragrunt',
+          currentValue: '12.0.0',
+          datasource: 'github-releases',
+        },
+      ]);
     });
   });
 });
diff --git a/lib/versioning/__snapshots__/index.spec.ts.snap b/lib/versioning/__snapshots__/index.spec.ts.snap
deleted file mode 100644
index 475eeaec6909c7f494ad84f4e50da939fe82a3e8..0000000000000000000000000000000000000000
--- a/lib/versioning/__snapshots__/index.spec.ts.snap
+++ /dev/null
@@ -1,22 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`versioning/index has api 1`] = `
-Array [
-  "equals",
-  "getMajor",
-  "getMinor",
-  "getNewValue",
-  "getPatch",
-  "getSatisfyingVersion",
-  "isCompatible",
-  "isGreaterThan",
-  "isLessThanRange",
-  "isSingleVersion",
-  "isStable",
-  "isValid",
-  "isVersion",
-  "matches",
-  "minSatisfyingVersion",
-  "sortVersions",
-]
-`;
diff --git a/lib/versioning/index.spec.ts b/lib/versioning/index.spec.ts
index da1137ccac1e0a5dcb4bed007fb4eb29ad6272c1..d6f118aa7ecbf951d4327b2e2e512399a508953d 100644
--- a/lib/versioning/index.spec.ts
+++ b/lib/versioning/index.spec.ts
@@ -12,8 +12,24 @@ const supportedSchemes = getOptions().find(
 
 describe('versioning/index', () => {
   it('has api', () => {
-    // FIXME: explicit assert condition
-    expect(Object.keys(allVersioning.get('semver')).sort()).toMatchSnapshot();
+    expect(Object.keys(allVersioning.get('semver')).sort()).toEqual([
+      'equals',
+      'getMajor',
+      'getMinor',
+      'getNewValue',
+      'getPatch',
+      'getSatisfyingVersion',
+      'isCompatible',
+      'isGreaterThan',
+      'isLessThanRange',
+      'isSingleVersion',
+      'isStable',
+      'isValid',
+      'isVersion',
+      'matches',
+      'minSatisfyingVersion',
+      'sortVersions',
+    ]);
   });
   it('validates', () => {
     function validate(
diff --git a/lib/versioning/loose/__snapshots__/utils.spec.ts.snap b/lib/versioning/loose/__snapshots__/utils.spec.ts.snap
deleted file mode 100644
index 9113e49e812375e2f49504ddacdead00cd81d1b8..0000000000000000000000000000000000000000
--- a/lib/versioning/loose/__snapshots__/utils.spec.ts.snap
+++ /dev/null
@@ -1,27 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`versioning/loose/utils GenericVersioningApi equals 1`] = `true`;
-
-exports[`versioning/loose/utils GenericVersioningApi getMajor 1`] = `1`;
-
-exports[`versioning/loose/utils GenericVersioningApi getMinor 1`] = `0`;
-
-exports[`versioning/loose/utils GenericVersioningApi getNewValue 1`] = `undefined`;
-
-exports[`versioning/loose/utils GenericVersioningApi getPatch 1`] = `0`;
-
-exports[`versioning/loose/utils GenericVersioningApi isCompatible 1`] = `true`;
-
-exports[`versioning/loose/utils GenericVersioningApi isGreaterThan 1`] = `false`;
-
-exports[`versioning/loose/utils GenericVersioningApi isSingleVersion 1`] = `true`;
-
-exports[`versioning/loose/utils GenericVersioningApi isStable 1`] = `true`;
-
-exports[`versioning/loose/utils GenericVersioningApi isValid 1`] = `true`;
-
-exports[`versioning/loose/utils GenericVersioningApi isVersion 1`] = `true`;
-
-exports[`versioning/loose/utils GenericVersioningApi matches 1`] = `true`;
-
-exports[`versioning/loose/utils GenericVersioningApi sortVersions 1`] = `0`;
diff --git a/lib/versioning/loose/utils.spec.ts b/lib/versioning/loose/utils.spec.ts
index 4b503762d0c9983272a01a5b6cc0e126164aaa18..bfaa7cc66dd341a695208690833f1a2ac7f3fdc8 100644
--- a/lib/versioning/loose/utils.spec.ts
+++ b/lib/versioning/loose/utils.spec.ts
@@ -40,19 +40,52 @@ describe('versioning/loose/utils', () => {
     }
 
     const api = new DummyScheme();
-    const schemeKeys = getAllPropertyNames(api)
-      .filter((val) => !optionalFunctions.includes(val) && !val.startsWith('_'))
-      .filter(
-        (val) => !['minSatisfyingVersion', 'getSatisfyingVersion'].includes(val)
-      )
-      .sort();
 
-    for (const key of schemeKeys) {
-      it(`${key}`, () => {
-        // FIXME: explicit assert condition
-        expect(api[key]()).toMatchSnapshot();
-      });
-    }
+    it('Scheme keys', () => {
+      const schemeKeys = getAllPropertyNames(api)
+        .filter(
+          (val) => !optionalFunctions.includes(val) && !val.startsWith('_')
+        )
+        .filter(
+          (val) =>
+            !['minSatisfyingVersion', 'getSatisfyingVersion'].includes(val)
+        )
+        .sort();
+      expect(schemeKeys).toEqual([
+        'equals',
+        'getMajor',
+        'getMinor',
+        'getNewValue',
+        'getPatch',
+        'isCompatible',
+        'isGreaterThan',
+        'isSingleVersion',
+        'isStable',
+        'isValid',
+        'isVersion',
+        'matches',
+        'sortVersions',
+      ]);
+    });
+
+    test.each`
+      fn                   | expected
+      ${'equals'}          | ${true}
+      ${'getMajor'}        | ${1}
+      ${'getMinor'}        | ${0}
+      ${'getNewValue'}     | ${undefined}
+      ${'getPatch'}        | ${0}
+      ${'isCompatible'}    | ${true}
+      ${'isGreaterThan'}   | ${false}
+      ${'isSingleVersion'} | ${true}
+      ${'isStable'}        | ${true}
+      ${'isValid'}         | ${true}
+      ${'isVersion'}       | ${true}
+      ${'matches'}         | ${true}
+      ${'sortVersions'}    | ${0}
+    `('$fn', ({ fn, expected }) => {
+      expect(api[fn]()).toBe(expected);
+    });
 
     it('getMajor is null', () => {
       expect(api.getMajor('test')).toBeNull();
diff --git a/lib/workers/branch/__snapshots__/auto-replace.spec.ts.snap b/lib/workers/branch/__snapshots__/auto-replace.spec.ts.snap
deleted file mode 100644
index ee040deb4527e594152d91d8d795a1c0715d5815..0000000000000000000000000000000000000000
--- a/lib/workers/branch/__snapshots__/auto-replace.spec.ts.snap
+++ /dev/null
@@ -1,11 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`workers/branch/auto-replace doAutoReplace handles a double attempt 1`] = `"     <script src=\\"https://cdnjs.cloudflare.com/ajax/libs/reactstrap/7.1.0/reactstrap.min.js\\">  <script src=\\"https://cdnjs.cloudflare.com/ajax/libs/reactstrap/7.1.1/reactstrap.min.js\\"> "`;
-
-exports[`workers/branch/auto-replace doAutoReplace handles already updated 1`] = `"     <script src=\\"https://cdnjs.cloudflare.com/ajax/libs/reactstrap/7.1.1/reactstrap.min.js\\">   "`;
-
-exports[`workers/branch/auto-replace doAutoReplace updates version and integrity 1`] = `"     <script src=\\"https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min.js\\" integrity=\\"sha256-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\" crossorigin=\\"anonymous\\">   "`;
-
-exports[`workers/branch/auto-replace doAutoReplace updates version only 1`] = `"     <script src=\\"https://cdnjs.cloudflare.com/ajax/libs/reactstrap/7.1.1/reactstrap.min.js\\">   "`;
-
-exports[`workers/branch/auto-replace doAutoReplace updates with autoReplaceNewString 1`] = `"FROM node:8.11.4-alpine@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa AS node"`;
diff --git a/lib/workers/branch/auto-replace.spec.ts b/lib/workers/branch/auto-replace.spec.ts
index e89415f4dd6dfce07225bbb66df3b56e17188bd8..10a3df60a6cdce8db07c8a48503fb10b6a5ca8d9 100644
--- a/lib/workers/branch/auto-replace.spec.ts
+++ b/lib/workers/branch/auto-replace.spec.ts
@@ -48,8 +48,7 @@ describe('workers/branch/auto-replace', () => {
       upgrade.newDigest = 'some-digest';
       upgrade.depIndex = 0;
       const res = await doAutoReplace(upgrade, src, reuseExistingBranch);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toEqual(src.replace('7.1.0', '7.1.1'));
     });
     it('handles a double attempt', async () => {
       const script =
@@ -62,8 +61,9 @@ describe('workers/branch/auto-replace', () => {
       upgrade.newValue = '7.1.1';
       upgrade.depIndex = 1;
       const res = await doAutoReplace(upgrade, src, reuseExistingBranch);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toEqual(
+        `     ${script}  ${script.replace('7.1.0', '7.1.1')} `
+      );
     });
     it('handles already updated', async () => {
       const script =
@@ -83,8 +83,7 @@ describe('workers/branch/auto-replace', () => {
         srcAlreadyUpdated,
         reuseExistingBranch
       );
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toEqual(srcAlreadyUpdated);
     });
     it('returns existing content if replaceString mismatch', async () => {
       const script =
@@ -102,14 +101,12 @@ describe('workers/branch/auto-replace', () => {
         'wrong source',
         reuseExistingBranch
       );
-      // FIXME: explicit assert condition
       expect(res).toBe('wrong source');
     });
     it('updates version and integrity', async () => {
       const script =
         '<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.10.0/katex.min.js" integrity="sha384-K3vbOmF2BtaVai+Qk37uypf7VrgBubhQreNQe9aGsz9lB63dIFiQVlJbr92dw2Lx" crossorigin="anonymous">';
-      const src = `     ${script}   `;
-      upgrade.baseDeps = extractPackageFile(src).deps;
+      upgrade.baseDeps = extractPackageFile(script).deps;
       upgrade.depName = 'KaTeX';
       upgrade.lookupName = 'KaTeX/0.10.0/katex.min.js';
       upgrade.currentValue = '0.10.0';
@@ -119,9 +116,10 @@ describe('workers/branch/auto-replace', () => {
       upgrade.newDigest = 'sha256-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
       upgrade.depIndex = 0;
       upgrade.replaceString = script;
-      const res = await doAutoReplace(upgrade, src, reuseExistingBranch);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      const res = await doAutoReplace(upgrade, script, reuseExistingBranch);
+      expect(res).toEqual(
+        `<script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.11.1/katex.min.js" integrity="sha256-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" crossorigin="anonymous">`
+      );
     });
     it('updates with autoReplaceNewString', async () => {
       const dockerfile =
@@ -140,8 +138,9 @@ describe('workers/branch/auto-replace', () => {
       upgrade.autoReplaceStringTemplate =
         '{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}';
       const res = await doAutoReplace(upgrade, dockerfile, reuseExistingBranch);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toEqual(
+        `FROM node:8.11.4-alpine@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa AS node`
+      );
     });
     it('fails with oldversion in depname', async () => {
       const yml =
diff --git a/lib/workers/pr/__snapshots__/automerge.spec.ts.snap b/lib/workers/pr/__snapshots__/automerge.spec.ts.snap
deleted file mode 100644
index 76721cbc3840a36b7392111d754de709a29d5207..0000000000000000000000000000000000000000
--- a/lib/workers/pr/__snapshots__/automerge.spec.ts.snap
+++ /dev/null
@@ -1,57 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`workers/pr/automerge checkAutoMerge(pr, config) should automerge comment 1`] = `
-Object {
-  "automerged": true,
-  "branchRemoved": false,
-}
-`;
-
-exports[`workers/pr/automerge checkAutoMerge(pr, config) should automerge if enabled and pr is mergeable 1`] = `
-Object {
-  "automerged": true,
-  "branchRemoved": true,
-}
-`;
-
-exports[`workers/pr/automerge checkAutoMerge(pr, config) should indicate if automerge failed 1`] = `
-Object {
-  "automerged": false,
-  "prAutomergeBlockReason": "PlatformRejection",
-}
-`;
-
-exports[`workers/pr/automerge checkAutoMerge(pr, config) should not automerge if enabled and pr is mergeable but branch status is not success 1`] = `
-Object {
-  "automerged": false,
-  "prAutomergeBlockReason": "BranchNotGreen",
-}
-`;
-
-exports[`workers/pr/automerge checkAutoMerge(pr, config) should not automerge if enabled and pr is mergeable but cannot rebase 1`] = `
-Object {
-  "automerged": false,
-  "prAutomergeBlockReason": "BranchModified",
-}
-`;
-
-exports[`workers/pr/automerge checkAutoMerge(pr, config) should not automerge if enabled and pr is mergeable but unstable 1`] = `
-Object {
-  "automerged": false,
-  "prAutomergeBlockReason": "PlatformNotReady",
-}
-`;
-
-exports[`workers/pr/automerge checkAutoMerge(pr, config) should not automerge if enabled and pr is unmergeable 1`] = `
-Object {
-  "automerged": false,
-  "prAutomergeBlockReason": "Conflicted",
-}
-`;
-
-exports[`workers/pr/automerge checkAutoMerge(pr, config) should remove previous automerge comment when rebasing 1`] = `
-Object {
-  "automerged": true,
-  "branchRemoved": false,
-}
-`;
diff --git a/lib/workers/pr/automerge.spec.ts b/lib/workers/pr/automerge.spec.ts
index 1268a50562dfa7fa1e9b9d8726f6e421b00e6709..967d127c7b56c3b2b70f06b92611420e55775e68 100644
--- a/lib/workers/pr/automerge.spec.ts
+++ b/lib/workers/pr/automerge.spec.ts
@@ -29,8 +29,7 @@ describe('workers/pr/automerge', () => {
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
       platform.mergePr.mockResolvedValueOnce(true);
       const res = await prAutomerge.checkAutoMerge(pr, config);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toEqual({ automerged: true, branchRemoved: true });
       expect(platform.mergePr).toHaveBeenCalledTimes(1);
     });
     it('should indicate if automerge failed', async () => {
@@ -38,8 +37,10 @@ describe('workers/pr/automerge', () => {
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
       platform.mergePr.mockResolvedValueOnce(false);
       const res = await prAutomerge.checkAutoMerge(pr, config);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toEqual({
+        automerged: false,
+        prAutomergeBlockReason: 'PlatformRejection',
+      });
       expect(platform.mergePr).toHaveBeenCalledTimes(1);
     });
     it('should automerge comment', async () => {
@@ -49,8 +50,7 @@ describe('workers/pr/automerge', () => {
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
       platform.ensureComment.mockResolvedValueOnce(true);
       const res = await prAutomerge.checkAutoMerge(pr, config);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toEqual({ automerged: true, branchRemoved: false });
       expect(platform.ensureCommentRemoval).toHaveBeenCalledTimes(0);
       expect(platform.ensureComment).toHaveBeenCalledTimes(1);
     });
@@ -62,8 +62,7 @@ describe('workers/pr/automerge', () => {
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
       platform.ensureComment.mockResolvedValueOnce(true);
       const res = await prAutomerge.checkAutoMerge(pr, config);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toEqual({ automerged: true, branchRemoved: false });
       expect(platform.ensureCommentRemoval).toHaveBeenCalledTimes(1);
       expect(platform.ensureComment).toHaveBeenCalledTimes(1);
     });
@@ -72,32 +71,40 @@ describe('workers/pr/automerge', () => {
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
       git.isBranchModified.mockResolvedValueOnce(true);
       const res = await prAutomerge.checkAutoMerge(pr, config);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toEqual({
+        automerged: false,
+        prAutomergeBlockReason: 'BranchModified',
+      });
       expect(platform.mergePr).toHaveBeenCalledTimes(0);
     });
     it('should not automerge if enabled and pr is mergeable but branch status is not success', async () => {
       config.automerge = true;
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.yellow);
       const res = await prAutomerge.checkAutoMerge(pr, config);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toEqual({
+        automerged: false,
+        prAutomergeBlockReason: 'BranchNotGreen',
+      });
       expect(platform.mergePr).toHaveBeenCalledTimes(0);
     });
     it('should not automerge if enabled and pr is mergeable but unstable', async () => {
       config.automerge = true;
       pr.canMerge = undefined;
       const res = await prAutomerge.checkAutoMerge(pr, config);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toEqual({
+        automerged: false,
+        prAutomergeBlockReason: 'PlatformNotReady',
+      });
       expect(platform.mergePr).toHaveBeenCalledTimes(0);
     });
     it('should not automerge if enabled and pr is unmergeable', async () => {
       config.automerge = true;
       pr.isConflicted = true;
       const res = await prAutomerge.checkAutoMerge(pr, config);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toEqual({
+        automerged: false,
+        prAutomergeBlockReason: 'Conflicted',
+      });
       expect(platform.mergePr).toHaveBeenCalledTimes(0);
     });
   });
diff --git a/lib/workers/pr/body/__snapshots__/controls.spec.ts.snap b/lib/workers/pr/body/__snapshots__/controls.spec.ts.snap
deleted file mode 100644
index 4d97e9e1e0b570c2c7ed2b22876dc91dd8a83d57..0000000000000000000000000000000000000000
--- a/lib/workers/pr/body/__snapshots__/controls.spec.ts.snap
+++ /dev/null
@@ -1,21 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`workers/pr/body/controls getControls when the branch is  modified has the correct contents 1`] = `
-"
-
----
-
- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox. âš  **Warning**: custom changes will be lost.
-
-"
-`;
-
-exports[`workers/pr/body/controls getControls when the branch is  not modified has the correct contents 1`] = `
-"
-
----
-
- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox.
-
-"
-`;
diff --git a/lib/workers/pr/body/controls.spec.ts b/lib/workers/pr/body/controls.spec.ts
index 50724044d383deb50841a6d52263561ab71a378b..a47b50eebbf1de895dc2ee1da4789c7b38871e72 100644
--- a/lib/workers/pr/body/controls.spec.ts
+++ b/lib/workers/pr/body/controls.spec.ts
@@ -13,19 +13,33 @@ describe('workers/pr/body/controls', () => {
       branchConfig = mock<BranchConfig>();
       branchConfig.branchName = 'branchName';
     });
-    [true, false].forEach((modified) => {
-      describe(`when the branch is ${modified ? '' : ' not'} modified`, () => {
-        beforeEach(() => {
-          git.isBranchModified.mockResolvedValue(modified);
-        });
-        it('has the correct contents', async () => {
-          // FIXME: explicit assert condition
-          expect(await getControls(branchConfig)).toMatchSnapshot();
-          expect(git.isBranchModified).toHaveBeenCalledTimes(1);
-          expect(git.isBranchModified).toHaveBeenCalledWith(
-            branchConfig.branchName
-          );
-        });
+    describe(`when the branch is modified`, () => {
+      beforeEach(() => {
+        git.isBranchModified.mockResolvedValue(true);
+      });
+      it('has the correct contents', async () => {
+        expect(await getControls(branchConfig)).toContain(
+          `- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox. âš  **Warning**: custom changes will be lost.`
+        );
+        expect(git.isBranchModified).toHaveBeenCalledTimes(1);
+        expect(git.isBranchModified).toHaveBeenCalledWith(
+          branchConfig.branchName
+        );
+      });
+    });
+
+    describe(`when the branch is not modified`, () => {
+      beforeEach(() => {
+        git.isBranchModified.mockResolvedValue(false);
+      });
+      it('has the correct contents', async () => {
+        expect(await getControls(branchConfig)).toContain(
+          `- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox.`
+        );
+        expect(git.isBranchModified).toHaveBeenCalledTimes(1);
+        expect(git.isBranchModified).toHaveBeenCalledWith(
+          branchConfig.branchName
+        );
       });
     });
   });
diff --git a/lib/workers/pr/changelog/__snapshots__/release-notes.spec.ts.snap b/lib/workers/pr/changelog/__snapshots__/release-notes.spec.ts.snap
index 298f4f4de9cfc85ae409301aa7e1694029ab0391..d0fc8813efca4390e3e6ccc32969fcfa9d075bd5 100644
--- a/lib/workers/pr/changelog/__snapshots__/release-notes.spec.ts.snap
+++ b/lib/workers/pr/changelog/__snapshots__/release-notes.spec.ts.snap
@@ -106,18 +106,6 @@ Array [
 `;
 
 exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body "" 1`] = `
-Object {
-  "body": "some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)
-",
-  "id": undefined,
-  "name": undefined,
-  "notesSourceUrl": "https://api.github.com/repos/some/other-repository/releases",
-  "tag": "1.0.1",
-  "url": "https://github.com/some/other-repository/releases/1.0.1",
-}
-`;
-
-exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body "" 2`] = `
 Array [
   Object {
     "headers": Object {
@@ -133,18 +121,6 @@ Array [
 `;
 
 exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body "other@" 1`] = `
-Object {
-  "body": "some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)
-",
-  "id": undefined,
-  "name": undefined,
-  "notesSourceUrl": "https://api.github.com/repos/some/other-repository/releases",
-  "tag": "other@1.0.1",
-  "url": "https://github.com/some/other-repository/releases/other@1.0.1",
-}
-`;
-
-exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body "other@" 2`] = `
 Array [
   Object {
     "headers": Object {
@@ -160,18 +136,6 @@ Array [
 `;
 
 exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body "other_v" 1`] = `
-Object {
-  "body": "some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)
-",
-  "id": undefined,
-  "name": undefined,
-  "notesSourceUrl": "https://api.github.com/repos/some/other-repository/releases",
-  "tag": "other_v1.0.1",
-  "url": "https://github.com/some/other-repository/releases/other_v1.0.1",
-}
-`;
-
-exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body "other_v" 2`] = `
 Array [
   Object {
     "headers": Object {
@@ -187,18 +151,6 @@ Array [
 `;
 
 exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body "other-" 1`] = `
-Object {
-  "body": "some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)
-",
-  "id": undefined,
-  "name": undefined,
-  "notesSourceUrl": "https://api.github.com/repos/some/other-repository/releases",
-  "tag": "other-1.0.1",
-  "url": "https://github.com/some/other-repository/releases/other-1.0.1",
-}
-`;
-
-exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body "other-" 2`] = `
 Array [
   Object {
     "headers": Object {
@@ -214,18 +166,6 @@ Array [
 `;
 
 exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body "v" 1`] = `
-Object {
-  "body": "some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)
-",
-  "id": undefined,
-  "name": undefined,
-  "notesSourceUrl": "https://api.github.com/repos/some/other-repository/releases",
-  "tag": "v1.0.1",
-  "url": "https://github.com/some/other-repository/releases/v1.0.1",
-}
-`;
-
-exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body "v" 2`] = `
 Array [
   Object {
     "headers": Object {
@@ -241,16 +181,6 @@ Array [
 `;
 
 exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body from gitlab repo "" 1`] = `
-Object {
-  "body": "some body #123, [#124](https://gitlab.com/some/yet-other-repository/issues/124)",
-  "name": undefined,
-  "notesSourceUrl": "https://api.gitlab.com/projects/some%2fother-repository/releases",
-  "tag": "1.0.1",
-  "url": "https://gitlab.com/some/other-repository/tags/1.0.1",
-}
-`;
-
-exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body from gitlab repo "" 2`] = `
 Array [
   Object {
     "headers": Object {
@@ -266,16 +196,6 @@ Array [
 `;
 
 exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body from gitlab repo "other-" 1`] = `
-Object {
-  "body": "some body #123, [#124](https://gitlab.com/some/yet-other-repository/issues/124)",
-  "name": undefined,
-  "notesSourceUrl": "https://api.gitlab.com/projects/some%2fother-repository/releases",
-  "tag": "other-1.0.1",
-  "url": "https://gitlab.com/some/other-repository/tags/other-1.0.1",
-}
-`;
-
-exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body from gitlab repo "other-" 2`] = `
 Array [
   Object {
     "headers": Object {
@@ -291,16 +211,6 @@ Array [
 `;
 
 exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body from gitlab repo "v" 1`] = `
-Object {
-  "body": "some body #123, [#124](https://gitlab.com/some/yet-other-repository/issues/124)",
-  "name": undefined,
-  "notesSourceUrl": "https://api.gitlab.com/projects/some%2fother-repository/releases",
-  "tag": "v1.0.1",
-  "url": "https://gitlab.com/some/other-repository/tags/v1.0.1",
-}
-`;
-
-exports[`workers/pr/changelog/release-notes getReleaseNotes() gets release notes with body from gitlab repo "v" 2`] = `
 Array [
   Object {
     "headers": Object {
diff --git a/lib/workers/pr/changelog/github.spec.ts b/lib/workers/pr/changelog/github.spec.ts
index 95bfe0d6b85557ed0feb2047d3f2a3146807ecfd..b4b345943472cad206d1606fe86a669585bc698b 100644
--- a/lib/workers/pr/changelog/github.spec.ts
+++ b/lib/workers/pr/changelog/github.spec.ts
@@ -83,41 +83,105 @@ describe('workers/pr/changelog/github', () => {
     });
 
     it('works without Github', async () => {
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: true,
+        project: {
+          apiBaseUrl: 'https://api.github.com/',
+          baseUrl: 'https://github.com/',
+          depName: 'renovate',
+          repository: 'chalk/chalk',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://github.com/chalk/chalk',
+          type: 'github',
+        },
+        versions: [
+          { version: '2.5.2' },
+          { version: '2.4.2' },
+          { version: '2.3.0' },
+          { version: '2.2.2' },
+        ],
+      });
     });
 
     it('uses GitHub tags', async () => {
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: true,
+        project: {
+          apiBaseUrl: 'https://api.github.com/',
+          baseUrl: 'https://github.com/',
+          depName: 'renovate',
+          repository: 'chalk/chalk',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://github.com/chalk/chalk',
+          type: 'github',
+        },
+        versions: [
+          { version: '2.5.2' },
+          { version: '2.4.2' },
+          { version: '2.3.0' },
+          { version: '2.2.2' },
+        ],
+      });
     });
 
     it('filters unnecessary warns', async () => {
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
           depName: '@renovate/no',
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: true,
+        project: {
+          apiBaseUrl: 'https://api.github.com/',
+          baseUrl: 'https://github.com/',
+          depName: '@renovate/no',
+          repository: 'chalk/chalk',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://github.com/chalk/chalk',
+          type: 'github',
+        },
+        versions: [
+          { version: '2.5.2' },
+          { version: '2.4.2' },
+          { version: '2.3.0' },
+          { version: '2.2.2' },
+        ],
+      });
     });
 
     it('supports node engines', async () => {
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
           depType: 'engines',
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: true,
+        project: {
+          apiBaseUrl: 'https://api.github.com/',
+          baseUrl: 'https://github.com/',
+          depName: 'renovate',
+          repository: 'chalk/chalk',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://github.com/chalk/chalk',
+          type: 'github',
+        },
+        versions: [
+          { version: '2.5.2' },
+          { version: '2.4.2' },
+          { version: '2.3.0' },
+          { version: '2.2.2' },
+        ],
+      });
     });
 
     it('handles no sourceUrl', async () => {
@@ -171,13 +235,29 @@ describe('workers/pr/changelog/github', () => {
         token: 'super_secret',
         matchHost: 'https://github-enterprise.example.com/',
       });
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
           endpoint: 'https://github-enterprise.example.com/',
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: true,
+        project: {
+          apiBaseUrl: 'https://api.github.com/',
+          baseUrl: 'https://github.com/',
+          depName: 'renovate',
+          repository: 'chalk/chalk',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://github.com/chalk/chalk',
+          type: 'github',
+        },
+        versions: [
+          { version: '2.5.2' },
+          { version: '2.4.2' },
+          { version: '2.3.0' },
+          { version: '2.2.2' },
+        ],
+      });
     });
 
     it('supports github enterprise and github enterprise changelog', async () => {
@@ -187,14 +267,30 @@ describe('workers/pr/changelog/github', () => {
         token: 'abc',
       });
       process.env.GITHUB_ENDPOINT = '';
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
           sourceUrl: 'https://github-enterprise.example.com/chalk/chalk',
           endpoint: 'https://github-enterprise.example.com/',
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: true,
+        project: {
+          apiBaseUrl: 'https://github-enterprise.example.com/api/v3/',
+          baseUrl: 'https://github-enterprise.example.com/',
+          depName: 'renovate',
+          repository: 'chalk/chalk',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://github-enterprise.example.com/chalk/chalk',
+          type: 'github',
+        },
+        versions: [
+          { version: '2.5.2' },
+          { version: '2.4.2' },
+          { version: '2.3.0' },
+          { version: '2.2.2' },
+        ],
+      });
     });
   });
 });
diff --git a/lib/workers/pr/changelog/gitlab.spec.ts b/lib/workers/pr/changelog/gitlab.spec.ts
index 7894bc600812a70f8312d4628b74ebac1cb5d4f1..836e0d6367c952412ced7c93cc2801ccad7d58b2 100644
--- a/lib/workers/pr/changelog/gitlab.spec.ts
+++ b/lib/workers/pr/changelog/gitlab.spec.ts
@@ -76,12 +76,28 @@ describe('workers/pr/changelog/gitlab', () => {
       ).toBeNull();
     });
     it('works without GitLab', async () => {
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: false,
+        project: {
+          apiBaseUrl: 'https://gitlab.com/api/v4/',
+          baseUrl: 'https://gitlab.com/',
+          depName: 'renovate',
+          repository: 'meno/dropzone',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://gitlab.com/meno/dropzone/',
+          type: 'gitlab',
+        },
+        versions: [
+          { version: '5.6.1' },
+          { version: '5.6.0' },
+          { version: '5.5.0' },
+          { version: '5.4.0' },
+        ],
+      });
     });
     it('uses GitLab tags', async () => {
       httpMock
@@ -101,12 +117,28 @@ describe('workers/pr/changelog/gitlab', () => {
         .persist()
         .get('/api/v4/projects/meno%2fdropzone/releases?per_page=100')
         .reply(200, []);
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: true,
+        project: {
+          apiBaseUrl: 'https://gitlab.com/api/v4/',
+          baseUrl: 'https://gitlab.com/',
+          depName: 'renovate',
+          repository: 'meno/dropzone',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://gitlab.com/meno/dropzone/',
+          type: 'gitlab',
+        },
+        versions: [
+          { version: '5.6.1' },
+          { version: '5.6.0' },
+          { version: '5.5.0' },
+          { version: '5.4.0' },
+        ],
+      });
       expect(httpMock.getTrace()).toMatchSnapshot();
     });
     it('handles empty GitLab tags response', async () => {
@@ -120,12 +152,28 @@ describe('workers/pr/changelog/gitlab', () => {
         .persist()
         .get('/api/v4/projects/meno%2fdropzone/releases?per_page=100')
         .reply(200, []);
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: false,
+        project: {
+          apiBaseUrl: 'https://gitlab.com/api/v4/',
+          baseUrl: 'https://gitlab.com/',
+          depName: 'renovate',
+          repository: 'meno/dropzone',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://gitlab.com/meno/dropzone/',
+          type: 'gitlab',
+        },
+        versions: [
+          { version: '5.6.1' },
+          { version: '5.6.0' },
+          { version: '5.5.0' },
+          { version: '5.4.0' },
+        ],
+      });
       expect(httpMock.getTrace()).toMatchSnapshot();
     });
     it('uses GitLab tags with error', async () => {
@@ -139,12 +187,28 @@ describe('workers/pr/changelog/gitlab', () => {
         .persist()
         .get('/api/v4/projects/meno%2fdropzone/releases?per_page=100')
         .reply(200, []);
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: false,
+        project: {
+          apiBaseUrl: 'https://gitlab.com/api/v4/',
+          baseUrl: 'https://gitlab.com/',
+          depName: 'renovate',
+          repository: 'meno/dropzone',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://gitlab.com/meno/dropzone/',
+          type: 'gitlab',
+        },
+        versions: [
+          { version: '5.6.1' },
+          { version: '5.6.0' },
+          { version: '5.5.0' },
+          { version: '5.4.0' },
+        ],
+      });
       expect(httpMock.getTrace()).toMatchSnapshot();
     });
     it('handles no sourceUrl', async () => {
@@ -186,14 +250,30 @@ describe('workers/pr/changelog/gitlab', () => {
         token: 'abc',
       });
       process.env.GITHUB_ENDPOINT = '';
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
           sourceUrl: 'https://gitlab-enterprise.example.com/meno/dropzone/',
           endpoint: 'https://gitlab-enterprise.example.com/',
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: false,
+        project: {
+          apiBaseUrl: 'https://gitlab-enterprise.example.com/api/v4/',
+          baseUrl: 'https://gitlab-enterprise.example.com/',
+          depName: 'renovate',
+          repository: 'meno/dropzone',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://gitlab-enterprise.example.com/meno/dropzone/',
+          type: 'gitlab',
+        },
+        versions: [
+          { version: '5.6.1' },
+          { version: '5.6.0' },
+          { version: '5.5.0' },
+          { version: '5.4.0' },
+        ],
+      });
     });
     it('supports self-hosted gitlab changelog', async () => {
       httpMock.scope('https://git.test.com').persist().get(/.*/).reply(200, []);
@@ -203,7 +283,6 @@ describe('workers/pr/changelog/gitlab', () => {
         token: 'abc',
       });
       process.env.GITHUB_ENDPOINT = '';
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
@@ -211,7 +290,24 @@ describe('workers/pr/changelog/gitlab', () => {
           sourceUrl: 'https://git.test.com/meno/dropzone/',
           endpoint: 'https://git.test.com/api/v4/',
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: false,
+        project: {
+          apiBaseUrl: 'https://git.test.com/api/v4/',
+          baseUrl: 'https://git.test.com/',
+          depName: 'renovate',
+          repository: 'meno/dropzone',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://git.test.com/meno/dropzone/',
+          type: 'gitlab',
+        },
+        versions: [
+          { version: '5.6.1' },
+          { version: '5.6.0' },
+          { version: '5.5.0' },
+          { version: '5.4.0' },
+        ],
+      });
     });
   });
 });
diff --git a/lib/workers/pr/changelog/index.spec.ts b/lib/workers/pr/changelog/index.spec.ts
index 051a141def702d9304ebe514a95f888814d569d6..9dcc7408d78129beccc1d8b6062971c9d5636755 100644
--- a/lib/workers/pr/changelog/index.spec.ts
+++ b/lib/workers/pr/changelog/index.spec.ts
@@ -94,12 +94,28 @@ describe('workers/pr/changelog/index', () => {
         .get('/repos/chalk/chalk/releases?per_page=100')
         .times(4)
         .reply(500);
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: true,
+        project: {
+          apiBaseUrl: 'https://api.github.com/',
+          baseUrl: 'https://github.com/',
+          depName: 'renovate',
+          repository: 'chalk/chalk',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://github.com/chalk/chalk',
+          type: 'github',
+        },
+        versions: [
+          { version: '2.5.2' },
+          { version: '2.4.2' },
+          { version: '2.3.0' },
+          { version: '2.2.2' },
+        ],
+      });
       expect(httpMock.getTrace()).toHaveLength(9);
     });
     it('uses GitHub tags', async () => {
@@ -117,12 +133,28 @@ describe('workers/pr/changelog/index', () => {
         .persist()
         .get(/.*/)
         .reply(200, []);
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: true,
+        project: {
+          apiBaseUrl: 'https://api.github.com/',
+          baseUrl: 'https://github.com/',
+          depName: 'renovate',
+          repository: 'chalk/chalk',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://github.com/chalk/chalk',
+          type: 'github',
+        },
+        versions: [
+          { version: '2.5.2' },
+          { version: '2.4.2' },
+          { version: '2.3.0' },
+          { version: '2.2.2' },
+        ],
+      });
       expect(httpMock.getTrace()).toMatchSnapshot();
     });
     it('filters unnecessary warns', async () => {
@@ -135,18 +167,50 @@ describe('workers/pr/changelog/index', () => {
         ...upgrade,
         depName: '@renovate/no',
       });
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toMatchSnapshot({
+        hasReleaseNotes: true,
+        project: {
+          apiBaseUrl: 'https://api.github.com/',
+          baseUrl: 'https://github.com/',
+          depName: '@renovate/no',
+          repository: 'chalk/chalk',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://github.com/chalk/chalk',
+          type: 'github',
+        },
+        versions: [
+          { version: '2.5.2' },
+          { version: '2.4.2' },
+          { version: '2.3.0' },
+          { version: '2.2.2' },
+        ],
+      });
       expect(httpMock.getTrace()).toMatchSnapshot();
     });
     it('supports node engines', async () => {
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
           depType: 'engines',
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: true,
+        project: {
+          apiBaseUrl: 'https://api.github.com/',
+          baseUrl: 'https://github.com/',
+          depName: 'renovate',
+          repository: 'chalk/chalk',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://github.com/chalk/chalk',
+          type: 'github',
+        },
+        versions: [
+          { version: '2.5.2' },
+          { version: '2.4.2' },
+          { version: '2.3.0' },
+          { version: '2.2.2' },
+        ],
+      });
       // FIXME: missing mocks
       httpMock.clear(false);
     });
@@ -197,13 +261,29 @@ describe('workers/pr/changelog/index', () => {
         token: 'super_secret',
         matchHost: 'https://github-enterprise.example.com/',
       });
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
           endpoint: 'https://github-enterprise.example.com/',
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: true,
+        project: {
+          apiBaseUrl: 'https://api.github.com/',
+          baseUrl: 'https://github.com/',
+          depName: 'renovate',
+          repository: 'chalk/chalk',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://github.com/chalk/chalk',
+          type: 'github',
+        },
+        versions: [
+          { version: '2.5.2' },
+          { version: '2.4.2' },
+          { version: '2.3.0' },
+          { version: '2.2.2' },
+        ],
+      });
       expect(httpMock.getTrace()).toMatchSnapshot();
     });
     it('supports github enterprise and github enterprise changelog', async () => {
@@ -218,14 +298,30 @@ describe('workers/pr/changelog/index', () => {
         token: 'abc',
       });
       process.env.GITHUB_ENDPOINT = '';
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
           sourceUrl: 'https://github-enterprise.example.com/chalk/chalk',
           endpoint: 'https://github-enterprise.example.com/',
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: true,
+        project: {
+          apiBaseUrl: 'https://github-enterprise.example.com/api/v3/',
+          baseUrl: 'https://github-enterprise.example.com/',
+          depName: 'renovate',
+          repository: 'chalk/chalk',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://github-enterprise.example.com/chalk/chalk',
+          type: 'github',
+        },
+        versions: [
+          { version: '2.5.2' },
+          { version: '2.4.2' },
+          { version: '2.3.0' },
+          { version: '2.2.2' },
+        ],
+      });
       expect(httpMock.getTrace()).toMatchSnapshot();
     });
 
@@ -240,13 +336,29 @@ describe('workers/pr/changelog/index', () => {
         matchHost: 'https://github-enterprise.example.com/',
         token: 'abc',
       });
-      // FIXME: explicit assert condition
       expect(
         await getChangeLogJSON({
           ...upgrade,
           sourceUrl: 'https://github-enterprise.example.com/chalk/chalk',
         })
-      ).toMatchSnapshot();
+      ).toMatchSnapshot({
+        hasReleaseNotes: true,
+        project: {
+          apiBaseUrl: 'https://github-enterprise.example.com/api/v3/',
+          baseUrl: 'https://github-enterprise.example.com/',
+          depName: 'renovate',
+          repository: 'chalk/chalk',
+          sourceDirectory: undefined,
+          sourceUrl: 'https://github-enterprise.example.com/chalk/chalk',
+          type: 'github',
+        },
+        versions: [
+          { version: '2.5.2' },
+          { version: '2.4.2' },
+          { version: '2.3.0' },
+          { version: '2.2.2' },
+        ],
+      });
       expect(httpMock.getTrace()).toMatchSnapshot();
     });
   });
diff --git a/lib/workers/pr/changelog/release-notes.spec.ts b/lib/workers/pr/changelog/release-notes.spec.ts
index 209a741fd1b9168e4479e8db4647d1d8f10c46fa..e83859385039e41c67609a588b15fa8063859ea9 100644
--- a/lib/workers/pr/changelog/release-notes.spec.ts
+++ b/lib/workers/pr/changelog/release-notes.spec.ts
@@ -280,62 +280,261 @@ describe('workers/pr/changelog/release-notes', () => {
       expect(httpMock.getTrace()).toMatchSnapshot();
     });
 
-    it.each([[''], ['v'], ['other-'], ['other_v'], ['other@']])(
-      'gets release notes with body "%s"',
-      async (prefix) => {
-        httpMock
-          .scope('https://api.github.com/')
-          .get('/repos/some/other-repository/releases?per_page=100')
-          .reply(200, [
-            { tag_name: `${prefix}1.0.0` },
-            {
-              tag_name: `${prefix}1.0.1`,
-              body: 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)',
-            },
-          ]);
-        const res = await getReleaseNotes(
+    it('gets release notes with body ""', async () => {
+      const prefix = '';
+      httpMock
+        .scope('https://api.github.com/')
+        .get('/repos/some/other-repository/releases?per_page=100')
+        .reply(200, [
+          { tag_name: `${prefix}1.0.0` },
           {
-            ...githubProject,
-            repository: 'some/other-repository',
-            depName: 'other',
+            tag_name: `${prefix}1.0.1`,
+            body: 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)',
           },
-          '1.0.1'
-        );
-        // FIXME: explicit assert condition
-        expect(res).toMatchSnapshot();
-        expect(httpMock.getTrace()).toMatchSnapshot();
-      }
-    );
+        ]);
+      const res = await getReleaseNotes(
+        {
+          ...githubProject,
+          repository: 'some/other-repository',
+          depName: 'other',
+        },
+        '1.0.1'
+      );
+      expect(res).toEqual({
+        body: 'some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)\n',
+        id: undefined,
+        name: undefined,
+        notesSourceUrl:
+          'https://api.github.com/repos/some/other-repository/releases',
+        tag: '1.0.1',
+        url: 'https://github.com/some/other-repository/releases/1.0.1',
+      });
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
+    it('gets release notes with body "v"', async () => {
+      const prefix = 'v';
+      httpMock
+        .scope('https://api.github.com/')
+        .get('/repos/some/other-repository/releases?per_page=100')
+        .reply(200, [
+          { tag_name: `${prefix}1.0.0` },
+          {
+            tag_name: `${prefix}1.0.1`,
+            body: 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)',
+          },
+        ]);
+      const res = await getReleaseNotes(
+        {
+          ...githubProject,
+          repository: 'some/other-repository',
+          depName: 'other',
+        },
+        '1.0.1'
+      );
+      expect(res).toEqual({
+        body: 'some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)\n',
+        id: undefined,
+        name: undefined,
+        notesSourceUrl:
+          'https://api.github.com/repos/some/other-repository/releases',
+        tag: 'v1.0.1',
+        url: 'https://github.com/some/other-repository/releases/v1.0.1',
+      });
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
+    it('gets release notes with body "other-"', async () => {
+      const prefix = 'other-';
+      httpMock
+        .scope('https://api.github.com/')
+        .get('/repos/some/other-repository/releases?per_page=100')
+        .reply(200, [
+          { tag_name: `${prefix}1.0.0` },
+          {
+            tag_name: `${prefix}1.0.1`,
+            body: 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)',
+          },
+        ]);
+      const res = await getReleaseNotes(
+        {
+          ...githubProject,
+          repository: 'some/other-repository',
+          depName: 'other',
+        },
+        '1.0.1'
+      );
+      expect(res).toEqual({
+        body: 'some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)\n',
+        id: undefined,
+        name: undefined,
+        notesSourceUrl:
+          'https://api.github.com/repos/some/other-repository/releases',
+        tag: 'other-1.0.1',
+        url: 'https://github.com/some/other-repository/releases/other-1.0.1',
+      });
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
+    it('gets release notes with body "other_v"', async () => {
+      const prefix = 'other_v';
+      httpMock
+        .scope('https://api.github.com/')
+        .get('/repos/some/other-repository/releases?per_page=100')
+        .reply(200, [
+          { tag_name: `${prefix}1.0.0` },
+          {
+            tag_name: `${prefix}1.0.1`,
+            body: 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)',
+          },
+        ]);
+      const res = await getReleaseNotes(
+        {
+          ...githubProject,
+          repository: 'some/other-repository',
+          depName: 'other',
+        },
+        '1.0.1'
+      );
+      expect(res).toEqual({
+        body: 'some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)\n',
+        id: undefined,
+        name: undefined,
+        notesSourceUrl:
+          'https://api.github.com/repos/some/other-repository/releases',
+        tag: 'other_v1.0.1',
+        url: 'https://github.com/some/other-repository/releases/other_v1.0.1',
+      });
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
+    it('gets release notes with body "other@"', async () => {
+      const prefix = 'other@';
+      httpMock
+        .scope('https://api.github.com/')
+        .get('/repos/some/other-repository/releases?per_page=100')
+        .reply(200, [
+          { tag_name: `${prefix}1.0.0` },
+          {
+            tag_name: `${prefix}1.0.1`,
+            body: 'some body #123, [#124](https://github.com/some/yet-other-repository/issues/124)',
+          },
+        ]);
+      const res = await getReleaseNotes(
+        {
+          ...githubProject,
+          repository: 'some/other-repository',
+          depName: 'other',
+        },
+        '1.0.1'
+      );
+      expect(res).toEqual({
+        body: 'some body [#123](https://github.com/some/other-repository/issues/123), [#124](https://github.com/some/yet-other-repository/issues/124)\n',
+        id: undefined,
+        name: undefined,
+        notesSourceUrl:
+          'https://api.github.com/repos/some/other-repository/releases',
+        tag: 'other@1.0.1',
+        url: 'https://github.com/some/other-repository/releases/other@1.0.1',
+      });
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
 
-    it.each([[''], ['v'], ['other-']])(
-      'gets release notes with body from gitlab repo "%s"',
-      async (prefix) => {
-        httpMock
-          .scope('https://api.gitlab.com/')
-          .get('/projects/some%2fother-repository/releases?per_page=100')
-          .reply(200, [
-            { tag_name: `${prefix}1.0.0` },
-            {
-              tag_name: `${prefix}1.0.1`,
-              description:
-                'some body #123, [#124](https://gitlab.com/some/yet-other-repository/issues/124)',
-            },
-          ]);
+    it('gets release notes with body from gitlab repo ""', async () => {
+      const prefix = '';
+      httpMock
+        .scope('https://api.gitlab.com/')
+        .get('/projects/some%2fother-repository/releases?per_page=100')
+        .reply(200, [
+          { tag_name: `${prefix}1.0.0` },
+          {
+            tag_name: `${prefix}1.0.1`,
+            description:
+              'some body #123, [#124](https://gitlab.com/some/yet-other-repository/issues/124)',
+          },
+        ]);
 
-        const res = await getReleaseNotes(
+      const res = await getReleaseNotes(
+        {
+          ...gitlabProject,
+          repository: 'some/other-repository',
+          depName: 'other',
+          apiBaseUrl: 'https://api.gitlab.com/',
+        },
+        '1.0.1'
+      );
+      expect(res).toEqual({
+        body: 'some body #123, [#124](https://gitlab.com/some/yet-other-repository/issues/124)',
+        name: undefined,
+        notesSourceUrl:
+          'https://api.gitlab.com/projects/some%2fother-repository/releases',
+        tag: '1.0.1',
+        url: 'https://gitlab.com/some/other-repository/tags/1.0.1',
+      });
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
+    it('gets release notes with body from gitlab repo "v"', async () => {
+      const prefix = 'v';
+      httpMock
+        .scope('https://api.gitlab.com/')
+        .get('/projects/some%2fother-repository/releases?per_page=100')
+        .reply(200, [
+          { tag_name: `${prefix}1.0.0` },
           {
-            ...gitlabProject,
-            repository: 'some/other-repository',
-            depName: 'other',
-            apiBaseUrl: 'https://api.gitlab.com/',
+            tag_name: `${prefix}1.0.1`,
+            description:
+              'some body #123, [#124](https://gitlab.com/some/yet-other-repository/issues/124)',
           },
-          '1.0.1'
-        );
-        // FIXME: explicit assert condition
-        expect(res).toMatchSnapshot();
-        expect(httpMock.getTrace()).toMatchSnapshot();
-      }
-    );
+        ]);
+
+      const res = await getReleaseNotes(
+        {
+          ...gitlabProject,
+          repository: 'some/other-repository',
+          depName: 'other',
+          apiBaseUrl: 'https://api.gitlab.com/',
+        },
+        '1.0.1'
+      );
+      expect(res).toEqual({
+        body: 'some body #123, [#124](https://gitlab.com/some/yet-other-repository/issues/124)',
+        name: undefined,
+        notesSourceUrl:
+          'https://api.gitlab.com/projects/some%2fother-repository/releases',
+        tag: 'v1.0.1',
+        url: 'https://gitlab.com/some/other-repository/tags/v1.0.1',
+      });
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
+    it('gets release notes with body from gitlab repo "other-"', async () => {
+      const prefix = 'other-';
+      httpMock
+        .scope('https://api.gitlab.com/')
+        .get('/projects/some%2fother-repository/releases?per_page=100')
+        .reply(200, [
+          { tag_name: `${prefix}1.0.0` },
+          {
+            tag_name: `${prefix}1.0.1`,
+            description:
+              'some body #123, [#124](https://gitlab.com/some/yet-other-repository/issues/124)',
+          },
+        ]);
+
+      const res = await getReleaseNotes(
+        {
+          ...gitlabProject,
+          repository: 'some/other-repository',
+          depName: 'other',
+          apiBaseUrl: 'https://api.gitlab.com/',
+        },
+        '1.0.1'
+      );
+      expect(res).toEqual({
+        body: 'some body #123, [#124](https://gitlab.com/some/yet-other-repository/issues/124)',
+        name: undefined,
+        notesSourceUrl:
+          'https://api.gitlab.com/projects/some%2fother-repository/releases',
+        tag: 'other-1.0.1',
+        url: 'https://gitlab.com/some/other-repository/tags/other-1.0.1',
+      });
+      expect(httpMock.getTrace()).toMatchSnapshot();
+    });
 
     it('gets null from repository without gitlab/github in domain', async () => {
       const res = await getReleaseNotes(
diff --git a/lib/workers/pr/index.spec.ts b/lib/workers/pr/index.spec.ts
index 37aba8e8b15482af639799b8f975de139bd719f9..27520244f7b99e96c6b9b4039aecd528173b6261 100644
--- a/lib/workers/pr/index.spec.ts
+++ b/lib/workers/pr/index.spec.ts
@@ -237,8 +237,12 @@ describe('workers/pr/index', () => {
       config.schedule = ['before 5am'];
       const { pr } = await prWorker.ensurePr(config);
       expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
-      // FIXME: explicit assert condition
-      expect(platform.createPr.mock.calls[0]).toMatchSnapshot();
+      expect(platform.createPr.mock.calls[0]).toMatchSnapshot([
+        {
+          prTitle: 'Update dependency dummy to v1.1.0',
+          sourceBranch: 'renovate/gitlabdummy-1.x',
+        },
+      ]);
       existingPr.body = platform.createPr.mock.calls[0][0].prBody;
       config.branchName = 'renovate/dummy-1.x';
       config.depName = 'dummy';
@@ -253,8 +257,12 @@ describe('workers/pr/index', () => {
       config.schedule = ['before 5am'];
       const { pr } = await prWorker.ensurePr(config);
       expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
-      // FIXME: explicit assert condition
-      expect(platform.createPr.mock.calls[0]).toMatchSnapshot();
+      expect(platform.createPr.mock.calls[0]).toMatchSnapshot([
+        {
+          prTitle: 'Update dependency dummy to v1.1.0',
+          sourceBranch: 'renovate/dummy-1.x',
+        },
+      ]);
       existingPr.body = platform.createPr.mock.calls[0][0].prBody;
     });
     it('should not create PR if limit is reached', async () => {
@@ -347,8 +355,12 @@ describe('workers/pr/index', () => {
       }
       const { pr } = await prWorker.ensurePr(config);
       expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
-      // FIXME: explicit assert condition
-      expect(platform.createPr.mock.calls[0]).toMatchSnapshot();
+      expect(platform.createPr.mock.calls[0]).toMatchSnapshot([
+        {
+          prTitle: 'Update dependency dummy to v1.1.0',
+          sourceBranch: 'renovate/dummy-1.x',
+        },
+      ]);
     });
     it('should add note about Pin', async () => {
       platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green);
@@ -361,8 +373,12 @@ describe('workers/pr/index', () => {
       config.logJSON = await changelogHelper.getChangeLogJSON(config);
       const { pr } = await prWorker.ensurePr(config);
       expect(pr).toMatchObject({ displayNumber: 'New Pull Request' });
-      // FIXME: explicit assert condition
-      expect(platform.createPr.mock.calls[0]).toMatchSnapshot();
+      expect(platform.createPr.mock.calls[0]).toMatchSnapshot([
+        {
+          prTitle: 'Update dependency dummy to v1.1.0',
+          sourceBranch: 'renovate/dummy-1.x',
+        },
+      ]);
       expect(platform.createPr.mock.calls[0][0].prBody).toContain(
         'this Pin PR'
       );
@@ -577,8 +593,10 @@ describe('workers/pr/index', () => {
       config.logJSON = await changelogHelper.getChangeLogJSON(config);
       platform.getBranchPr.mockResolvedValueOnce(existingPr);
       const { pr } = await prWorker.ensurePr(config);
-      // FIXME: explicit assert condition
-      expect(pr).toMatchSnapshot();
+      expect(pr).toMatchSnapshot({
+        displayNumber: 'Existing PR',
+        title: 'Update dependency dummy to v1.1.0',
+      });
     });
     it('should return modified existing PR title', async () => {
       config.newValue = '1.2.0';
@@ -587,8 +605,10 @@ describe('workers/pr/index', () => {
         title: 'wrong',
       });
       const { pr } = await prWorker.ensurePr(config);
-      // FIXME: explicit assert condition
-      expect(pr).toMatchSnapshot();
+      expect(pr).toMatchSnapshot({
+        displayNumber: 'Existing PR',
+        title: 'wrong',
+      });
     });
     it('should create PR if branch tests failed', async () => {
       config.automerge = true;
diff --git a/lib/workers/repository/process/__snapshots__/fetch.spec.ts.snap b/lib/workers/repository/process/__snapshots__/fetch.spec.ts.snap
index ef8a80d40d3895b10665e71a7a9f9e0b9199b26b..a7450cb6b11e404c2e701ec90cd52de8ea86262f 100644
--- a/lib/workers/repository/process/__snapshots__/fetch.spec.ts.snap
+++ b/lib/workers/repository/process/__snapshots__/fetch.spec.ts.snap
@@ -20,17 +20,6 @@ Object {
 }
 `;
 
-exports[`workers/repository/process/fetch fetchUpdates() handles empty deps 1`] = `
-Object {
-  "npm": Array [
-    Object {
-      "deps": Array [],
-      "packageFile": "package.json",
-    },
-  ],
-}
-`;
-
 exports[`workers/repository/process/fetch fetchUpdates() handles ignored, skipped and disabled 1`] = `
 Object {
   "npm": Array [
diff --git a/lib/workers/repository/process/__snapshots__/index.spec.ts.snap b/lib/workers/repository/process/__snapshots__/index.spec.ts.snap
deleted file mode 100644
index 5450c97623943c82d221170a9aa2935bd2a56c96..0000000000000000000000000000000000000000
--- a/lib/workers/repository/process/__snapshots__/index.spec.ts.snap
+++ /dev/null
@@ -1,15 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`workers/repository/process/index processRepo() processes baseBranches 1`] = `
-Object {
-  "branchList": Array [
-    undefined,
-  ],
-  "branches": Array [
-    undefined,
-  ],
-  "packageFiles": undefined,
-}
-`;
-
-exports[`workers/repository/process/index processRepo() processes single branches 1`] = `undefined`;
diff --git a/lib/workers/repository/process/__snapshots__/sort.spec.ts.snap b/lib/workers/repository/process/__snapshots__/sort.spec.ts.snap
deleted file mode 100644
index 5c44708bca9bbcb9b08af738c1ff511f4bb111b9..0000000000000000000000000000000000000000
--- a/lib/workers/repository/process/__snapshots__/sort.spec.ts.snap
+++ /dev/null
@@ -1,73 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`workers/repository/process/sort sortBranches() sorts based on isVulnerabilityAlert 1`] = `
-Array [
-  Object {
-    "isVulnerabilityAlert": true,
-    "prPriority": -1,
-    "prTitle": "a minor update",
-    "updateType": "minor",
-  },
-  Object {
-    "prPriority": 1,
-    "prTitle": "some major update",
-    "updateType": "major",
-  },
-  Object {
-    "prPriority": 0,
-    "prTitle": "some other pin",
-    "updateType": "pin",
-  },
-  Object {
-    "prPriority": -1,
-    "prTitle": "some pin",
-    "updateType": "pin",
-  },
-]
-`;
-
-exports[`workers/repository/process/sort sortBranches() sorts based on prPriority 1`] = `
-Array [
-  Object {
-    "prPriority": 1,
-    "prTitle": "some major update",
-    "updateType": "major",
-  },
-  Object {
-    "prPriority": 0,
-    "prTitle": "some other pin",
-    "updateType": "pin",
-  },
-  Object {
-    "prPriority": -1,
-    "prTitle": "some pin",
-    "updateType": "pin",
-  },
-  Object {
-    "prPriority": -1,
-    "prTitle": "a minor update",
-    "updateType": "minor",
-  },
-]
-`;
-
-exports[`workers/repository/process/sort sortBranches() sorts based on updateType and prTitle 1`] = `
-Array [
-  Object {
-    "prTitle": "some other pin",
-    "updateType": "pin",
-  },
-  Object {
-    "prTitle": "some pin",
-    "updateType": "pin",
-  },
-  Object {
-    "prTitle": "a minor update",
-    "updateType": "minor",
-  },
-  Object {
-    "prTitle": "some major update",
-    "updateType": "major",
-  },
-]
-`;
diff --git a/lib/workers/repository/process/fetch.spec.ts b/lib/workers/repository/process/fetch.spec.ts
index bf44f283a16a4dd57925fb63d12b4e4a7ca82624..cafdb59080630b7b728f0974fb39b950e8e452f4 100644
--- a/lib/workers/repository/process/fetch.spec.ts
+++ b/lib/workers/repository/process/fetch.spec.ts
@@ -20,8 +20,9 @@ describe('workers/repository/process/fetch', () => {
         npm: [{ packageFile: 'package.json', deps: [] }],
       };
       await fetchUpdates(config, packageFiles);
-      // FIXME: explicit assert condition
-      expect(packageFiles).toMatchSnapshot();
+      expect(packageFiles).toEqual({
+        npm: [{ deps: [], packageFile: 'package.json' }],
+      });
     });
     it('handles ignored, skipped and disabled', async () => {
       config.ignoreDeps = ['abcd'];
diff --git a/lib/workers/repository/process/index.spec.ts b/lib/workers/repository/process/index.spec.ts
index 63a53900e6f9063a99c319dd37da0336cf22c630..5f25f20aab1e875cf6c3be8a93e531d762136680 100644
--- a/lib/workers/repository/process/index.spec.ts
+++ b/lib/workers/repository/process/index.spec.ts
@@ -17,8 +17,7 @@ describe('workers/repository/process/index', () => {
   describe('processRepo()', () => {
     it('processes single branches', async () => {
       const res = await extractDependencies(config);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toBeUndefined();
     });
     it('processes baseBranches', async () => {
       extract.mockResolvedValue({} as never);
@@ -29,8 +28,11 @@ describe('workers/repository/process/index', () => {
       git.branchExists.mockReturnValueOnce(true);
       const res = await extractDependencies(config);
       await updateRepo(config, res.branches);
-      // FIXME: explicit assert condition
-      expect(res).toMatchSnapshot();
+      expect(res).toEqual({
+        branchList: [undefined],
+        branches: [undefined],
+        packageFiles: undefined,
+      });
     });
   });
 });
diff --git a/lib/workers/repository/process/sort.spec.ts b/lib/workers/repository/process/sort.spec.ts
index 17558593fb9cc885f35436e764c789d7b4ff430f..4267c68587ba2fa403f64793b8fa69628a57abf0 100644
--- a/lib/workers/repository/process/sort.spec.ts
+++ b/lib/workers/repository/process/sort.spec.ts
@@ -23,8 +23,12 @@ describe('workers/repository/process/sort', () => {
         },
       ];
       sortBranches(branches);
-      // FIXME: explicit assert condition
-      expect(branches).toMatchSnapshot();
+      expect(branches).toEqual([
+        { prTitle: 'some other pin', updateType: 'pin' },
+        { prTitle: 'some pin', updateType: 'pin' },
+        { prTitle: 'a minor update', updateType: 'minor' },
+        { prTitle: 'some major update', updateType: 'major' },
+      ]);
     });
     it('sorts based on prPriority', () => {
       const branches = [
@@ -50,8 +54,12 @@ describe('workers/repository/process/sort', () => {
         },
       ];
       sortBranches(branches);
-      // FIXME: explicit assert condition
-      expect(branches).toMatchSnapshot();
+      expect(branches).toEqual([
+        { prPriority: 1, prTitle: 'some major update', updateType: 'major' },
+        { prPriority: 0, prTitle: 'some other pin', updateType: 'pin' },
+        { prPriority: -1, prTitle: 'some pin', updateType: 'pin' },
+        { prPriority: -1, prTitle: 'a minor update', updateType: 'minor' },
+      ]);
     });
     it('sorts based on isVulnerabilityAlert', () => {
       const branches = [
@@ -78,8 +86,17 @@ describe('workers/repository/process/sort', () => {
         },
       ];
       sortBranches(branches);
-      // FIXME: explicit assert condition
-      expect(branches).toMatchSnapshot();
+      expect(branches).toEqual([
+        {
+          isVulnerabilityAlert: true,
+          prPriority: -1,
+          prTitle: 'a minor update',
+          updateType: 'minor',
+        },
+        { prPriority: 1, prTitle: 'some major update', updateType: 'major' },
+        { prPriority: 0, prTitle: 'some other pin', updateType: 'pin' },
+        { prPriority: -1, prTitle: 'some pin', updateType: 'pin' },
+      ]);
     });
   });
 });