jest: Inline Snapshots with non literal can't be found

🐛 Bug Report

When I try to add a test with an inline snapshot:

it('works with inline snapshots', () => {
  expect({a: 1}).toMatchInlineSnapshot();
});

I get this error:

Jest: Couldn't locate all inline snapshots.

I can’t repro this in repl.it because that version does not have inline snapshots yet:

TypeError: expect(...).toMatchInlineSnapshot is not a function

I cloned the github repo and added a test to inline_snapshots.test.js

test('saveInlineSnapshots() replaces empty function call with a template literal for objects', () => {
  const filename = path.join(__dirname, 'my.test.js');
  fs.readFileSync = (jest.fn(
    () => `expect({a: 'a'}).toMatchInlineSnapshot();\n`,
  ): any);

  saveInlineSnapshots(
    [
      {
        frame: {column: 11, file: filename, line: 1},
        snapshot: `{a: 'a'}`,
      },
    ],
    prettier,
    babelTraverse,
  );

  expect(fs.writeFileSync).toHaveBeenCalledWith(
    filename,
    "expect({a: 'a'}).toMatchInlineSnapshot(`{a: 'a'}`);\n",
  );
});

and this reproes the issue:

 FAIL  packages/jest-snapshot/src/__tests__/inline_snapshots.test.js
  ✓ saveInlineSnapshots() replaces empty function call with a template literal (67ms)
  ✕ saveInlineSnapshots() replaces empty function call with a template literal for objects (19ms)
  ✓ saveInlineSnapshots() replaces existing template literal - babylon parser (4ms)
  ✓ saveInlineSnapshots() replaces existing template literal - flow parser (2ms)
  ✓ saveInlineSnapshots() replaces existing template literal - typescript parser (2ms)
  ✓ saveInlineSnapshots() replaces existing template literal with property matchers (3ms)
  ✓ saveInlineSnapshots() throws if frame does not match (2ms)
  ✓ saveInlineSnapshots() throws if multiple calls to to the same location (2ms)
  ✓ saveInlineSnapshots() uses escaped backticks (2ms)

  ● saveInlineSnapshots() replaces empty function call with a template literal for objects

    Jest: Couldn't locate all inline snapshots.

      at Object.parse (packages/jest-snapshot/src/inline_snapshots.js:168:11)

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 11
  • Comments: 28 (18 by maintainers)

Commits related to this issue

Most upvoted comments

What helped for me with Jest 27 and typescript is to add sourceMap: true in my tsconfig.json. It immediately fixed the problem.

ts-jest used to have it on by default, but changed it in v27.

@karlmarxlopez mind setting up a quick repository we could pull down and check?

@SimenB I don’t have a minimal repro yet. I can reproduce it in react’s codebase though:

$ git clone --branch jest-repro-locate-inline-snapshots https://github.com/eps1lon/react.git
$ yarn install
$ yarn build-for-devtools
$ yarn test-build-devtools treeContext

Produces

 FAIL  packages/react-devtools-shared/src/__tests__/treeContext-test.js
  ● Test suite failed to run

    Jest: Couldn't locate all inline snapshots.

      at Object.parse (node_modules/jest-snapshot/build/inline_snapshots.js:321:11)
      at Object.parse (node_modules/prettier/index.js:9739:19)
      at coreFormat (node_modules/prettier/index.js:13252:23)
      at format (node_modules/prettier/index.js:13510:73)
      at formatWithCursor (node_modules/prettier/index.js:13526:12)
      at node_modules/prettier/index.js:44207:15
      at Object.format (node_modules/prettier/index.js:44226:12)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        3.05s
Ran all test suites matching /treeContext/i.

Applying

diff --git a/packages/react-devtools-shared/src/__tests__/treeContext-test.js b/packages/react-devtools-shared/src/__tests__/treeContext-test.js
index 3f97970d63..55265dd911 100644
--- a/packages/react-devtools-shared/src/__tests__/treeContext-test.js
+++ b/packages/react-devtools-shared/src/__tests__/treeContext-test.js
@@ -943,7 +943,7 @@ describe('TreeListContext', () => {
       );
 
       utils.act(() => TestRenderer.create(<Contexts />));
-      expect({state, store}).toMatchInlineSnapshot();
+      expect({ state: state, store: store }).toMatchInlineSnapshot();
 
       selectNextErrorOrWarning();
       let statefulStore = {state, store};

Fixes the issue.

So it looks like the stack trace is based on the code after transpilation (particularly after @babel/plugin-transform-shorthand-properties).

I’m seeing this problem as well:

Jest: 27.4.7 ts-jest: 27.1.2

repo and branch with error : https://github.com/rkesters/typescript-json-validator/tree/rkesters/deps2

run: npx jest index

I have sourceMap set to true.

Error Message:

FAIL src/tests/index.test.ts ● Test suite failed to run

Jest: Couldn't locate all inline snapshots.

  at traverseAst (node_modules/jest-snapshot/build/InlineSnapshots.js:377:11)

Finding myself here again, having gotten burned by this issue while trying to rewrite some other React DevTools tests to use inline snapshots. They’re so much better (when they work!)

As far as I can tell the cause of https://github.com/facebook/jest/issues/6744#issuecomment-748042991 is missing source-maps.

React’s jest config has a custom preprocessor that transpiles the files without source maps. So expect({state, store}).toMatchInlineSnapshot(); will be transpiled to expect({ state: state, store: store }).toMatchInlineSnapshot(); which means that the generated snapshot will point to a different column (it’s using the stack trace) compared to the original source code.

I could fix https://github.com/facebook/jest/issues/6744#issuecomment-748042991 with

diff --git a/scripts/jest/preprocessor.js b/scripts/jest/preprocessor.js
index f57005c940..32836141a3 100644
--- a/scripts/jest/preprocessor.js
+++ b/scripts/jest/preprocessor.js
@@ -86,7 +86,10 @@ module.exports = {
       return babel.transform(
         src,
         Object.assign(
-          {filename: path.relative(process.cwd(), filePath)},
+          {
+            filename: path.relative(process.cwd(), filePath),
+            sourceMaps: isTestFile ? 'inline' : false,
+          },
           babelOptions,
           {
             plugins,

But I don’t understand how jest creates accurate frames for other cases. For example expect({stat, store}).toMatchInlineSnapshot(); will throw a ReferenceError that points to the correct column.