Knapsack Pro Cypress: Quickstart
Create an account to generate API tokens and use Knapsack Pro.
Installation
Make sure you have cypress
in your package.json
because @knapsack-pro/cypress
uses the version installed in your project.
- npm
- yarn
# Cypress version >=10
npm install --save-dev @knapsack-pro/cypress
# Cypress version <10
npm install --save-dev "@knapsack-pro/cypress@^4.6.0"
# Cypress version >=10
yarn add --dev @knapsack-pro/cypress
# Cypress version <10
yarn add --dev @knapsack-pro/cypress@4.6.0
Now, fill in the following form to generate the instruction steps for your project:
What is your CI provider?
Instructions
AppVeyor
Generate an API token for each Knapsack Pro command on the CI. Each command needs its own API token to treat every test suite as a separate entity.
For each parallel job, define:
Remember to configure the number of parallel CI nodes in AppVeyor.
- Node 1
- Node 2
- Node N
KNAPSACK_PRO_CI_NODE_TOTAL=N \
KNAPSACK_PRO_CI_NODE_INDEX=0 \
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=MY_CYPRESS_API_TOKEN \
npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
KNAPSACK_PRO_CI_NODE_TOTAL=N \
KNAPSACK_PRO_CI_NODE_INDEX=1 \
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=MY_CYPRESS_API_TOKEN \
npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
KNAPSACK_PRO_CI_NODE_TOTAL=N \
KNAPSACK_PRO_CI_NODE_INDEX=N-1 \
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=MY_CYPRESS_API_TOKEN \
npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
Buildkite
Generate an API token for each Knapsack Pro command on the CI. Each command needs its own API token to treat every test suite as a separate entity.
Remember to configure the parallelism
parameter in your build step.
- Node 1
- Node 2
- Node N
npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
When using the docker-compose
plugin on Buildkite, you have to pass the following environment variables:
steps:
- label: "Test"
parallelism: 2
plugins:
- docker-compose#3.0.3:
run: app
command: npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
config: docker-compose.test.yml
env:
- BUILDKITE
- BUILDKITE_PARALLEL_JOB_COUNT
- BUILDKITE_PARALLEL_JOB
- BUILDKITE_BUILD_NUMBER
- BUILDKITE_COMMIT
- BUILDKITE_BRANCH
- BUILDKITE_BUILD_AUTHOR
- BUILDKITE_BUILD_CREATOR
Here you can find an article on how to set up a new pipeline for your project in Buildkite and configure Knapsack Pro.
You can also check out the following example repositories for Ruby on Rails projects:
- Buildkite Rails Parallel Example with Knapsack Pro
- Buildkite Rails Docker Parallel Example with Knapsack Pro
CircleCI
Generate an API token for each Knapsack Pro command on the CI. Each command needs its own API token to treat every test suite as a separate entity.
Remember to add additional parallel containers in the CircleCI settings.
jobs:
build:
parallelism: 2
steps:
- checkout
# ...
- run:
name: cypress with @knapsack-pro/cypress
command: npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
Here you can find an example of a Rails application configured with Knapsack Pro and CircleCI 2.0.
Cirrus CI
Generate an API token for each Knapsack Pro command on the CI. Each command needs its own API token to treat every test suite as a separate entity.
Configure the number of parallel CI nodes with the matrix modification:
task:
environment:
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS: ENCRYPTED[KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS]
matrix:
name: CI Node 0
name: CI Node 1
name: CI Node 2
test_script:
- npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
Remember to set up the KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS
as an encrypted variable.
Here is an example of a .cirrus.yml
configuration file for a Ruby project.
CloudBees CodeShip
Generate an API token for each Knapsack Pro command on the CI. Each command needs its own API token to treat every test suite as a separate entity.
For each parallel pipeline, define:
- Node 1
- Node 2
- Node N
KNAPSACK_PRO_CI_NODE_TOTAL=N \
KNAPSACK_PRO_CI_NODE_INDEX=0 \
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=MY_CYPRESS_API_TOKEN \
npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
KNAPSACK_PRO_CI_NODE_TOTAL=N \
KNAPSACK_PRO_CI_NODE_INDEX=1 \
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=MY_CYPRESS_API_TOKEN \
npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
KNAPSACK_PRO_CI_NODE_TOTAL=N \
KNAPSACK_PRO_CI_NODE_INDEX=N-1 \
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=MY_CYPRESS_API_TOKEN \
npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
Consider moving the KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS
to the Environment page of your project settings in CodeShip.
Codefresh
Generate an API token for each Knapsack Pro command on the CI. Each command needs its own API token to treat every test suite as a separate entity.
Define in .codefresh/codefresh.yml
:
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS
KNAPSACK_PRO_CI_NODE_TOTAL
KNAPSACK_PRO_CI_NODE_INDEX
- In the
matrix
section, list all theKNAPSACK_PRO_CI_NODE_INDEX
es (from0
toKNAPSACK_PRO_CI_NODE_TOTAL-1
).
- In the
Remember to configure the YAML file path on Codefresh: Pipelines > Settings (cog icon next to the pipeline) > Workflow Tab (horizontal menu on the top) > Path to YAML > ./.codefresh/codefresh.yml
.
Here's an example config:
- codefresh.yml
- Dockerfile
version: "1.0"
stages:
- "clone"
- "build"
- "tests"
steps:
main_clone:
type: "git-clone"
description: "Cloning main repository..."
repo: "${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}"
revision: "${{CF_BRANCH}}"
stage: "clone"
BuildTestDockerImage:
title: Building Test Docker image
type: build
arguments:
image_name: "${{CF_ACCOUNT}}/${{CF_REPO_NAME}}-test"
tag: "${{CF_BRANCH_TAG_NORMALIZED}}-${{CF_SHORT_REVISION}}"
dockerfile: Test.Dockerfile
stage: "build"
run_tests:
stage: "tests"
image: "${{BuildTestDockerImage}}"
working_directory: /src
fail_fast: false
environment:
- KNAPSACK_PRO_CI_NODE_TOTAL=2
matrix:
environment:
- KNAPSACK_PRO_CI_NODE_INDEX=0
- KNAPSACK_PRO_CI_NODE_INDEX=1
commands:
- (npm run start:ci &) && echo "npm run start:ci running in the background"
- npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
Consider setting up the KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS
on the Codefresh dashboard: Pipelines > Settings (cog icon next to the pipeline) > Variables Tab (vertical menu on the right-hand side).
FROM cypress/base:10
RUN apt-get update && \
apt-get install -y \
python3-dev \
python3-pip
# Install AWS CLI
RUN pip3 install awscli
# Install Codefresh CLI
RUN wget https://github.com/codefresh-io/cli/releases/download/v0.31.1/codefresh-v0.31.1-alpine-x64.tar.gz
RUN tar -xf codefresh-v0.31.1-alpine-x64.tar.gz -C /usr/local/bin/
COPY . /src
WORKDIR /src
RUN npm install
GitHub Actions
Generate an API token for each Knapsack Pro command on the CI. Each command needs its own API token to treat every test suite as a separate entity.
Define in .github/workflows/main.yaml
:
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS
in GitHub Settings > Secrets as described in GitHub Actions' docs.KNAPSACK_PRO_CI_NODE_TOTAL
using thematrix
propertyKNAPSACK_PRO_CI_NODE_INDEX
using thematrix
property
Here's an example config:
name: Main
on: [push]
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [18.x]
ci_node_total: [2]
ci_node_index: [0, 1]
steps:
- uses: actions/checkout@v2
- name: Set up Node
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install and Build
run: |
npm install
npm run build --if-present
- name: Run `npm run start:ci` in the background
run: |
npm run start:ci &
- name: Run tests
env:
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS: ${{ secrets.KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS }}
KNAPSACK_PRO_CI_NODE_TOTAL: ${{ matrix.ci_node_total }}
KNAPSACK_PRO_CI_NODE_INDEX: ${{ matrix.ci_node_index }}
run: |
npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
GitLab CI
Generate an API token for each Knapsack Pro command on the CI. Each command needs its own API token to treat every test suite as a separate entity.
GitLab CI >= 11.5
test:
parallel: 2
script:
- KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=MY_CYPRESS_API_TOKEN npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
See also how to configure running parallel CI nodes in GitLab.
GitLab CI < 11.5
Define in .gitlab-ci.yml
:
Here's an example configuration for 2 parallel jobs:
stages:
- test
variables:
KNAPSACK_PRO_CI_NODE_TOTAL: 2
test_ci_first_node:
stage: test
script:
- export KNAPSACK_PRO_CI_NODE_INDEX=0
- KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=MY_CYPRESS_API_TOKEN npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
test_ci_second_node:
stage: test
script:
- export KNAPSACK_PRO_CI_NODE_INDEX=1
- KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=MY_CYPRESS_API_TOKEN npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
Remember to set up the KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS
as Secret Variables in GitLab CI: Settings > CI/CD Pipelines > Secret Variables.
Heroku CI
Generate an API token for each Knapsack Pro command on the CI. Each command needs its own API token to treat every test suite as a separate entity.
Define in app.json
:
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS
quantity
: number of parallel dynostest
: the Knapsack Pro command
{
"environments": {
"test": {
"formation": {
"test": {
"quantity": 2
}
},
"addons": [
"heroku-postgresql:in-dyno",
"heroku-redis:in-dyno"
],
"scripts": {
"test": "npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false"
},
"env": {
"KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS": "MY_CYPRESS_API_TOKEN"
}
}
}
}
Remember to set up the KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS
outside of app.json
in your Heroku CI pipeline's settings.
Jenkins
Generate an API token for each Knapsack Pro command on the CI. Each command needs its own API token to treat every test suite as a separate entity.
In order to run parallel jobs with Jenkins you should use Jenkins Pipeline as described in Parallelism and Distributed Builds with Jenkins.
Here is an example of a Jenkinsfile
working with Jenkins Pipeline:
timeout(time: 60, unit: 'MINUTES') {
node() {
stage('Checkout') {
checkout([/* checkout code from git */])
// determine git commit hash because we need to pass it to Knapsack Pro
COMMIT_HASH = sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
stash 'source'
}
}
def num_nodes = 4; // define your total number of CI nodes (how many parallel jobs will be executed)
def nodes = [:]
for (int i = 0; i < num_nodes; i++) {
def index = i;
nodes["ci_node_${i}"] = {
node() {
stage('Setup') {
unstash 'source'
// other setup steps
}
def knapsack_options = """\
KNAPSACK_PRO_CI_NODE_TOTAL=${num_nodes}\
KNAPSACK_PRO_CI_NODE_INDEX=${index}\
KNAPSACK_PRO_COMMIT_HASH=${COMMIT_HASH}\
KNAPSACK_PRO_BRANCH=${env.BRANCH_NAME}\
KNAPSACK_PRO_CI_NODE_BUILD_ID=${env.BUILD_TAG}\
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=MY_CYPRESS_API_TOKEN
"""
stage('Run tests') {
sh """${knapsack_options} npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false"""
}
}
}
}
parallel nodes // run CI nodes in parallel
}
Consider setting up the KNAPSACK_PRO_TEST_SUITE_TOKEN_*
as global environment variables in Jenkins.
Semaphore CI
Generate an API token for each Knapsack Pro command on the CI. Each command needs its own API token to treat every test suite as a separate entity.
Define in .semaphore/semaphore.yml
:
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS
parallelism
Here's an example config:
version: v1.0
name: My app
agent:
machine:
type: e1-standard-2
os_image: ubuntu1804
blocks:
- name: Cypress tests
task:
env_vars:
- name: KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS
value: MY_CYPRESS_API_TOKEN
prologue:
commands:
- checkout
- nvm install --lts hydrogen
- sem-version node --lts hydrogen
jobs:
- name: Run tests with Knapsack Pro
parallelism: 2
commands:
- npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
Remember to set up KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS
as a secret.
Travis CI
Generate an API token for each Knapsack Pro command on the CI. Each command needs its own API token to treat every test suite as a separate entity.
Define in .travis.yml
:
script:
- "npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false"
env:
global:
- KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=MY_CYPRESS_API_TOKEN
- KNAPSACK_PRO_CI_NODE_TOTAL=3
jobs:
- KNAPSACK_PRO_CI_NODE_INDEX=0
- KNAPSACK_PRO_CI_NODE_INDEX=1
- KNAPSACK_PRO_CI_NODE_INDEX=2
Remember to set up KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS
as tokens in the Travis settings to avoid exposing them in the build logs.
You can find more info about the global and matrix env configuration in the Travis' docs.
Other CI provider
Generate an API token for each Knapsack Pro command on the CI. Each command needs its own API token to treat every test suite as a separate entity.
Define the following global environment variables on your CI server:
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS
KNAPSACK_PRO_CI_NODE_TOTAL
KNAPSACK_PRO_CI_NODE_INDEX
KNAPSACK_PRO_CI_NODE_BUILD_ID
- Node 1
- Node 2
- Node N
KNAPSACK_PRO_CI_NODE_TOTAL=N \
KNAPSACK_PRO_CI_NODE_INDEX=0 \
KNAPSACK_PRO_CI_NODE_BUILD_ID=MY_BUILD_ID \
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=MY_CYPRESS_API_TOKEN \
npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
KNAPSACK_PRO_CI_NODE_TOTAL=N \
KNAPSACK_PRO_CI_NODE_INDEX=1 \
KNAPSACK_PRO_CI_NODE_BUILD_ID=MY_BUILD_ID \
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=MY_CYPRESS_API_TOKEN \
npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
KNAPSACK_PRO_CI_NODE_TOTAL=N \
KNAPSACK_PRO_CI_NODE_INDEX=N-1 \
KNAPSACK_PRO_CI_NODE_BUILD_ID=MY_BUILD_ID \
KNAPSACK_PRO_TEST_SUITE_TOKEN_CYPRESS=MY_CYPRESS_API_TOKEN \
npx knapsack-pro-cypress --config trashAssetsBeforeRuns=false
Verify that everything works
Push a new commit to your repository and visit your dashboard to make sure all your CI nodes were recorded successfully in Show build metrics > Show (build).
Congratulations! Now that Knapsack Pro knows the statistics of your test suite, your CI builds will be parallelized optimally.
Next up
Make sure you check out the Reference and Cookbook pages to fine-tune your Knapsack Pro setup.
Need help?
We have helped TONS of teams and seen TONS of projects. We know each test suite is a different beast and we'd be happy to help you set up Knapsack Pro.