Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error when running all snapshots #10

Closed
tomitrescak opened this issue Dec 20, 2018 · 24 comments
Closed

Error when running all snapshots #10

tomitrescak opened this issue Dec 20, 2018 · 24 comments
Labels
cypress bug Issue caused by bug in Cypress wontfix This will not be worked on

Comments

@tomitrescak
Copy link

Hi, thanks for the amazing plugin!!!

There is a possible bug, as when I run all tests in the cypress browser I receive following error:

CypressError: cy.task('cypress-plugin-snapshot:matchText') failed with the following error:

> Error: Cannot load snapshot file. File "__snapshots__/__all.snap does not contain valid JSON or javascript
@meinaart
Copy link
Owner

This was quite hard to fix but I managed it. Probably need to contact Cypress about why Cypress.spec is not correct when running all tests. Or why they don't populate the "file" field in Mocha.

@meinaart
Copy link
Owner

meinaart commented Jan 2, 2019

@tomitrescak can you verify it works?

meinaart pushed a commit that referenced this issue Jan 11, 2019
…breaks other functionality (Reopens #10) (Fixes #14)
@meinaart
Copy link
Owner

I will remove the fix, it was causing other issues and the real reason is a bug in Cypress:
cypress-io/cypress#3090

@meinaart meinaart reopened this Jan 11, 2019
meinaart pushed a commit that referenced this issue Jan 11, 2019
…breaks other functionality (Reopens #10) (Fixes #14)
@sgnl
Copy link
Contributor

sgnl commented May 1, 2019

IMO this issue should be mentioned on the README as it's a huge blocker for me, I only found out after implementing and writing tests (using .only while writing tests) to find the error in the GUI test runner after I ran all my tests which made all my work previously useless.

Please consider adding an eye-catching warning or 'caveat' section which mentions this issue so that other users of this package will not share the same experience I had or at the very least, know of this important bug.

Hope Cypress gets the fix in soon, :fingers

(added a PR as a suggestion for a new section in the README file: #37)

meinaart pushed a commit that referenced this issue May 2, 2019
adds caveat section which highlights #10 cypress-io/cypress/3090
@bahmutov
Copy link
Contributor

So the workaround I can offer for now is to fix Cypress.spec object by looking at the __filename in each spec file. Here is the code to place into cypress/support/index.js. It is a utility function that forms Cypress.spec from passed filename

// cypress/support/index.js
export const fixCypressSpec = filename => () => {
  const path = require('path')
  const relative = filename.substr(1) // removes leading "/"
  const projectRoot = Cypress.config('projectRoot')
  const absolute = path.join(projectRoot, relative)
  Cypress.spec = {
    absolute,
    name: path.basename(filename),
    relative
  }
}

From each spec file (that wants to use snapshots)

import { fixCypressSpec } from '../support'

beforeEach(fixCypressSpec(__filename))

I have been playing with this in https://github.com/bahmutov/objection-example using this approach to run all specs with snapshots

@CSchulz
Copy link

CSchulz commented Aug 15, 2019

Seems not to be working if you are using TypeScript.

@meinaart meinaart added cypress bug Issue caused by bug in Cypress wontfix This will not be worked on labels Aug 30, 2019
@meinaart
Copy link
Owner

Investigate if this would work as a possible fix.

Cypress.mocha.getRunner().suite.ctx.currentTest.title

@diggabyte
Copy link
Contributor

diggabyte commented Jan 28, 2020

Seems not to be working if you are using TypeScript.

+1 @CSchulz

When using typescript, the workaround mentioned by @bahmutov does not work, as the __filename resolves to index.js, which is a result of the fact that typescript is being transpiled to js, so (depending on your setup), it will reference the file in which the ts -> js transformation took place (plugins/index.js, for example)

@georg-malahov
Copy link

Typescript users, just pass the exact spec file path to beforeEach(fixCypressSpec('/cypress/integration/spec.ts')). 👍

FYI @CSchulz @meinaart

@webdevisme
Copy link

Any light at the end of this tunnel? The suggested fixes don't seem to work for me :(

@dploeger
Copy link

dploeger commented Apr 7, 2020

Especially for Typescript users, it's easier to use a custom command for the workaround like this:

Cypress.Commands.add('fixCypressSpec', (filename) => {
    const path = require('path')
    const relative = filename.substr(1) // removes leading "/"
    const projectRoot = Cypress.config('projectRoot')
    const absolute = path.join(projectRoot, relative)
    Cypress.spec = {
        absolute,
        name: path.basename(filename),
        relative
    }
})

add it to the index.d.ts like this:

/// <reference types="cypress" />

declare namespace Cypress {
  interface Chainable {
    fixCypressSpec(filename: string): void
  }
}

and then in the spec in a beforeEach:

describe('my test', () => {
  beforeEach(() => {
    cy.fixCypressSpec('/cypress/integration/mytest_spec.ts')
(...)

@skivol
Copy link

skivol commented Jul 21, 2020

+ if using cypress-cucumber-preprocessor, then one could write a "Given" step like so:

Given('I use snapshots for {string} feature', (fileName) => {
	cy.fixCypressSpec(fileName);
});

And in specs/features that use the snapshotting specify that:
Given I use snapshots for "/cypress/integration/mytest.feature" feature

But still would be nice to avoid all these workarounds ;)

@bmcgary
Copy link

bmcgary commented Jul 21, 2020

I put the fix suggested by @bahmutov and it seems to work. But it looks like an error is thrown from getSpec.js,
if (Cypress.spec.absolute === '__all') { throw new Error('cypress-plugin-snapshots does not work when running all tests, this will be fixed once this bug is resolved: https://github.com/cypress-io/cypress/issues/3090'); }

If I comment this out the test works fine. The question is how do you handle this for others on the team? Tell them to npm install then go into node_modules and comment out the offending line? Is anyone else doing something more streamlined?

@Winggo
Copy link

Winggo commented Aug 12, 2020

I put the fix suggested by @bahmutov and it seems to work. But it looks like an error is thrown from getSpec.js,
if (Cypress.spec.absolute === '__all') { throw new Error('cypress-plugin-snapshots does not work when running all tests, this will be fixed once this bug is resolved: https://github.com/cypress-io/cypress/issues/3090'); }

If I comment this out the test works fine. The question is how do you handle this for others on the team? Tell them to npm install then go into node_modules and comment out the offending line? Is anyone else doing something more streamlined?

I had this problem too. Solved the issue by forking the plugin, modifying the fork by commenting out those lines that throw the error, and using that forked module in package.json.

@krisraven
Copy link

When I apply @bahmutov's workaround - it works well, thanks for this 😄 however, after running the all the test specs, a folder called "ypress" gets created (ie.
ypress/integration/__snapshots__/myTestSpecName.spec.js.snap). I was wondering if this is correct or is a side effect of the workaround, as it has not been mentioned here.

@441N143G
Copy link

There is no reason to manually specify the path: cy.fixCypressSpec(__filename);

@nielsboecker-zuhlke
Copy link

nielsboecker-zuhlke commented Nov 16, 2020

Thanks @dploeger and @441N143G, that's really helpful.

Btw, TypeScript users will also want to install @types/node and add it to their tsconfig in order for __filename to work:

{
    ...,
    "types": ["cypress", ..., "@types/node"],
}

Also, @krisraven, I have had the same. I believe the issue here is that you may have provided cypress/integration/mytest_spec.ts instead of /cypress/integration/mytest_spec.ts (no leading slash). This is also the case when using __filename. With this argument, the one line in the workaround which truncates the first character is not required anymore:

  const relative = filename.substr(1); // removes leading "/"

@franck-mahieu
Copy link

franck-mahieu commented Mar 31, 2021

When I apply @bahmutov's workaround - it works well, thanks for this 😄 however, after running the all the test specs, a folder called "ypress" gets created (ie.
ypress/integration/__snapshots__/myTestSpecName.spec.js.snap). I was wondering if this is correct or is a side effect of the workaround, as it has not been mentioned here.

I experienced the same thing, to not have "ypress" folder, you juste have to remove substr(1) ;)

@rdadoune
Copy link

This solution works for me universally with TypeScript:

support/snapshotPatch.ts:

import { basename } from 'path';

declare global {
  // eslint-disable-next-line @typescript-eslint/no-namespace
  namespace Cypress {
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    interface Chainable<Subject> {
      /**
       * Patch cypress-plugin-snapshots
       *
       * @returns {void}
       */
      fixCypressSpec(): void;
    }
  }
}

Cypress.Commands.add('fixCypressSpec', function () {
  const { absoluteFile, relativeFile } = this.test.invocationDetails;
  Cypress.spec = {
    ...Cypress.spec,
    absolute: absoluteFile,
    name: basename(absoluteFile),
    relative: relativeFile,
  };
});

support/index.ts:

import './support/snapshotPatch.ts';

beforeEach(() => {
  cy.fixCypressSpec();
});

@sergei-shneider
Copy link

This solution works for me universally with TypeScript:

support/snapshotPatch.ts:

import { basename } from 'path';

declare global {
  // eslint-disable-next-line @typescript-eslint/no-namespace
  namespace Cypress {
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    interface Chainable<Subject> {
      /**
       * Patch cypress-plugin-snapshots
       *
       * @returns {void}
       */
      fixCypressSpec(): void;
    }
  }
}

Cypress.Commands.add('fixCypressSpec', function () {
  const { absoluteFile, relativeFile } = this.test.invocationDetails;
  Cypress.spec = {
    ...Cypress.spec,
    absolute: absoluteFile,
    name: basename(absoluteFile),
    relative: relativeFile,
  };
});

support/index.ts:

import './support/snapshotPatch.ts';

beforeEach(() => {
  cy.fixCypressSpec();
});

if i use it globally it saves all the snapshots as index.ts.snap, but works if i call it as a command within tests, which i feel is preferable anyway

@rdadoune
Copy link

@SSDlm Thanks for pointing that issue out! That's a bug I discovered shortly after I posted the above solution. I meant to come back here and update but never did 😖

@edimitchel
Copy link

The maintenance of this package is freezed.. I was added to the project but I didn't have any right for merge PR or update project settings (CICD is broken)..

@knownasilya
Copy link

Could this plugin run the fix (workaround) internally?

@chrisbraddock
Copy link

if i use it globally it saves all the snapshots as index.ts.snap, but works if i call it as a command within tests, which i feel is preferable anyway

If you change:

const { absoluteFile, relativeFile } = this.test.invocationDetails;

to:

const { absoluteFile, relativeFile } = this.currentTest.invocationDetails;

it works in a global beforeEach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cypress bug Issue caused by bug in Cypress wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests