cypress-image-snapshot icon indicating copy to clipboard operation
cypress-image-snapshot copied to clipboard

Can't get the plugin working with Typescript

Open draunitschke opened this issue 5 years ago • 5 comments

Hi, I already worked through the suggestions in https://github.com/palmerhq/cypress-image-snapshot/issues/13 however I still can't get the plugin working.

We are using TypeScript with WebPack. I also installed @types/jest-image-snapshot

I've added a file index.d.ts in my <"root dir">/types/cypress-image-snapshot folder:

index.d.ts:

import Cypress from 'cypress';
import { MatchImageSnapshotOptions } from 'jest-image-snapshot';

declare global {
  namespace Cypress {
    interface MatchImageSnapshotOptions extends MatchImageSnapshotOptions, Partial<ScreenshotOptions> {}

    interface Chainable {
      matchImageSnapshot(options?: MatchImageSnapshotOptions): void;
      matchImageSnapshot(fileName: string, options?: MatchImageSnapshotOptions): void;
    }
  }
}

Then pointing to the file in tsconfig.json:

tsconfig.json

{
  "compilerOptions": {
    "sourceMap": true,
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "types": [
      "cypress"
    ]
  },
  "include": [
    // spec files
    "cypress/*/*.ts",
    "tests/**/*.ts"
  ],
  "files": [
    "types/cypress-image-snapshot/index.d.ts"
  ]
}

In <"rootDir">/cypress/plugins/index.js I added the required lines for this plugin:

const wp = require('@cypress/webpack-preprocessor');
const {
  addMatchImageSnapshotPlugin,
} = require('cypress-image-snapshot/plugin');


module.exports = (on, config) => {
    const options = {
        webpackOptions: require('../../webpack.config'),
    };
    on('file:preprocessor', wp(options));
    addMatchImageSnapshotPlugin(on, config);

    return getConfigurationByEnvironment(config)
};

So far so good, but when I add in <rootDir>/cypress/support/commands.ts (not commands.js) :


 import { addMatchImageSnapshotCommand } from '../../node_modules/cypress-image-snapshot/command';

addMatchImageSnapshotCommand();

I get an error saying that no declaration for the module "../../node_modules/cypress-image-snapshot/command" could be found and I should try to install @types/cypress-image-snapshot (which does not exist) or that I should add a declaration file (.d.ts), which contains "declare module 'cypress-image-snapshot';"

And in my test specs I can add a cy.matchImageSnapshot command and I do not get a syntax-error in the spec, but when I run cypress I get an error:

TypeError: cy.matchImageSnapshot is not a function

draunitschke avatar Mar 08 '19 08:03 draunitschke

So in my case I am using a dist file for the transpiled javascript and pointing my cypress.json to the specific folders for plugins and support. That way I cheated and did this

// tslint:disable-next-line:no-var-requires
const command = require('cypress-image-snapshot/command')
command.addMatchImageSnapshotCommand({
  customDiffConfig: {threshold: 5.0}, // threshold for each pixel
  failureThreshold: 5.0, // threshold for entire image
  failureThresholdType: 'percent', // percent of image or number of pixels
});

And it doesn't pop an error during transpile.

jordandlaman avatar Mar 14 '19 16:03 jordandlaman

I had the same problems and found a solution.

I get an error saying that no declaration for the module "../../node_modules/cypress-image-snapshot/command" could be found and I should try to install @types/cypress-image-snapshot (which does not exist) or that I should add a declaration file (.d.ts), which contains "declare module 'cypress-image-snapshot';"

You need to add a custom module definition file for that.

And in my test specs I can add a cy.matchImageSnapshot command and I do not get a syntax-error in the spec, but when I run cypress I get an error:

Currently there's an issue with the typescript preprocessor that causes this behavior: https://github.com/nrwl/nx/issues/1609. As a workaround you can declare a type for matchImageSnapshot in support/commands.ts and you have to import that in your test case.

The following setup worked for me:

integration/signin.ts:

import '../support';

describe('signin page', () => {
  beforeEach(() => {
    cy.visit('/signin');
  });

  it('should match the design', () => {
    cy.matchImageSnapshot();
  });
});

support/index.ts:

import './commands';

support/commands.ts:

import { addMatchImageSnapshotCommand, SnapshotOptions } from 'cypress-image-snapshot/command';

addMatchImageSnapshotCommand();

declare global {
  namespace Cypress {
    interface Chainable {
      /**
       * Screenshot test the current page.
       * @param name file name of the screenshot
       * @param options general options
       */
      matchImageSnapshot(name: string, options?: SnapshotOptions): Chainable<Element>;

      /**
       * Screenshot test the current page.
       * @param options general options
       */
      matchImageSnapshot(options?: SnapshotOptions): Chainable<Element>;
    }
  }
}

support/modules.d.ts:

declare module 'cypress-image-snapshot/command' {
  type SnapshotOptions = Partial<
    Cypress.Loggable &
    Cypress.Timeoutable &
    Cypress.ScreenshotOptions &
    import('jest-image-snapshot').MatchImageSnapshotOptions
  >;

  export const addMatchImageSnapshotCommand: (options?: SnapshotOptions) => void;
}

kremerd avatar Oct 17 '19 10:10 kremerd

I went ahead and added typings for folks to use: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/41222

Now, all you need to do is yarn add @types/cypress-image-snapshot -D for this plugin to work with TypeScript!

Keysox avatar Dec 27 '19 18:12 Keysox

should issue be closed?

also, adding types.ts instead of index.d.ts worked for me, but decided to use Keysox's types instead

prmichaelsen avatar Jan 24 '20 01:01 prmichaelsen

I went ahead and added typings for folks to use: DefinitelyTyped/DefinitelyTyped#41222

Now, all you need to do is yarn add @types/cypress-image-snapshot -D for this plugin to work with TypeScript!

@Keysox This man is doing god's work! :clap: :clap: :clap:

ivoiv avatar Feb 03 '21 16:02 ivoiv