Skip to content

Commit

Permalink
feat: add support for cypress.json and cypress.env.json (plus add tes…
Browse files Browse the repository at this point in the history
…ts) (#4)
  • Loading branch information
dpgraham authored Jul 23, 2020
1 parent 08a0ba0 commit 1e9d8c6
Show file tree
Hide file tree
Showing 22 changed files with 157 additions and 15 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Integration Tests

on:
pull_request:
branches:
- master

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x, 14.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js v${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm ci --production
- name: Run integration tests
run: bash tests/integration/integration-tests.sh

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,5 @@ cypress

# saucectl configuration folder
.sauce

results/
12 changes: 12 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# CONTRIBUTING

## Run tests

### Integration tests
`npm run test-integration` triggers the [integration tests script](/tests/integration/integration-tests.sh). Which triggers the tests in (/tests/integration/fixtures/cypress-tests) and runs them through `cypress-runner.js`.

## Publishing to Docker Hub
To publish the Docker image:
* Create a [new release](https://github.com/saucelabs/sauce-cypress-runner/releases)
* Tag it with an appropriate version, based on semantic versioning
* Update the changelog and list the frameworks and browsers. If the frameworks and browsers didn't change, then copy and paste them from the previous release
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ Sauce Labs test runner image to run Cypress tests on Sauce.

### Build Docker Image
`make docker`

## Contributing
[See contributing doc](/CONTRIBUTING.md)
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
{
"name": "sauce-cypress-runner",
"version": "1.0.0",
"version": "1.1.0",
"description": "",
"main": "./src/cypress-runner.js",
"bin": "./bin/cypress",
"scripts": {
"test": "./bin/cypress"
"test": "./bin/cypress",
"test-integration": "bash tests/integration/integration-tests.sh"
},
"keywords": [],
"author": "devx <dev@saucelas.com>",
"author": "devx <dev@saucelabs.com>",
"license": "ISC",
"dependencies": {
"cypress": "4.9.0",
Expand Down
54 changes: 44 additions & 10 deletions src/cypress-runner.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
const { sauceReporter } = require('./sauce-reporter');
const path = require('path');
const fs = require('fs');

const { promisify } = require('util');
const yaml = require('js-yaml');
const cypress = require('cypress');
const { getAbsolutePath } = require('./utils');

const DEFAULT_BROWSER = 'chrome';
const buildName = process.env.SAUCE_BUILD_NAME || `stt-cypress-build-${(new Date()).getTime()}`;
const supportedBrowsers = {
Expand All @@ -18,7 +22,7 @@ if (!browserName) {
const report = async (results) => {
const status = results.failures || results.totalFailed;
if (!(process.env.SAUCE_USERNAME && process.env.SAUCE_ACCESS_KEY)) {
console.log('Skipping asset uploads! Remeber to setup your SAUCE_USERNAME/SAUCE_ACCESS_KEY');
console.log('Skipping asset uploads! Remember to setup your SAUCE_USERNAME/SAUCE_ACCESS_KEY');
return status;
}
const runs = results.runs || [];
Expand All @@ -28,24 +32,49 @@ const report = async (results) => {
return status;
}

const yaml = require('js-yaml');
const config = yaml.safeLoad(fs.readFileSync('config.yaml', 'utf8'))

const cypressRunner = async function () {
try {
// Get the configuration info from config.yaml
const configYamlPath = process.env.CONFIG_FILE || 'config.yaml';
const config = yaml.safeLoad(await promisify(fs.readFile)(configYamlPath, 'utf8'));

// If relative paths were provided in YAML, convert them to absolute
const targetDir = getAbsolutePath(config.targetDir);
const reportsDir = getAbsolutePath(config.reportsDir);

// Get the cypress.json config file (https://docs.cypress.io/guides/references/configuration.html#Options)
let configFile = 'cypress.json';
let cypressJsonPath = path.join(targetDir, 'cypress.json');
if (await promisify(fs.exists)(cypressJsonPath)) {
configFile = path.relative(process.cwd(), cypressJsonPath);
}

// Get the cypress env variables from 'cypress.env.json' (if present)
let env = {};
const cypressEnvPath = path.join(targetDir, 'cypress.env.json')
if (await promisify(fs.exists)(cypressEnvPath)) {
try {
env = JSON.parse(await promisify(fs.readFile)(cypressEnvPath));
} catch (e) {
console.error(`Could not parse contents of '${cypressEnvPath}'. Will use empty object for environment variables.`);
}
}

const results = await cypress.run({
browser: browserName,
configFile,
config: {
env,
video: true,
videosFolder: config.reportsDir,
videosFolder: reportsDir,
videoCompression: false,
videoUploadOnPasses: false,
screenshotsFolder: config.reportsDir,
integrationFolder: config.targetDir,
testFiles: `${config.targetDir}/**/?(*.)+(spec|test).[jt]s?(x)`,
screenshotsFolder: reportsDir,
integrationFolder: targetDir,
testFiles: `${targetDir}/**/?(*.)+(spec|test).[jt]s?(x)`,
reporter: "src/custom-reporter.js",
reporterOptions: {
mochaFile: `${config.reportsDir}/[suite].xml`
mochaFile: `${reportsDir}/[suite].xml`
}
}
});
Expand All @@ -57,4 +86,9 @@ const cypressRunner = async function () {
}
}

// For dev and test purposes, this allows us to run our Cypress Runner from command line
if (require.main === module) {
cypressRunner();
}

exports.cypressRunner = cypressRunner
2 changes: 1 addition & 1 deletion src/sauce-reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ exports.sauceReporter = async (buildName, browserName, spec) => {
'cypress/results'
);

// updaload assets
// upload assets
await Promise.all([
api.uploadJobAssets(
sessionId,
Expand Down
10 changes: 10 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const path = require('path');

function getAbsolutePath(pathToDir) {
if (path.isAbsolute(pathToDir)) {
return pathToDir;
}
return path.join(process.cwd(), pathToDir);
}

module.exports.getAbsolutePath = getAbsolutePath;
14 changes: 14 additions & 0 deletions tests/fixtures/cypress-tests/config-tests/config.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/// <reference types="cypress" />

context('Actions', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/actions')
})

// https://on.cypress.io/interacting-with-elements

it('should use .env.json', () => {
expect(Cypress.env('foo')).to.equal('bar');
})
})

6 changes: 6 additions & 0 deletions tests/fixtures/cypress-tests/config-tests/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
rootDir: ./tests/fixtures/cypress-tests/
targetDir: ./tests/fixtures/cypress-tests/config-tests/
reportsDir: ./results
execCommand:
- npm
- test
5 changes: 5 additions & 0 deletions tests/fixtures/cypress-tests/config-tests/cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"env": {
"foo": "bar"
}
}
6 changes: 6 additions & 0 deletions tests/fixtures/cypress-tests/env-tests/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
rootDir: ./tests/fixtures/cypress-tests/
targetDir: ./tests/fixtures/cypress-tests/env-tests/
reportsDir: ./results
execCommand:
- npm
- test
3 changes: 3 additions & 0 deletions tests/fixtures/cypress-tests/env-tests/cypress.env.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"foo": "BAR"
}
12 changes: 12 additions & 0 deletions tests/fixtures/cypress-tests/env-tests/env.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/// <reference types="cypress" />

context('Actions', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/actions')
})

it('should use .env.json', () => {
expect(Cypress.env('foo')).to.equal('BAR');
})
})

File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 6 additions & 0 deletions tests/fixtures/cypress-tests/kitchen-sink/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
rootDir: ./tests/fixtures/cypress-tests/
targetDir: ./tests/fixtures/cypress-tests/kitchen-sink/
reportsDir: ./results
execCommand:
- npm
- test
File renamed without changes.
File renamed without changes.
4 changes: 4 additions & 0 deletions tests/integration/integration-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export SAUCE_USERNAME=''
export SAUCE_ACCESS_KEY=''
export CONFIG_FILE=./tests/fixtures/cypress-tests/config-tests/config.yaml && node .
export CONFIG_FILE=./tests/fixtures/cypress-tests/kitchen-sink/config.yaml && node .

0 comments on commit 1e9d8c6

Please sign in to comment.