Skip to content

Commit

Permalink
feat: use CYPRESS_PACKAGE_CONFIG_PATH
Browse files Browse the repository at this point in the history
  • Loading branch information
agoldis committed Sep 12, 2021
1 parent 9d062fa commit 743a892
Show file tree
Hide file tree
Showing 13 changed files with 495 additions and 250 deletions.
34 changes: 28 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,74 +1,96 @@
# Logs

logs
*.log
npm-debug.log*
_.log
npm-debug.log_
yarn-debug.log*
yarn-error.log*
.vscode/settings.json

# Runtime data

pids
*.pid
*.seed
_.pid
_.seed
*.pid.lock

# dynamic graphql typedefs

# Directory for instrumented libs generated by jscoverage/JSCover

lib-cov

# Coverage directory used by tools like istanbul

coverage

# nyc test coverage

.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)

.grunt

# Bower dependency directory (https://bower.io/)

bower_components

# node-waf configuration

.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)

build/Release
dist

# Dependency directories

node_modules/
jspm_packages/

# TypeScript v1 declaration files

typings/

# Optional npm cache directory

.npm

# Optional eslint cache

.eslintcache

# Optional REPL history

.node_repl_history

# Output of 'npm pack'
*.tgz

\*.tgz

# Yarn Integrity file

.yarn-integrity

# dotenv environment variables file

.env

# next.js build output

.next

# AWS

credentials

# Minio

/data
example/data

_local
_global
_global
**/__temp_fixture*
63 changes: 50 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,46 @@ Change cypress API URL configuration on-the-fly using environment variable `CYPR
npm install cy2
```

---

## Usage

```sh
Use `http://localhost:1234` as Cypress API URL:

CYPRESS_API_URL="http://localhost:1234/" cy2 open
```sh
CYPRESS_API_URL="http://localhost:1234/" cy2 run --parallel --record --key somekey --ci-build-id hello-cypress
```

Example usage with [sorry-cypress](https://sorry-cypress.dev)

```sh
CYPRESS_API_URL="https://sorry-cypress.domain.com" cy2 run --parallel --record --key somekey --ci-build-id hello-cypress
CYPRESS_API_URL="https://sorry-cypress-demo-director.herokuapp.com" cy2 run --parallel --record --key somekey --ci-build-id hello-cypress
```

When `CYPRESS_API_URL` is not available, it just uses the default API server.
When `CYPRESS_API_URL` is not set, it just uses the default API server `https://api.cypress.io`

## API

Patch `cypress` package
---

```ts
patch(apiURL: string) => Promise<void>
```
## API

Patch and run `cypress`
### Patch Cypress

```ts
run(apiURL?: string = 'https://yourserver.io/'), label?: string = 'cy2')=> Promise<void>
/**
* Patch Cypress with a custom API URL.
*
* Tries to discover the location of `app.yml`
* and patch it with a custom URL.
*
* https://github.com/cypress-io/cypress/blob/develop/packages/server/config/app.yml
*
* @param {string} apiURL - new API URL to use
* @param {string} [cypressConfigFilePath] - explicitly provide the path to Cypress app.yml and disable auto-discovery
*/
patch(apiURL: string, cypressConfigPath?: string) => Promise<void>
```

### Examples
Example

```js
const { patch } = require('cy2');
Expand All @@ -52,6 +62,17 @@ async function main() {
main().catch(console.error);
```

### Patch and run cypress

```ts
/**
* Run Cypress programmatically as a child process
*/
run(apiURL?: string = 'https://api.cypress.io/'), label?: string = 'cy2')=> Promise<void>
```

Example

```js
#!/usr/bin/env node

Expand All @@ -76,3 +97,19 @@ Options:
*/
```

---

## Explicit config file location (since 1.4.0)

Sometimes `cy2` is not able to automatically detect the location of cypress package on your system. In that case you should explicitly provide environment variable `CYPRESS_PACKAGE_CONFIG_PATH` with the location of cypress's `app.yml` configuration file.

Example:

```sh
CYPRESS_API_URL="http://localhost:1234/" \
CYPRESS_PACKAGE_CONFIG_PATH="/Users/John/Cypress/8.3.0/Cypress.app/Contents/Resources/app/packages/server/config/app.yml" \
DEBUG=cy2* yarn cy2 run --parallel --record --key somekey --ci-build-id hello-cypress
```

See [cypress agent configuration](https://docs.sorry-cypress.dev/cypress-agent/configuring-cypress-agent) for locating `app.yml` file on your system.
11 changes: 0 additions & 11 deletions __tests__/index.test.js

This file was deleted.

8 changes: 6 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ const DEFAULT_OVERRIDE_URL = 'https://api.cypress.io/';

exports.patch = lib.patch;

exports.run = async (cypressAPIUrl = DEFAULT_OVERRIDE_URL, label = 'cy2') => {
await lib.patch(cypressAPIUrl);
exports.run = async (
cypressAPIUrl = DEFAULT_OVERRIDE_URL,
label = 'cy2',
cypressConfigFilePath = process.env.CYPRESS_PACKAGE_CONFIG_PATH
) => {
await lib.patch(cypressAPIUrl, cypressConfigFilePath);
console.log(`[${label}] Running cypress with API URL: ${cypressAPIUrl}`);
await lib.run();
};
25 changes: 25 additions & 0 deletions lib/__tests__/discovery.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const fs = require('fs');
const { getConfigFilesPaths } = require('../discovery');
const { getAutoDiscoveredConfigFilesPaths } = require('../auto-discovery');

jest.mock('../auto-discovery');

test('should use explicit path', async () => {
fs.statSync = jest.fn().mockReturnValue(true);

const result = await getConfigFilesPaths('explicitPath/app.yml');

expect(result.configFilePath).toMatch('explicitPath/app.yml');
expect(result.backupConfigFilePath).toMatch('explicitPath/_app.yml');
expect(fs.statSync).toHaveBeenCalledWith(
expect.stringMatching('explicitPath')
);
});

test('should use auto-discovery', async () => {
getAutoDiscoveredConfigFilesPaths.mockReturnValue({});

await getConfigFilesPaths();

expect(getAutoDiscoveredConfigFilesPaths).toHaveBeenCalled();
});
18 changes: 18 additions & 0 deletions lib/__tests__/fixtures/app.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
default:
cdn_url: https://cdn.cypress.io
desktop_url: https://download.cypress.io/desktop
desktop_manifest_url: https://download.cypress.io/desktop.json
chromium_url: https://download.cypress.io/chromium
chromium_manifest_url: https://download.cypress.io/chromium.json
development:
api_url: http://localhost:1234/
on_url: http://localhost:8080/
test:
api_url: http://localhost:1234/
on_url: http://localhost:8080/
staging:
api_url: https://api-staging.cypress.io/
on_url: https://on.cypress.io/
production:
api_url: https://api.cypress.io/
on_url: https://on.cypress.io/
34 changes: 34 additions & 0 deletions lib/__tests__/patch.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const fs = require('fs');
const path = require('path');

const yaml = require('js-yaml');
const { nanoid } = require('nanoid');

const { patch } = require('../patch');
const { getConfigFilesPaths } = require('../discovery');

jest.mock('../discovery');

const original = path.resolve(__dirname, './fixtures/app.yml');

test('should patch', async () => {
const seed = nanoid();
const filename = `./fixtures/__temp_fixture_${seed}`;

const configFilePath = path.resolve(__dirname, `${filename}.yml`);
const backupConfigFilePath = path.resolve(
__dirname,
`${filename}_backup.yml`
);
fs.copyFileSync(original, configFilePath);

getConfigFilesPaths.mockResolvedValueOnce({
configFilePath,
backupConfigFilePath,
});

await patch(seed);

const doc = yaml.load(fs.readFileSync(configFilePath, 'utf8'));
expect(doc.production.api_url).toEqual(seed);
});
67 changes: 67 additions & 0 deletions lib/auto-discovery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const path = require('path');
const { getCypressCLIBinPath } = require('./bin-path');
const { lookupPaths } = require('./fs');
const debug = require('debug')('cy2');

module.exports = {
getAutoDiscoveredConfigFilesPaths,
};

async function getAutoDiscoveredConfigFilesPaths() {
const stateModulePath = await getStateModulePath();
const state = require(stateModulePath);

const pkgPath = state.getBinaryPkgPath(state.getBinaryDir());
debug('Cypress pkgPath: %s', pkgPath);

const pkgRoot = path.dirname(pkgPath);
debug('Cypress pkgRoot: %s', pkgRoot);

const configFilePath = path.resolve(
pkgRoot,
'packages/server/config/app.yml'
);
const backupConfigFilePath = path.resolve(
pkgRoot,
'packages/server/config/_app.yml'
);

debug('Cypress configFilePath: %s', configFilePath);
return {
configFilePath,
backupConfigFilePath,
};
}

async function getStateModulePath() {
try {
const cliBinPath = await getCypressCLIBinPath();
const candidates = [
path.join(
path.dirname(cliBinPath),
'node_modules',
'cypress/lib/tasks/state.js'
),
path.join(path.dirname(cliBinPath), '..', 'lib/tasks/state.js'),
path.join(
path.dirname(cliBinPath),
'..',
'cypress',
'lib/tasks/state.js'
),
];

debug('Cypress state module candidates: %o', candidates);

const result = lookupPaths(candidates);

if (!result) {
throw new Error('Cannot detect cypress');
}

debug('Cypress state module detected: %s', result);
return result;
} catch (error) {
throw new Error('Cannot detect cypress. Is cypress installed?');
}
}
Loading

0 comments on commit 743a892

Please sign in to comment.