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

Create a Plugins / Extensions API #684

Closed
brian-mann opened this Issue Sep 23, 2017 · 6 comments

Comments

5 participants
@brian-mann
Member

brian-mann commented Sep 23, 2017

The idea behind this

As it stands - while users can create custom commands in the driver, we do not expose any real way to alter, modify or change Cypress's behavior BEHIND the driver (in the node server code).

Currently all we expose is a simple cypress.json to change the way Cypress works. This is heavily limiting.

What we need to do is expose a public interface so users can write node code to modify and alter the internals.

The use cases we're specifically trying to support are:

Custom Preprocessors

Swapping out the default preprocessor for custom ones. This is the thing that processes the spec files and ultimately serves them to the browser.

Customizing the preprocess would enable users to write typescript, coffeescript 2.0, clojurescript, use webpack, customize babel options, use newer ES7 features, etc, etc. Big win.

Browser Configuration

Users would have access to the browser processes and launch configuration. This would enable them to change the flags used to launch browsers.

You could also use this to load in browser extensions.

Browser Finding

Changes / modifies the logic we use to find browsers on the system.

Custom Configuration

Having just a single cypress.json is limiting. Users have expressed a desire to have more programatic control over things like environment variables.

Backend Messaging

While we currently expose cy.exec and cy.request, there is still a desire to message / talk directly to your backend.

Exposing this API would enable you to do things like call your application code directly to do things like setup / seed / create / update database records.

Screenshot Diffing

As we continue to expand the features of Cypress we would expand these API's to do things like letting you swap out the screenshot diffing algorithm.

The Cypress Ecosystem

Going down this route will enable us to develop a Cypress Ecosystem consisting of official extensions (created by us) as well as user submitted extensions.

We'll also need to create an "index" of extensions that enable users to search, browse, and submit new extensions.

Things to consider

  • How will we / users handle versioning for plugins? We may need to set a process.versions.cypress
  • How will we differentiate official plugins from regular ones? We could publish them under our @cypress npm namespace.
  • How will we make modifying the default plugin that Cypress uses by default. Users may want to swap out entire implementations (like the preprocessor) or perhaps just modify the configuration for the default one.
  • We should likely seed a commented out cypress/plugins/index.js with all of the API's that we support.
  • We should enable users to easily debug their node code by passing a flag to Cypress which spawns the internal chrome inspector.
  • Users code will run in the builtin node environment that comes with Cypress.

Examples of how we could do this

// cypress/plugins/index.js

module.exports = ((register, config, utils, defaults) => {
  register('on:spec:file:preprocessor', (filePath, options) => {
    // do your own custom preprocessing on the spec
  })

  register('on:before:browser:launch', (browserName, flags) => {
    // do your own custom bits on launching the browser
    // such as loading in an extension or modifying the flags
    // used to launch the browser
  })

  register('on:find:all:browsers', (browsersFound) => {
    // add or modify the browsers we found
  })

  register('on:config', (config) => {
    // read in your own yaml files to change some
    // environment variables
    return fs.readFile("./some/yaml", "utf8")
    .then((str) => {
      const yaml = jsYaml.parse(str)

      config.env.yml = yaml

      return config
    })
  })

  register('on:driver:message', (msg, options) => {
    const db = require('./lib/db') // your db

    const request = require('request') // 3rd party request module

    // pass custom messages and do your own thing here loading
    // your own application files
    switch (msg) {
      case 'create:user':
        return db.seed(options)
      case 'reset:db':
        return db.reset()
      case 'make:request':
        return Promise.all(options.urls, request)
    }
  })
})
@brian-mann

This comment has been minimized.

Show comment
Hide comment
@brian-mann

brian-mann Sep 24, 2017

Member

Related to:

Preprocessor:

  • CoffeeScript 2: #663
  • Disable preprocessing: #533
  • ES7/Webpack: #580
  • ES7: #487
  • Babel configuration: #343
  • Source maps / Babel configuration: #881
  • Spread operator #905

Browsers:

  • Browser flags: #573
  • Chome headless: #488
  • Modify user-agent: #364
  • Test chrome extensions: #298

Miscellaneous:

  • Code coverage: #346
  • Trigger re-run: #188
  • Trigger re-run: #412
  • Trigger re-run (proposal): #456
Member

brian-mann commented Sep 24, 2017

Related to:

Preprocessor:

  • CoffeeScript 2: #663
  • Disable preprocessing: #533
  • ES7/Webpack: #580
  • ES7: #487
  • Babel configuration: #343
  • Source maps / Babel configuration: #881
  • Spread operator #905

Browsers:

  • Browser flags: #573
  • Chome headless: #488
  • Modify user-agent: #364
  • Test chrome extensions: #298

Miscellaneous:

  • Code coverage: #346
  • Trigger re-run: #188
  • Trigger re-run: #412
  • Trigger re-run (proposal): #456

@brian-mann brian-mann changed the title from Create a Plugins / Extensions API to Proposal: Create a Plugins / Extensions API Sep 24, 2017

@brian-mann brian-mann added the Epic label Sep 25, 2017

@jennifer-shehane jennifer-shehane changed the title from Proposal: Create a Plugins / Extensions API to Create a Plugins / Extensions API Sep 25, 2017

@bahmutov

This comment has been minimized.

Show comment
Hide comment
@bahmutov
Collaborator

bahmutov commented Oct 18, 2017

Example repos with TypeScript test compilation (using Cypress from source)

@brian-mann

This comment has been minimized.

Show comment
Hide comment
@brian-mann

brian-mann Nov 20, 2017

Member

The PR #888 implements the Plugins API.

I'm keeping this issue open (as it is an epic) documenting many other plugin events that we are adding.

We'll close the associated issues that are open and keep this issue open until all of them are complete.

Member

brian-mann commented Nov 20, 2017

The PR #888 implements the Plugins API.

I'm keeping this issue open (as it is an epic) documenting many other plugin events that we are adding.

We'll close the associated issues that are open and keep this issue open until all of them are complete.

@laurentpayot

This comment has been minimized.

Show comment
Hide comment
@laurentpayot

laurentpayot Feb 20, 2018

Any news about backend messaging? Is #794 still relevant and should I start using cypress-adapter-node?

laurentpayot commented Feb 20, 2018

Any news about backend messaging? Is #794 still relevant and should I start using cypress-adapter-node?

@brian-mann

This comment has been minimized.

Show comment
Hide comment
@brian-mann

brian-mann Jun 1, 2018

Member

@laurentpayot we recently released cy.task with 3.0.0

This issue should now be closed since we've effectively created the plugins API.

Member

brian-mann commented Jun 1, 2018

@laurentpayot we recently released cy.task with 3.0.0

This issue should now be closed since we've effectively created the plugins API.

@brian-mann brian-mann closed this Jun 1, 2018

@laurentpayot

This comment has been minimized.

Show comment
Hide comment
@laurentpayot

laurentpayot Jun 27, 2018

@brian-mann I made the switch to Cypress 3.0.1 yesterday.
I had some minor CoffeeScript file related issues (#2046) but making firebase-related tasks work was a pain because firebase use grpc and grpc and electron do not live together well.
I encountered the following issue grpc/grpc#6138 that I fixed by a postinstall of the electron runtime of grpc, plus I had to create symbolic links to it because Firebase (or Cypress?) was still looking for the node version of grpc.

laurentpayot commented Jun 27, 2018

@brian-mann I made the switch to Cypress 3.0.1 yesterday.
I had some minor CoffeeScript file related issues (#2046) but making firebase-related tasks work was a pain because firebase use grpc and grpc and electron do not live together well.
I encountered the following issue grpc/grpc#6138 that I fixed by a postinstall of the electron runtime of grpc, plus I had to create symbolic links to it because Firebase (or Cypress?) was still looking for the node version of grpc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment