Skip to content
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 · 10 comments
Closed

Create a Plugins / Extensions API #684

brian-mann opened this issue Sep 23, 2017 · 10 comments
Assignees
Labels
pkg/server This is due to an issue in the packages/server directory type: feature New feature that does not currently exist

Comments

@brian-mann
Copy link
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 brian-mann added the type: feature New feature that does not currently exist label Sep 23, 2017
@brian-mann brian-mann changed the title Create a Plugins / Extensions API Proposal: Create a Plugins / Extensions API Sep 24, 2017
@jennifer-shehane jennifer-shehane added stage: proposal 💡 No work has been done of this issue and removed Epic labels Sep 25, 2017
@jennifer-shehane jennifer-shehane changed the title Proposal: Create a Plugins / Extensions API Create a Plugins / Extensions API Sep 25, 2017
@jennifer-shehane jennifer-shehane added pkg/server This is due to an issue in the packages/server directory stage: in progress and removed stage: proposal 💡 No work has been done of this issue labels Sep 25, 2017
@bahmutov
Copy link
Contributor

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

@brian-mann
Copy link
Member Author

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
Copy link

laurentpayot commented Feb 20, 2018

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

@brian-mann
Copy link
Member Author

@laurentpayot we recently released cy.task with 3.0.0

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

@laurentpayot
Copy link

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.

@CharumathiA
Copy link

Hi, Is there any cypress function for Highlight and mark the text? Please confirm.

@jennifer-shehane
Copy link
Member

@CharumathiA Not that I'm aware of.

@hixus
Copy link

hixus commented Apr 23, 2020

Documentation (https://docs.cypress.io/api/plugins/writing-a-plugin.html#List-of-events) says "We have many new plugin events we are adding." and links to this 2 year old closed issue. So I'm curious are there new events but undocumented or is the development still going?

@jennifer-shehane
Copy link
Member

Yes actually there are new events planned here: #2840

I'll remove this link from the docs as it's outdated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg/server This is due to an issue in the packages/server directory type: feature New feature that does not currently exist
Projects
None yet
Development

No branches or pull requests

7 participants