Skip to content

feat: allow usage of @react/plugins with cypress.config.js #17738

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 28 commits into from
Sep 9, 2021

Conversation

elevatebart
Copy link
Contributor

@elevatebart elevatebart commented Aug 13, 2021

Closes https://cypress-io.atlassian.net/browse/UNIFY-278

User facing changelog

When #17000 is merged, this PR will make this code valid and work

// @ts-check

const { defineConfig } = require("cypress");
const cracoConfig = require('./craco.config.js')
const setupCracoDevServer = require("@cypress/react/plugins/craco");

module.exports = defineConfig({
  component: {
    testFiles: "src/**/*.test.{js,ts,jsx,tsx}",
    componentFolder: "src",
    devServer(devServerConfig){
      return setupCracoDevServer(devServerConfig, cracoConfig)
    }
  }
})

it also will make nextjs installs easier

// cypress.congig.js
const { defineConfig } = require("cypress");
const { devServer } = require("@cypress/react/plugins/next");

module.exports = defineConfig({
  component: {
    testFiles: "src/**/*.test.{js,ts,jsx,tsx}",
    devServer
  }
})
  • Have tests been added/updated?

Changelog of this PR

  • created the wrap-devserver function
  • used wrap-devserver in all the npm/react/plugins/xxxx/index.js
  • added typings for those index.js files
  • checked the types definition by using them examples by using @ts-check

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Aug 13, 2021

Thanks for taking the time to open a PR!

@cypress
Copy link

cypress bot commented Aug 13, 2021



Test summary

8368 0 100 4Flakiness 1


Run details

Project cypress
Status Passed
Commit 9aa0f17
Started Sep 9, 2021 9:07 PM
Ended Sep 9, 2021 9:17 PM
Duration 10:03 💡
OS Linux Debian - 10.9
Browser Multiple

View run in Cypress Dashboard ➡️


Flakiness

cypress/integration/cypress/proxy-logging-spec.ts Flakiness
1 Proxy Logging > request logging > fetch log shows resource type, url, method, and status code and has expected snapshots and consoleProps

This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard

Copy link
Contributor

@cowboy cowboy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comments are mostly about consistency. We have the following dev servers:

  • @cypress/webpack-dev-server
  • @cypress/vite-dev-server
  • @cypress/react/plugins/babel
  • @cypress/react/plugins/craco
  • @cypress/react/plugins/load-webpack
  • @cypress/react/plugins/next
  • @cypress/react/plugins/react-scripts

I think this PR should ensure:

  • all dev server function signatures are both backwards- and forwards-compatible in the same way, with signatures as-defined in the notion document
  • all dev server modules export their functions consistently
  • all the examples refer to the dev servers consistently

// New CT plugin signature: setupDevServer(options)
const [options, additionalOptions] = args

return devServer(options, additionalOptions)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're going to have a postProcessConfig we also need to call it with the setupDevServer(options) signature

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot postProcess the config in this case, can we?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as discussed with Jessica, I don't think this should be part of the PR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a followup issue to address this? I want to make sure these dev server modules behave consistently when used with the new signature. /cc @JessicaSachs

lmiller1990
lmiller1990 previously approved these changes Aug 17, 2021
Copy link
Contributor

@lmiller1990 lmiller1990 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming aside, I did a QA locally and it seems to function correctly. I checked this out, then merged in #17000, fixed conflicts, ran yarn and then did yarn cy:open in npm/react and it functions as expected. Anything else I should look at?

I'll approve this for now, but we should definitely resolve @cowboy's comments before merging.

@cowboy cowboy self-assigned this Aug 17, 2021
Copy link
Contributor

@JessicaSachs JessicaSachs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to update the names to be consistent.

JessicaSachs
JessicaSachs previously approved these changes Aug 18, 2021
JessicaSachs
JessicaSachs previously approved these changes Aug 18, 2021
@cowboy
Copy link
Contributor

cowboy commented Aug 19, 2021

I've been through the code for the following dev server modules:

All the dev server modules in this PR follow the pattern outlined in the notion doc, which I have duplicated here:

// no additionalOptions
function setupDevServer(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions): void
function setupDevServer(options: Cypress.DevServerOptions): Cypress.ResolvedDevServerConfig

// optional additionalOptions
function setupDevServer(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions, additionalOptions?: TBDType): void
function setupDevServer(options: Cypress.DevServerOptions, additionalOptions?: TBDType): Cypress.ResolvedDevServerConfig

// required additionalOptions
function setupDevServer(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions, additionalOptions: TBDType): void
function setupDevServer(options: Cypress.DevServerOptions, additionalOptions: TBDType): Cypress.ResolvedDevServerConfig

For example, react/plugins/babel exports a default (not a named) function, eg.

module.exports = returnSetupDevServerFunction(startBabelDevServer, (config) => {
  // code
})

That has the following signatures:

interface AdditionalOptions {
  setWebpackConfig?(config: Configuration): Configuration
}

declare function setupBabelDevServer(
  on: Cypress.PluginEvents,
  config: Cypress.PluginConfigOptions,
  additionalOptions?: AdditionalOptions
): void
declare function setupBabelDevServer(
  options: Cypress.DevServerOptions,
  additionalOptions?: AdditionalOptions
): Cypress.ResolvedDevServerConfig

Which will be used like this in index/plugins.js:

const setupDevServer = require('@cypress/react/plugins/babel')
module.exports = (on, config) => {
  setupDevServer(on, config)
  return config
}

And like this in cypress.config.js:

const setupDevServer = require('@cypress/react/plugins/babel')
module.exports = {
  component: {
    startDevServer(options) {
      return startDevServer(options)
    }
  }
}

However, the vite-dev-server and webpack-dev-server behave differently. They export named, not default, functions, and their function signatures deviate from the pattern used in the dev server modules in this PR.

For example, vite-dev-server exports a named function with a very different signature, eg.

export async function startDevServer(startDevServerArgs: StartDevServerOptions): Promise<ResolvedDevServerConfig> {
  // code
}
export interface StartDevServerOptions {
  options: Cypress.DevServerOptions
  viteConfig?: UserConfig
}

Which will be used like this in index/plugins.js:

import { startDevServer } from '@cypress/vite-dev-server'
module.exports = (on, config) => {
  on('dev-server:start', async (options) => startDevServer({ options }))
  return config
}

And like this in cypress.config.js:

const { startDevServer } = require('@cypress/vite-dev-server')
module.exports = {
  component: {
    startDevServer(options) {
      return startDevServer({ options })
    }
  }
}

Before this PR is merged, I would like us to decide on a consistent pattern for the signatures and exports for all the dev server modules listed above, and make sure that pattern is followed both in this PR and in follow-up PRs for the vite-dev-server and webpack-dev-server modules, if necessary.

Questions to be answered:

  • Should the dev server function be a:
    • named export
    • default export
  • Should the dev server function receive:
    • a positional options argument that is of type Cypress.DevServerOptions along with a second signature where it receives on/config arguments (like in the notion doc and the dev server modules in this PR)
    • a single options argument that has an options property that is of type Cypress.DevServerOptions, along with possible additional properties that are specific to that dev server (like the vite-dev-server and webpack-dev-server modules)

I think that all dev server functions should be a named export, for all the reasons listed here and that all dev server functions should conform to the signature patterns outlined in the notion doc (shown above).

@cowboy
Copy link
Contributor

cowboy commented Aug 19, 2021

I spoke with @JessicaSachs, and we agreed on the following:

  1. The following are considered old and will be deprecated in an 8.x release and removed in the 9.0 release:

    • The webpack/vite signature setupDevServer({ options }) is considered old
    • The signature setupDevServer(on, config) is considered old
    • Default exports is considered old
  2. We'll call the object that the component.setupDevServer config function receives devServerConfig in all our code and examples

const { defineConfig } = require("cypress");
const cracoConfig = require('./craco.config.js')
const setupCracoDevServer = require("@cypress/react/plugins/craco");

module.exports = defineConfig({
  component: {
    setupDevServer(devServerConfig) {
      return setupCracoDevServer(devServerConfig, { cracoConfig })
    }
  }
})
  1. The Cypress.DevServerOptions type will be renamed to Cypress.DevServerConfig

  2. The new export for all dev server plugins will be a named export, and will be setupDevServer for the webpack/vite dev servers and a more specific name like setupCracoDevServer for the specific react dev servers

  3. The new signature for all dev server plugins will be positional, and be one of the following, where setupDevServer may be renamed for the specific react dev servers and options will be typed as-needed on a per-dev server basis

// no additionalOptions
function setupDevServer(devServerConfig: Cypress.DevServerConfig): Cypress.ResolvedDevServerConfig

// optional additionalOptions
function setupDevServer(devServerConfig: Cypress.DevServerConfig, options?: TBDType): Cypress.ResolvedDevServerConfig

// required additionalOptions
function setupDevServer(devServerConfig: Cypress.DevServerConfig, options: TBDType): Cypress.ResolvedDevServerConfig
  1. The options object (should a dev server module need it) will contain one or more properties corresponding to required or optional values, allowing for multiple options. For example:
setupCracoDevServer(devServerConfig, { cracoConfig })

@cowboy
Copy link
Contributor

cowboy commented Aug 23, 2021

I am continuing this work in #17817

@elevatebart elevatebart requested a review from a team as a code owner September 9, 2021 18:54
@elevatebart elevatebart requested review from chrisbreiding and jennifer-shehane and removed request for a team September 9, 2021 18:54
Copy link
Contributor

@cowboy cowboy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You missed some

Copy link
Contributor

@cowboy cowboy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@elevatebart elevatebart merged commit da4b1e0 into master Sep 9, 2021
tgriesser added a commit that referenced this pull request Sep 13, 2021
…p-gui-gql-stitching

* unified-desktop-gui:
  fix: Global Mode Crashes on Launch (#18059)
  fix(launchpad): add a11y support to Settings Card (#18027)
  fix transient dep problem
  fix(vite-dev-server): remove base and root from inlineVitConfig types (#17180)
  chore: adding the new app package for the unified app experience (#18053)
  feat: allow usage of @react/plugins with cypress.config.js (#17738)
  rename inject into devServer
  fix: add missing clientCertificate type to ResolvedConfigOptions (#18028)
  docs: restore author of react,vue,ng component testing (#16800)
  fix(cypress/schematic): add edge to list of allowed browsers (#17637)
  fix: global hooks cause duplicated hooks after domain navigation (#17884)
  chore: release @cypress/webpack-dev-server-v1.5.0
  chore: release @cypress/vite-dev-server-v2.0.8
@penx
Copy link
Contributor

penx commented Dec 16, 2021

hi, this looks useful - but what's the status now that #17000 has been closed?

@elevatebart elevatebart deleted the refactor/react-plugins-no-config branch March 24, 2022 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
npm: @cypress/react @cypress/react package issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants