haim-io / cypress-image-diff

Visual regression test with cypress
MIT License
240 stars 62 forks source link

In projects with cucumber, the standard json report is not generated #183

Closed edme88 closed 7 months ago

edme88 commented 9 months ago

In a project with cypress-cucumber, I have the following configuration:

In cypress.confog.js:

const { defineConfig } = require("cypress");
const createBundler = require("@bahmutov/cypress-esbuild-preprocessor");
const addCucumberPreprocessorPlugin =
  require("@badeball/cypress-cucumber-preprocessor").addCucumberPreprocessorPlugin;
const createEsbuildPlugin =
  require("@badeball/cypress-cucumber-preprocessor/esbuild").createEsbuildPlugin;
const getCompareSnapshotsPlugin = require("cypress-image-diff-js/dist/plugin");

module.exports = defineConfig({
  env: {
    TAGS: "not @ignore",
  e2e: {
    specPattern: "cypress/e2e/features/**/*.feature",
    async setupNodeEvents(on, config) {
      const bundler = createBundler({
        plugins: [createEsbuildPlugin(config)],
      });
      on("file:preprocessor", bundler);
      await addCucumberPreprocessorPlugin(on, config);
      return getCompareSnapshotsPlugin(on, config);
    },
  },
  viewportWith: 1536,
  viewportHeight: 960
});

In cypress/support/e2e.js:

const compareSnapshotCommand = require("cypress-image-diff-js/dist/command");
compareSnapshotCommand();

In package.json:

"cypress-cucumber-preprocessor": {
    "stepDefinitions": "cypress/e2e/step_definitions/**.js",
    "cucumberautocomplete.steps": "cypress/e2e/**.js",
    "html": {
      "enabled": true,
      "output": "reports/cucumber-report.html"
    },
    "messages": {
      "enabled": true,
      "output": "reports/messages.ndjson"
    },
    "json": {
      "enabled": true,
      "output": "reports/log.json"
    }
  }

Since I install and use cypress-image-diff-js, only the ndjson report is generated. json report abd html report are not generated.

There is something wrong with my configuration? Or there is a problem with the integration of cypress-image diff in a cucumber project?

kien-ht commented 9 months ago

Hi @edme88. It looks like the same Cypress multiple on events issue as #177

kien-ht commented 9 months ago

So basically we can't listen on the same on events more than once, and often time when we use many plugins together, this would make the internal plugin functions broken. Here is the quick workaround:

// cypress.config.js
// define OnWrapper
const isObject = require('lodash/isObject')
const merge = require('lodash/merge')

class OnWrapper {
  constructor(on) {
    this.listeners = {}
    this.originalOn = on
  }

  on(event, handler) {
    if (event === 'task') return this.originalOn('task', handler)

    if (this.listeners[event] === undefined) {
      this.listeners[event] = []
    }

    return this.listeners[event].push(handler)
  }

  forward() {
    Object.entries(this.listeners).forEach(([event, handlers]) => {
      this.originalOn(event, async (...args) => {
        let result = {}
        for (const handler of handlers) {
          const res = await handler(...args)
          // some `on` events need to return the configuration object
          // merge them if we can, otherwise the last one will be returned
          result = isObject(res) ? merge(result, res) : res
        }
        return result
      })
    })
  }
}

// define cypress config
module.exports = defineConfig({
  e2e: {
    async setupNodeEvents(cypressOn, config) {
      const wrapper = new OnWrapper(cypressOn)
      wrapper.on("file:preprocessor", () => {
        console.log('my file:preprocessor event')
      });

      await addCucumberPreprocessorPlugin(wrapper.on.bind(wrapper), config);
      const cypressImageDiffConfig = getCompareSnapshotsPlugin(wrapper.on.bind(wrapper), config);

      // remember to forward all events to the original cypress on
      wrapper.forward()
      return cypressImageDiffConfig
    }
  }
});
edme88 commented 9 months ago

Thanks in adcance! I will try to apply this solution 👍

github-actions[bot] commented 8 months ago

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] commented 7 months ago

This issue was closed because it has been inactive for 30 days since being marked as stale.