cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
47.01k stars 3.18k forks source link

Support for multiple preprocessors #5832

Open johnknoop opened 4 years ago

johnknoop commented 4 years ago

I haven't found any information in the docs about support for multiple preprocessors.

I've used the webpack preprocessor in some projects, and the cucumber proprocessor i others. For my new project, I'd like to use them both.

I tried adding two `on('file:preprocessor') like this:

    on('file:preprocessor', cucumber())
    on('file:preprocessor', wp({
        webpackOptions: require('../../webpack.config'),
    }))

but then it doesn't preprocess the .feature files.

Any advice?

johnknoop commented 4 years ago

Nevermind, I managed to solve it.

This works:

    on('file:preprocessor', file => {
        return file.filePath.includes('.feature')
            ? cucumber()(file)
            : wp({
                webpackOptions: webpackConfig,
            })(file)
    })
Maximus1285 commented 4 years ago

Actually, I do need to support more than one preprocessor at the same time. Is it possible?

csvan commented 4 years ago

Wondering the same thing as @Maximus1285

silversonicaxel commented 3 years ago

no answers?

jennifer-shehane commented 3 years ago

We'd like to understand the use case for using multiple preprocessors at the same time. Can anyone provide examples on what you're doing with multiple ones? Which ones you're using together? Thanks!

silversonicaxel commented 3 years ago

this is an example

const cucumber = require('cypress-cucumber-preprocessor').default
const webpack = require('@cypress/webpack-preprocessor')

const port = process.env.PORT

module.exports = (on, config) => {
  on('file:preprocessor', cucumber())

  const webpackOptions = {
    webpackOptions: require('../webpack.config.js')
  }
  on('file:preprocessor', webpack(webpackOptions))

  config.baseUrl = `http://localhost:${port}`
  return config
}
dthisner commented 3 years ago

Here is another example:

const rollupPreprocessor = require('cypress-rollup-preprocessor')
const cucumber = require('cypress-cucumber-preprocessor').default

module.exports = (on, config) => {
  on('file:preprocessor', cucumber())
  const options = {
    rollupOptions: require('../../rollup.config.js')
  }

  on('file:preprocessor', rollupPreprocessor(options))

  return config
}
tstackhouse commented 3 years ago

Chiming in with another example:

const { preprocessTypescript } = require('@nrwl/cypress/plugins/preprocessor');
const tagify = require('cypress-tags');

module.exports = (on, config) => {
  on('file:preprocessor', tagify(config));
  on('file:preprocessor', preprocessTypescript(config));

  return config;
};

This fails, but it would be nice to figure out how to have it not fail.

beamery-tomht commented 3 years ago

👍 have a similar use case for tagify + typescript. Looking to also experiment with other pre-processors such as swc builds

Haven't tried piping the typescript output into tagify but I imagine composing the preprocessors would work

replygirl commented 3 years ago

example for nuxt:

const cucumber = require('cypress-cucumber-preprocessor').default
const { plugin: nuxtPlugin } = require('cypress-nuxt')

module.exports = async (on, config) => {
  on('file:preprocessor', cucumber())
  on('file:preprocessor', await nuxtPlugin())
}
vjmaiky commented 3 years ago

any updates on this topic? i'm trying to use cucumber preprocessor and select test for example:

const allureWriter = require('@shelex/cypress-allure-plugin/writer');
const cucumber = require('cypress-cucumber-preprocessor').default
const selectTestsWithGrep = require('cypress-select-tests/grep')
module.exports = (on, config) => {

  on('file:preprocessor', cucumber());

  on('file:preprocessor', selectTestsWithGrep(config));

  allureWriter(on, config);

  return config;

}
bahmutov commented 3 years ago

@vjmaiky I advise everyone to move away from cypress-select-tests and instead use https://github.com/bahmutov/cypress-grep that does not require a preprocessor

smcenlly commented 3 years ago

Any idea of if/when this might be available? We are investigating the best way to enable Wallaby.js for people using Cypress.

To provide its features, Wallaby needs to modify the resulting JavaScript code. Perhaps we are mistaken but our assumption is that many (if not most) projects will already have a preprocessor in place. Depending on the nature of the preprocessor we may need to execute either before or after it (e.g. after for TypeScript but before for bundlers).

jennifer-shehane commented 3 years ago

This is not currently being worked on, but we'd be welcome to reviewing a PR request that makes this functionality possible.

mlberkow commented 3 years ago

@bahmutov using cypress-grep is slow. My project has 60 spec files and the 10-30 seconds it takes to open each file and parse it to decide whether or not there are tests to run is a bit of a showstopper. Setting up an @smoke tag takes roughly 19 min of test execution time to run the smoke tests, but the total time to run through all the files and determine which ones are actually needed makes the test run time almost 40 minutes. It's just not saving that much time in the end.

bahmutov commented 3 years ago

I say that waiting for 15-30 seconds for the spec to simply load is not normal and should be looked at to speed it up.

Sent from my iPhone

On Oct 18, 2021, at 16:51, mlberkow @.***> wrote:

 @bahmutov using cypress-grep is slow. My project has 60 spec files and the 10-30 seconds it takes to open each file and parse it to decide whether or not there are tests to run is a bit of a showstopper. Setting up an @smoke tag takes roughly 19 min of test execution time to run the smoke tests, but the total time to run through all the files and determine which ones are actually needed makes the test run time almost 40 minutes. It's just not saving that much time in the end.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

salvag-ntt commented 2 years ago

In my case I am in need to use 2 pre-processors. One to be able to parse feature files, the other to be able to import application code (the devs have a few functions that are really useful to get some data I though it was possible to reuse). Unfortunately I keep getting this:

Error: Can't walk dependency graph: Cannot find module '@src/services/api/ClientBuilder' from '/home/gr4ce/workspace/.../src/services/api/product-categories.ts'

Looks like the fact that I am importing a file from src/services/api/... folder that uses the syntax

import { apiClient, BASE_URL } from '@src/services/api/ClientBuilder'

is not really understood by Cypress and I was hoping for the pre-processor to handle it... no joy!

badeball commented 2 years ago

Hi, current maintainer of the Cucumber preprocessor here. None of the mentioned use-cases concerning cypress-cucumber-preprocessor are valid. You simply don't need multiple preprocessors. OP posts something like this

on('file:preprocessor', cucumber())
on('file:preprocessor', wp({
  webpackOptions: require('../../webpack.config'),
}))

.. but what you would typically do here instead is to modify webpack.config.js to contain a loader similar to that shown here.

omelnik commented 2 years ago

Hi there. I'd like to use both of these preprocessors cypress-tags and @cypress/webpack-preprocessor in my project. Any suggestion on how to overcome limitations? Thanks!

import webpackPreprocessor from '@cypress/webpack-preprocessor';
import { tagify } from 'cypress-tags';
import { cypressWebpackConfig } from '../webpack.config';

on('file:preprocessor', webpackPreprocessor({ webpackOptions: cypressWebpackConfig }));
on('file:preprocessor', tagify(config));
linavegiene commented 1 year ago

I wanted to use cypress-terminal-report and cypress-tags. Any advice?

lmiller1990 commented 1 year ago

This issue (https://github.com/cypress-io/cypress/issues/26167) leads to a similar request to combine our webpack-preprocessor (from npm) with cypress-tags, which uses browserify-preprocessor.

Docs for preprocessors: https://docs.cypress.io/api/plugins/preprocessors-api

I guess what a lot of people here are looking for is something like

on('file:preprocessor', pipe(
  processor1,
  processor2
))

A preprocessor just takes some code and processes it - it should be possible to combine them in userland. The example from this post actually builds a new preprocessor on top of an existing on.

on('file:preprocessor', (obj) => {
  const { filePath } = obj

  // do something with file
  const result =  cypressTagify(file)

  // write to a temp file to comply w/ preprocessor architecture
  fs.writeFileSync(`/tmp/whatever.js')

  // do something else
  const result2 = processWithWebpack({ filePath: '/tmp/whatever.js' })

  return result2
})

Just showing an example -- this won't work right now, I just wrote it to demonstrate. I think you should be able to combine these in some fashion right now. This is likely what would be implemented if we had a pipe like function in the core repo, anyway.

Note: This will like harm performance - now you have to preprocess everything twice.

J7mbo commented 2 months ago

Another example here... surprised there's no interest here.

Using cucumber() and also cypress-await.