Cypress: Monorepo with multiple apps usage - allow passing of `projects` array to `cypress run`

Created on 18 Jul 2018  路  11Comments  路  Source: cypress-io/cypress

Say I have a monorepo with multiple apps which share libs. If i modify a shared lib and want to test if my apps pass the tests, what is the best approach?

- packages
    - app-1
        - cypress
    - app-2
        - cypress
    - shared-library-1
    - shared-library-2
  • Can I have cypress search for multiple integrationFolders so that a single test run will test all my apps?
  • Maybe I could use a cypress dir in the monorepo root, then have symlinks to the different cypress/integration folders in each app in the monorepo?
cli proposal 馃挕 feature

Most helpful comment

@vjpr @jennifer-shehane This isn't complete workaround because it won't handle the case where tests have different support files, fixtures, or different configurations in cypress.json.

Can we re-open this issue?

We also use a monorepo at Airbnb, that looks something like:

projects/
  --  projectA
      -- cypress.json
      -- cypress
          -- integration
          -- support
          -- fixtures
              -- user.json

  --  projectB
      -- cypress.json
      -- cypress
          -- integration
          -- support
          -- fixtures
              -- user.json

You can symlink all the integration tests but that will still break on any test with its own fixture files or custom commands in the support directory. We also use mutually exclusive support commands, some teams choose to convert fetch to XHR, while others don't.

Right now, we invoke Cypress multiple times for a project in CI, and this comes with unexpected problems, eg. xvfb exitting non-zero (that could be fixed by https://github.com/cypress-io/cypress-docker-images/issues/54#issuecomment-487060555).


It would be great if cypress run + open supported projects by allowing you to pass in multiple directories that contained their own cypress.json files -- this is similar to Jest's projects:

See: https://jestjs.io/docs/en/configuration#projects-arraystring--projectconfig

projects [array]
Default: undefined
When the projects configuration is provided with an array of paths or glob patterns, Jest will run tests in all of the specified projects at the same time. This is great for monorepos or when working on multiple projects at the same time.

That way, in the root cypress.json we could specify the projects that we want to invoke cypress for like this:

{
  "defaultUrl": "https://www.airbnb.com",
  "projects": ["projects/projectA", "projects/projectB"],
}

And then when invoking cypress at the root of a monorepo, we can run all projects, or pick specific ones by using a flag to override the config like: --projects frontend/projectA.

All 11 comments

  • The integrationFolder ~accepts a glob~ (edit: no it doesn't), if you were able to specify something that works for you there.
  • You may also find use in the --spec flag to specify what spec files to run.

I also feel like our new changes coming out in our next release, introducing 'parallelism' will be really helpful to you. You'll be able to specify 'groups' so that you can have several cypress run commands run in one CI build. So, like:

my CI's yml file or config

// job 1
cypress run --group=app-1 --config integrationFolder=app-1/cypress/integration
// job 2
cypress run --group=app-2 --config integrationFolder=app-2/cypress/integration

You could essentially do this today without the --group flag, but they will display as 2 runs in the Dashboard.

The integrationFolder accepts a glob...

This glob doesn't seem to work: **/cypress/integration/**/*.

Or this: **/cypress/integration.

Just to clarify, the integrationFolder is used for cypress open to be able to show your test files in the UI, and also to find specs curing cypress run?

Does the integrationFolder limit where the --spec command searches?

And --spec is for specifying which tests to run during cypress run?

Does --spec override integrationFolder?

  • the integrationFolder is what we use to scan and list out all the specs in the GUI
  • --spec is what we actually run during cypress run

I lied about integrationFolder allowing globs. Sorry 馃槙 It accepts a string to a directory.

Workaround

I found a workable solution by symlinking all my sub-package cypress/integration dirs into shared/cypress/integration, and then making that the integrationFolder. Works okay.


~Actually, I just use module.exports = require('@org/app-1/cypress/integration') inside cypress/integration/app-1.js.~

This didn't work because then I can only have one spec file per app. It also breaks file watching. Symlinking might be better...

@vjpr @jennifer-shehane This isn't complete workaround because it won't handle the case where tests have different support files, fixtures, or different configurations in cypress.json.

Can we re-open this issue?

We also use a monorepo at Airbnb, that looks something like:

projects/
  --  projectA
      -- cypress.json
      -- cypress
          -- integration
          -- support
          -- fixtures
              -- user.json

  --  projectB
      -- cypress.json
      -- cypress
          -- integration
          -- support
          -- fixtures
              -- user.json

You can symlink all the integration tests but that will still break on any test with its own fixture files or custom commands in the support directory. We also use mutually exclusive support commands, some teams choose to convert fetch to XHR, while others don't.

Right now, we invoke Cypress multiple times for a project in CI, and this comes with unexpected problems, eg. xvfb exitting non-zero (that could be fixed by https://github.com/cypress-io/cypress-docker-images/issues/54#issuecomment-487060555).


It would be great if cypress run + open supported projects by allowing you to pass in multiple directories that contained their own cypress.json files -- this is similar to Jest's projects:

See: https://jestjs.io/docs/en/configuration#projects-arraystring--projectconfig

projects [array]
Default: undefined
When the projects configuration is provided with an array of paths or glob patterns, Jest will run tests in all of the specified projects at the same time. This is great for monorepos or when working on multiple projects at the same time.

That way, in the root cypress.json we could specify the projects that we want to invoke cypress for like this:

{
  "defaultUrl": "https://www.airbnb.com",
  "projects": ["projects/projectA", "projects/projectB"],
}

And then when invoking cypress at the root of a monorepo, we can run all projects, or pick specific ones by using a flag to override the config like: --projects frontend/projectA.

In our case, end-to-end involves 2/3 apps.
Wouldn't it make sense to have top-level projects for cypress tests? Is there any disadvantage to that?

Right now, we invoke Cypress multiple times for a project in CI, and this comes with unexpected problems, eg. xvfb exitting non-zero (that could be fixed by cypress-io/cypress-docker-images#54 (comment)).

@sharmilajesupaul I would make sure to express your issue in the https://github.com/cypress-io/cypress-docker-images/issues/54 issue, as commenting / expressing how this is a blocker definitely helps when prioritizing which things we work on.

Passing a projects flag is not a bad idea. It will not be as simple to implement as expected though. I will reopen this issue with the intent being to allow running multiple projects from a single cypress run command, but this would not be very high priority for us at the moment unfortunately.

@jennifer-shehane I noticed you mentioned:

I lied about integrationFolder allowing globs. Sorry 馃槙 It accepts a string to a directory.

would you accept a PR changing integrationFolder (or maybe adding integrationFolders) to accept a glob? I think that would help in the first step towards achieving this by allowing multiple integration test folders. or is that more complex than it seems?

I haven't looked at this in a while. You can already pass a testFiles argument, which is a string or array of globs to load test files.

I think allowing the integrationFolder to accept a glob wouldn't really begin to solve the issue at hand (plus we would have to rename the key), as mentioned in this comment they need to run as separate projects, with separate support files, config, etc.

@jennifer-shehane oh i wasn't aware of testFiles does that respect relative support file paths? the docs don't seem to clarify this.

I believe the testFiles reads relative to the project root.

Was this page helpful?
0 / 5 - 0 ratings