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

Issue 323 #324

Merged
merged 4 commits into from
Dec 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions source/_data/sidebar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ api:
version: version.html
plugins:
writing-a-plugin: writing-a-plugin.html
configuration-api: configuration-api.html
preprocessors-api: preprocessors-api.html

plugins:
Expand Down
136 changes: 136 additions & 0 deletions source/api/plugins/configuration-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
---
title: Configuration API
comments: false
---

Cypress enables you to dynamically modify configuration values and environment variables from your plugin file.

These means you can do things like store multiple configuration files and switch between them like:

- `cypress.qa.json`
- `cypress.dev.json`
- `cypress.prod.json`

How you choose to organize your configuration and environment variables is up to you.

# Usage

To modify configuration, you simply return an object from your plugins file exported function.

```javascript
// plugins file
module.exports = (on, config) => {
console.log(config) // see what all is in here!

// modify config values
config.defaultCommandTimeout = 10000
config.baseUrl = 'https://staging.acme.com'

// modify env var value
config.env.ENVIRONMENT = 'staging'

// return config
return config
}
```

Whenever you return an object from your `pluginFile`, Cypress will take this and "diff" it against the original configuration, and automatically set the resolved values to point to what you returned.

If you don't return an object, then configuration will not be modified.

Resolved values will show up in your Settings tab.

{% img /img/guides/plugin-configuration.png %}

## Promises

Additionally, Cypress will respect and await promises you return. This enables you to perform asynchronous tasks and eventually resolve with the modified configuration object.

```javascript
// promisified fs module
const fs = require('fs-extra')

function getConfigurationByFile (file) {
const pathToConfigFile = path.resolve('..', 'config', `${file}.json`)

return fs.readJson(pathToConfigFile)
}

// plugins file
module.exports = (on, config) => {
// accept a configFile value or use development by default
const file = config.env.configFile || 'development'

return getConfigurationByFile(file)
}
```

You could now swap out configuration + environment variables like so:

```shell
cypress run
cypress run --env configFile=qa
cypress run --env configFile=staging
cypress run --env configFile=production
```

Each of these environments would read in the configuration at these files:

```text
cypress/config/development.json
cypress/config/qa.json
cypress/config/staging.json
cypress/config/production.json
```

This would enable you to do things like this:

```js
// cypress/config/development.json

{
baseUrl: 'http://localhost:1234',
env: {
something: 'development'
}
}
```

```js
// cypress/config/qa.json

{
baseUrl: 'https://qa.acme.com',
env: {
something: 'qa'
}
}
```

```js
// cypress/config/staging.json

{
baseUrl: 'https://staging.acme.com',
env: {
something: 'staging'
}
}
```

```js
// cypress/config/production.json

{
baseUrl: 'https://production.acme.com',
env: {
something: 'production'
}
}
```

## Notes

These are just simple examples. Remember - you have the full power of `Node.js` at your disposal.

How you choose to organize multiple configurations and sets of environment variables is up to you. You don't even have to read off of the file system - you could store them all in memory inside of your `pluginsFile` if you wanted to.
26 changes: 17 additions & 9 deletions source/api/plugins/writing-a-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ To get started, open up this file:
cypress/plugins/index.js
```

{% note info %}
By default Cypress seeds this file for new projects, but if you have an existing project just create this file yourself.
{% endnote %}

The plugins file must export a function with the following signature:

```javascript
Expand All @@ -36,6 +32,10 @@ The exported function is called whenever a project is opened either with {% url

Your function will receive 2 arguments: `on` and `config`.

You can return a synchronous function, or you can also return a Promise, and it will be awaited until it resolves. This enables you to perform asynchronous actions in your exported function such as reading files in from the filesystem.

If you return or resolve with an object, Cypress will then merge this object into the `config` which enables you to overwrite configuration or environment variables.

## on

`on` is a function that you will use to register to various **events** that Cypress exposes.
Expand All @@ -54,13 +54,17 @@ Each event documents its own argument signature. To understand how to use them,

## config

`config` is the resolved [Cypress configuration](https://on.cypress.io/guides/configuration) of the opened project.
`config` is the resolved {% url "Cypress configuration" configuration %} of the opened project.

This configuration contains all of the values that get passed into the browser for your project.

{% url 'For a comprehensive list of all configuration values look here.' https://github.com/cypress-io/cypress/blob/master/packages/server/lib/config.coffee %}

Some plugins may utilize or require these values, so they can take certain actions based on the configuration.

{% url 'For a comprehensive list of all configuration values look here.' https://github.com/cypress-io/cypress/blob/master/packages/server/lib/config.coffee %}
You can programmatically modify these values and Cypress will then respect these changes. This enables you to swap out configuration based on things like the environment you're running in.

{% url "Please check out our API docs for modifying configuration here." configuration-api %}

## List of events

Expand All @@ -86,14 +90,18 @@ You will need to keep in mind it is **Cypress who is requiring your file** - not

Because of this, this global context and the version of node is controlled by Cypress.

{% note warning %}
Your code must be compatible with the {% url 'version of node' https://github.com/cypress-io/cypress/blob/master/.node-version %} that comes with Cypress!
{% endnote %}
{% note warning "Node version" %}

Keep in mind - code executed in plugins is executed **by the node version** that comes bundled in Cypress itself.

This version of node has **nothing to do** with your locally installed versions. Therefore you have to write node code which is compatible with this version.

You can find the current node version we use {% url 'here' https://github.com/cypress-io/cypress/blob/master/.node-version %}.

This node version gets updated regularly (next version will be in the `8.x.x` range) so you'll likely be able to use all the latest ES7 features.

{% endnote %}

## NPM modules

When Cypress executes your `pluginsFile` it will execute with `process.cwd()` set to your project's path. Additionally - you will be able to `require` **any node module** you have installed.
Expand Down
6 changes: 6 additions & 0 deletions source/faq/questions/using-cypress-faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ Cypress exposes an event for this (amongst many others) that you can listen for

This is documented in detail on the {% url "Catalog Of Events" catalog-of-events %} page.

## {% fa fa-angle-right %} Can I override environment variables or create configuration for different environments?

Yes, you use your `pluginsFile` to modify configuration values and environment variables.

{% url "We have a whole API document showing you how to do just that." configuration-api %}

## {% fa fa-angle-right %} I'm trying to test a chat application. Can I run more than one browser at a time with Cypress?

{% url "We've answered this question in detail here." trade-offs#Multiple-browsers %}
Expand Down
2 changes: 1 addition & 1 deletion source/guides/guides/debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Though Cypress has built out {% url "an excellent Test Runner" test-runner %} to
{% note info %}
## {% fa fa-video-camera %} See it in action!

You can see a walk-through of debugging some application code from Cypress {% url "in this segment from our React tutorial series" https://vimeo.com/242961930#t=264s %}.
You can see a walk-through of debugging some application code from Cypress [in this segment from our React tutorial series](https://vimeo.com/242961930#t=264s).

{% endnote %}

Expand Down
39 changes: 19 additions & 20 deletions source/guides/guides/plugins-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,30 @@ Normally, as a user, all of your test code, your application, and Cypress comman

Plugins are a "seam" for you to write your own custom code that executes during particular stages of the Cypress lifecycle.

{% note info "New Projects" %}
When new projects are added to Cypress we will automatically seed them with a basic plugins file.
{% note info "This is a brief overview" %}
If you want more details about how to write a plugin, we've written API docs that show you how to work with each plugin event.

By default Cypress will create a plugins file at: `cypress/plugins/index.js`.

This is configurable in your `cypress.json` with the {% url "`pluginsFile`" configuration#Folders-Files %} option.
You can {% url "check out the API docs here" writing-a-plugin %}.
{% endnote %}

# Plugin types
# Use Cases

## Configuration

With plugins, you can programmatically alter the resolved configuration and environment variables that come from `cypress.json`, `cypress.env.json`, the CLI, or system environment variables.

This enables you to do things like:

- Use multiple environments with their own configurations
- Swap out environment variables based on an environment
- Read in configuration files using the built in `fs` lib
- Write your configuration in `yml`

Check out our {% url 'Configuration API docs' configuration-api %} which describe how to use this event.

## Preprocessors

As of today we offer a single plugin event: `file:preprocessor`. This event is used to customize how your test code is transpiled and sent to the browser. By default Cypress handles CoffeeScript and ES6 using `babel` and then uses `browserify` to package it for the browser.
This event: `file:preprocessor` is used to customize how your test code is transpiled and sent to the browser. By default Cypress handles CoffeeScript and ES6 using `babel` and then uses `browserify` to package it for the browser.

You can use the `file:preprocessor` event to do things like:

Expand Down Expand Up @@ -78,16 +89,4 @@ module.exports = (on, config) => {
}
```

Check out our {% url 'Writing a Plugin doc' writing-a-plugin %} which describes how to write plugins.

{% note warning "Node version" %}

Keep in mind - code executed in plugins is executed **by the node version** that comes bundled in Cypress itself.

This version of node has **nothing to do** with your locally installed versions. Therefore you have to write node code which is compatible with this version.

You can find the current node version we use {% url 'here' https://github.com/cypress-io/cypress/blob/master/.node-version %}.

This node version gets updated regularly (next version will be in the `8.x.x` range) so you'll likely be able to use all the latest ES7 features.

{% endnote %}
For more information on writing plugins, please {% url "check out our API docs here" writing-a-plugin %}.
Binary file added source/img/guides/plugin-configuration.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions themes/cypress/languages/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ sidebar:
plugins: Plugins
writing-a-plugin: Writing a Plugin
preprocessors-api: Preprocessors
configuration-api: Configuration
version: version
arch: arch
platform: platform
Expand Down