Cypress: Ability to define multiple 'on' events in pluginsFile without overwriting previously defined

Created on 30 Sep 2019  路  3Comments  路  Source: cypress-io/cypress

Current behavior:

The last declaration of the on before hook is being executed using cypress open

Desired behavior:

In this example, i'm expecting both before browser launch's to execute.

Steps to reproduce: (app code and test code)

Add following code to plugins/index.js

module.exports = (on, config) => {
  on('before:browser:launch', (browser = {}, args) => {
    console.log('WONT GET CALLED', args);
    return args;
  });

  on('before:browser:launch', (browser = {}, args) => {
    console.log('WILL GET CALLED', args);
    return args;
  });
};

Versions

v3.4.1, MacOS Mojave, Chrome / Electron

proposal 馃挕 plugins 鈿欙笍 enhancement

Most helpful comment

To add to this issue, I agree that it would be useful to have multiple listeners. Currently if a plugin I use implements the before:browser:launch hook then it means I cannot also use this hook.

An example is when using one of Cypress' recommended visual regression plugins https://github.com/meinaart/cypress-plugin-snapshots.

The plugin has to be set up as follows:

const { initPlugin } = require('cypress-plugin-snapshots/plugin');

module.exports = (on, config) => {
  initPlugin(on, config);
  return config;
};

In initPlugin the before:browser:launch hook is used.

But in my plugins/index.js file I also want to use this hook in order to set the browser window size argument. So I tried this:

const { initPlugin } = require('cypress-plugin-snapshots/plugin')

module.exports = (on, config) => {
  on('before:browser:launch', (browser = {}, launchOptions) => {
    if (browser.name === 'chrome' || browser.name === 'chromium' || browser.name === 'canary') {
      launchOptions.args.push('--window-size=1200,800')
    }
    return launchOptions
  })

  initPlugin(on, config)
  return config
}

But only the last listener gets called. I have seen this method of plugin initialisation across several visual regression plugins suggesting this is a common way of getting plugin consumers to use the plugin, but it means that any hooks the plugin uses can't then be used by other plugins.

All 3 comments

@Alastair-Spencer I'm a little unsure on the usecase of having 2 listeners set up for before:browser:launch, the second before:browser:launch is overwriting the initial before:browser:launch. The before:browser:launch will only be called once.

Please explain the usecase for needing 2 listeners. You may also want to utilize some of the following methods to bind or unbind from the events. https://docs.cypress.io/api/events/catalog-of-events.html#Binding-to-Events

@jennifer-shehane

I apologise for not making the issue a little clearer - If I was to have multiple plugins hooking from the same event, this would prevent the first one from running and cause a race condition.

They look odd being placed together in this file but this is where plugins are initialised and will hook off these events being fired. Hope that helps! 馃憤

To add to this issue, I agree that it would be useful to have multiple listeners. Currently if a plugin I use implements the before:browser:launch hook then it means I cannot also use this hook.

An example is when using one of Cypress' recommended visual regression plugins https://github.com/meinaart/cypress-plugin-snapshots.

The plugin has to be set up as follows:

const { initPlugin } = require('cypress-plugin-snapshots/plugin');

module.exports = (on, config) => {
  initPlugin(on, config);
  return config;
};

In initPlugin the before:browser:launch hook is used.

But in my plugins/index.js file I also want to use this hook in order to set the browser window size argument. So I tried this:

const { initPlugin } = require('cypress-plugin-snapshots/plugin')

module.exports = (on, config) => {
  on('before:browser:launch', (browser = {}, launchOptions) => {
    if (browser.name === 'chrome' || browser.name === 'chromium' || browser.name === 'canary') {
      launchOptions.args.push('--window-size=1200,800')
    }
    return launchOptions
  })

  initPlugin(on, config)
  return config
}

But only the last listener gets called. I have seen this method of plugin initialisation across several visual regression plugins suggesting this is a common way of getting plugin consumers to use the plugin, but it means that any hooks the plugin uses can't then be used by other plugins.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jennifer-shehane picture jennifer-shehane  路  3Comments

szabyg picture szabyg  路  3Comments

jennifer-shehane picture jennifer-shehane  路  3Comments

zbigniewkalinowski picture zbigniewkalinowski  路  3Comments

simonhaenisch picture simonhaenisch  路  3Comments