version: 2.1 defaults: &defaults parallelism: 1 working_directory: ~/cypress parameters: executor: type: executor default: cy-doc executor: <> environment: ## set specific timezone TZ: "/usr/share/zoneinfo/America/New_York" ## store artifacts here CIRCLE_ARTIFACTS: /tmp/artifacts ## set so that e2e tests are consistent COLUMNS: 100 LINES: 24 executors: # the Docker image with Cypress dependencies and Chrome browser cy-doc: docker: - image: cypress/browsers:node8.9.3-chrome73 environment: PLATFORM: linux # executor to run on Mac OS # https://circleci.com/docs/2.0/executor-types/#using-macos # https://circleci.com/docs/2.0/testing-ios/#supported-xcode-versions mac: macos: xcode: "10.1.0" environment: PLATFORM: mac jobs: ## code checkout and NPM installs build: <<: *defaults steps: - checkout - run: name: Print working folder command: echo $PWD - run: name: print global NPM cache path command: echo $(npm -g bin) - run: name: print Node version command: node -v - run: name: print NPM version command: npm -v - run: npm run check-node-version ## make sure the TERM is set to 'xterm' in node (Linux only) ## else colors (and tests) will fail ## See the following information ## * http://andykdocs.de/development/Docker/Fixing+the+Docker+TERM+variable+issue ## * https://unix.stackexchange.com/questions/43945/whats-the-difference-between-various-term-variables - run: npm run check-terminal # need to restore a separate cache for each package.json - restore_cache: key: v8-{{ arch }}-{{ .Branch }}-cli-deps - restore_cache: key: v5-{{ arch }}-{{ .Branch }}-root-deps - restore_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-coffee - restore_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-desktop-gui - restore_cache: key: v6-{{ arch }}-{{ .Branch }}-deps-driver - restore_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-example - restore_cache: key: v7-{{ arch }}-{{ .Branch }}-deps-electron - restore_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-extension - restore_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-https-proxy - restore_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-launcher - restore_cache: key: v1-{{ arch }}-{{ .Branch }}-deps-network - restore_cache: key: v8-{{ arch }}-{{ .Branch }}-deps-reporter - restore_cache: key: v8-{{ arch }}-{{ .Branch }}-deps-runner - restore_cache: key: v8-{{ arch }}-{{ .Branch }}-deps-server - restore_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-socket - restore_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-static - restore_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-ts # show what is already cached globally - run: ls $(npm -g bin) - run: ls $(npm -g bin)/../lib/node_modules # only installs the root dependencies, without going into packages # via postinstall script - run: npm install --ignore-scripts - run: name: Top level packages command: npm ls --depth=0 || true ## symlink all of our sub packages in node_modules - run: npm run link ## now install all of the sub packages node_modules - run: npm run all install -- --serial - run: npm run all prune # save each node_modules folder per package - save_cache: key: v8-{{ arch }}-{{ .Branch }}-cli-deps-{{ checksum "cli/package.json" }} paths: - cli/node_modules - save_cache: key: v5-{{ arch }}-{{ .Branch }}-root-deps-{{ checksum "package.json" }} paths: - node_modules - save_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-coffee-{{ checksum "packages/coffee/package.json" }} paths: - packages/coffee/node_modules - save_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-desktop-gui-{{ checksum "packages/desktop-gui/package.json" }} paths: - packages/desktop-gui/node_modules - save_cache: key: v6-{{ arch }}-{{ .Branch }}-deps-driver-{{ checksum "packages/driver/package.json" }} paths: - packages/driver/node_modules - save_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-example-{{ checksum "packages/example/package.json" }} paths: - packages/example/node_modules - save_cache: key: v7-{{ arch }}-{{ .Branch }}-deps-electron-{{ checksum "packages/electron/package.json" }} paths: - packages/electron/node_modules - ~/.cache/electron - ~/.electron - save_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-extension-{{ checksum "packages/extension/package.json" }} paths: - packages/extension/node_modules - save_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-https-proxy-{{ checksum "packages/https-proxy/package.json" }} paths: - packages/https-proxy/node_modules - save_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-launcher-{{ checksum "packages/launcher/package.json" }} paths: - packages/launcher/node_modules - save_cache: key: v1-{{ arch }}-{{ .Branch }}-deps-network-{{ checksum "packages/network/package.json" }} paths: - packages/network/node_modules - save_cache: key: v8-{{ arch }}-{{ .Branch }}-deps-reporter-{{ checksum "packages/reporter/package.json" }} paths: - packages/reporter/node_modules - save_cache: key: v8-{{ arch }}-{{ .Branch }}-deps-runner-{{ checksum "packages/runner/package.json" }} paths: - packages/runner/node_modules - save_cache: key: v8-{{ arch }}-{{ .Branch }}-deps-server-{{ checksum "packages/server/package.json" }} paths: - packages/server/node_modules - save_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-socket-{{ checksum "packages/socket/package.json" }} paths: - packages/socket/node_modules - save_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-static-{{ checksum "packages/static/package.json" }} paths: - packages/static/node_modules - save_cache: key: v5-{{ arch }}-{{ .Branch }}-deps-ts-{{ checksum "packages/ts/package.json" }} paths: - packages/ts/node_modules - run: npm run stop-only ## now go build all of subpackages - run: npm run prebuild -- --serial - run: npm run build -- --serial ## save entire folder as artifact for other jobs to run without reinstalling - persist_to_workspace: root: ~/ paths: - cypress lint: <<: *defaults steps: - attach_workspace: at: ~/ - run: npm run lint - run: npm run all lint unit-tests: <<: *defaults parallelism: 1 steps: - attach_workspace: at: ~/ # make sure mocha runs - run: npm run test-mocha # test binary build code - run: npm run test-scripts # make sure our snapshots are compared correctly - run: npm run test-mocha-snapshot # make sure packages with TypeScript can be transpiled to JS - run: npm run all build-js # run unit tests from individual packages - run: npm run all test -- --package cli - run: npm run all test -- --package electron - run: npm run all test -- --package extension - run: npm run all test -- --package https-proxy - run: npm run all test -- --package launcher - run: npm run all test -- --package network # how to pass Mocha reporter through zunder? - run: npm run all test -- --package reporter - run: npm run all test -- --package runner - run: npm run all test -- --package socket - run: npm run all test -- --package static - store_test_results: path: /tmp/cypress lint-typescript: <<: *defaults parallelism: 1 steps: - attach_workspace: at: ~/ - run: command: ls -la types working_directory: cli - run: command: ls -la chai working_directory: cli/types - run: command: npm run dtslint working_directory: cli "server-unit-tests": <<: *defaults parallelism: 2 steps: - attach_workspace: at: ~/ - run: npm run all test-unit -- --package server - store_test_results: path: /tmp/cypress "server-integration-tests": <<: *defaults parallelism: 2 steps: - attach_workspace: at: ~/ - run: npm run all test-integration -- --package server - store_test_results: path: /tmp/cypress "server-performance-tests": <<: *defaults steps: - attach_workspace: at: ~/ - run: environment: DEBUG: test:proxy-performance command: npm run all test-performance -- --package server - store_test_results: path: /tmp/cypress - store_artifacts: path: /tmp/artifacts "server-e2e-tests-1": <<: *defaults steps: - attach_workspace: at: ~/ - run: command: npm run test-e2e -- --chunk 1 working_directory: packages/server - store_test_results: path: /tmp/cypress "server-e2e-tests-2": <<: *defaults steps: - attach_workspace: at: ~/ - run: command: npm run test-e2e -- --chunk 2 working_directory: packages/server - store_test_results: path: /tmp/cypress "server-e2e-tests-3": <<: *defaults steps: - attach_workspace: at: ~/ - run: command: npm run test-e2e -- --chunk 3 working_directory: packages/server - store_test_results: path: /tmp/cypress "server-e2e-tests-4": <<: *defaults steps: - attach_workspace: at: ~/ - run: command: npm run test-e2e -- --chunk 4 working_directory: packages/server - store_test_results: path: /tmp/cypress "server-e2e-tests-5": <<: *defaults steps: - attach_workspace: at: ~/ - run: command: npm run test-e2e -- --chunk 5 working_directory: packages/server - store_test_results: path: /tmp/cypress "server-e2e-tests-6": <<: *defaults steps: - attach_workspace: at: ~/ - run: command: npm run test-e2e -- --chunk 6 working_directory: packages/server - store_test_results: path: /tmp/cypress "server-e2e-tests-7": <<: *defaults steps: - attach_workspace: at: ~/ - run: command: npm run test-e2e -- --chunk 7 working_directory: packages/server - store_test_results: path: /tmp/cypress "server-e2e-tests-8": <<: *defaults steps: - attach_workspace: at: ~/ - run: command: npm run test-e2e -- --chunk 8 working_directory: packages/server - store_test_results: path: /tmp/cypress "driver-integration-tests-3x": <<: *defaults parallelism: 3 steps: - attach_workspace: at: ~/ - run: command: npm start background: true working_directory: packages/driver - run: command: $(npm bin)/wait-on http://localhost:3500 working_directory: packages/driver - run: command: | CYPRESS_KONFIG_ENV=production \ CYPRESS_RECORD_KEY=$PACKAGES_RECORD_KEY \ npm run cypress:run -- --record --parallel --group 3x-driver-chrome --browser chrome working_directory: packages/driver - store_test_results: path: /tmp/cypress - store_artifacts: path: /tmp/artifacts "desktop-gui-integration-tests-2x": <<: *defaults parallelism: 2 steps: - attach_workspace: at: ~/ - run: command: npm run build-prod working_directory: packages/desktop-gui - run: command: | CYPRESS_KONFIG_ENV=production \ CYPRESS_RECORD_KEY=$PACKAGES_RECORD_KEY \ npm run cypress:run -- --record --parallel --group 2x-desktop-gui working_directory: packages/desktop-gui - store_test_results: path: /tmp/cypress - store_artifacts: path: /tmp/artifacts "reporter-integration-tests": <<: *defaults steps: - attach_workspace: at: ~/ - run: command: npm run build-prod working_directory: packages/reporter - run: command: | CYPRESS_KONFIG_ENV=production \ CYPRESS_RECORD_KEY=$PACKAGES_RECORD_KEY \ npm run cypress:run -- --record --parallel --group reporter working_directory: packages/reporter - store_test_results: path: /tmp/cypress - store_artifacts: path: /tmp/artifacts "run-launcher": <<: *defaults steps: - attach_workspace: at: ~/ - run: command: node index.js working_directory: packages/launcher build-binary: <<: *defaults shell: /bin/bash --login steps: - run: name: Check environment variables before code sign (if on Mac) # NOTE # our Mac code sign works via electron-builder # by default, electron-builder will NOT sign app built in a pull request # even our internal one (!) # Usually this is not a problem, since we only build and test binary # built on "develop" and "master" branches # but if you need to really build and sign a Mac binary in a PR # set variable CSC_FOR_PULL_REQUEST=true command: | set -e if [[ "$OSTYPE" == "darwin"* ]]; then if [ -z "$CSC_LINK" ]; then echo "Need to provide environment variable CSC_LINK" echo "with base64 encoded certificate .p12 file" exit 1 fi if [ -z "$CSC_KEY_PASSWORD" ]; then echo "Need to provide environment variable CSC_KEY_PASSWORD" echo "with password for unlocking certificate .p12 file" exit 1 fi else echo "Not Mac platform, skipping code sign setup" fi - attach_workspace: at: ~/ - run: $(npm bin)/print-arch - run: environment: DEBUG: electron-builder,electron-osx-sign* command: npm run binary-build -- --platform $PLATFORM --version $NEXT_DEV_VERSION - run: npm run binary-zip -- --platform $PLATFORM - run: ls -l *.zip - run: name: upload unique binary command: | node scripts/binary.js upload-unique-binary \ --file cypress.zip \ --version $NEXT_DEV_VERSION - run: cat binary-url.json - run: mkdir /tmp/urls - run: cp binary-url.json /tmp/urls - run: cp cypress.zip /tmp/urls - run: ls /tmp/urls - persist_to_workspace: root: /tmp/urls paths: - binary-url.json - cypress.zip "test-kitchensink-against-staging": <<: *defaults steps: - attach_workspace: at: ~/ - run: name: Cloning test project command: git clone https://github.com/cypress-io/cypress-example-kitchensink.git /tmp/repo - run: name: Install prod dependencies command: npm install --production working_directory: /tmp/repo - run: name: Example server command: npm start working_directory: /tmp/repo background: true - run: name: Run Kitchensink example project command: | CYPRESS_PROJECT_ID=$TEST_KITCHENSINK_PROJECT_ID \ CYPRESS_RECORD_KEY=$TEST_KITCHENSINK_RECORD_KEY \ CYPRESS_ENV=staging \ CYPRESS_video=false \ npm run cypress:run -- --project /tmp/repo --record "test-against-staging": <<: *defaults steps: - attach_workspace: at: ~/ - run: name: Cloning test project command: git clone https://github.com/cypress-io/cypress-test-tiny.git /tmp/repo - run: name: Run test project command: | CYPRESS_PROJECT_ID=$TEST_TINY_PROJECT_ID \ CYPRESS_RECORD_KEY=$TEST_TINY_RECORD_KEY \ CYPRESS_ENV=staging \ npm run cypress:run -- --project /tmp/repo --record "build-npm-package": <<: *defaults steps: - attach_workspace: at: ~/ - run: name: bump NPM version command: npm --no-git-tag-version version $NEXT_DEV_VERSION - run: name: build NPM package working_directory: cli command: npm run build - run: command: ls -la types working_directory: cli/build - run: name: list NPM package contents working_directory: cli/build command: npm run size - run: name: pack NPM package working_directory: cli/build command: npm pack - run: name: list created NPM package working_directory: cli/build command: ls -l # created file should have filename cypress-.tgz - run: name: upload NPM package command: | node scripts/binary.js upload-npm-package \ --file cli/build/cypress-$NEXT_DEV_VERSION.tgz \ --version $NEXT_DEV_VERSION - run: cat npm-package-url.json - run: mkdir /tmp/urls - run: cp cli/build/cypress-$NEXT_DEV_VERSION.tgz /tmp/urls/cypress.tgz - run: cp npm-package-url.json /tmp/urls - run: ls /tmp/urls - persist_to_workspace: root: /tmp/urls paths: - npm-package-url.json - cypress.tgz "test-binary-and-npm-against-other-projects": <<: *defaults steps: - attach_workspace: at: ~/ - attach_workspace: at: /tmp/urls - run: ls -la /tmp/urls - run: cat /tmp/urls/*.json - run: mkdir /tmp/testing - run: name: create dummy package working_directory: /tmp/testing command: npm init -y - run: # install NPM from unique urls name: Install Cypress command: | node scripts/test-unique-npm-and-binary.js \ --npm /tmp/urls/npm-package-url.json \ --binary /tmp/urls/binary-url.json \ --cwd /tmp/testing - run: name: Verify Cypress binary working_directory: /tmp/testing command: $(npm bin)/cypress verify - run: name: Running other test projects with new NPM package and binary command: | node scripts/test-other-projects.js \ --npm /tmp/urls/npm-package-url.json \ --binary /tmp/urls/binary-url.json \ --provider circle "test-npm-module-and-verify-binary": <<: *defaults steps: - attach_workspace: at: ~/ - attach_workspace: at: /tmp/urls # make sure we have cypress.zip received - run: ls -l /tmp/urls/cypress.zip # build NPM package - run: command: npm run build working_directory: cli - run: mkdir test-binary - run: name: Create new NPM package working_directory: test-binary command: npm init -y - run: # install NPM from built NPM package folder name: Install Cypress working_directory: test-binary # force installing the freshly built binary command: CYPRESS_INSTALL_BINARY=/tmp/urls/cypress.zip npm i /tmp/urls/cypress.tgz - run: name: Verify Cypress binary working_directory: test-binary command: $(npm bin)/cypress verify # install NPM + binary zip and run against staging API "test-binary-against-staging": <<: *defaults steps: - attach_workspace: at: ~/ - attach_workspace: at: /tmp/urls # make sure we have the binary - run: ls -l /tmp/urls/cypress.zip # make sure we have the NPM package - run: ls -l /tmp/urls/cypress.tgz - run: name: Cloning test project command: git clone https://github.com/cypress-io/cypress-test-tiny.git /tmp/cypress-test-tiny - run: name: Install Cypress working_directory: /tmp/cypress-test-tiny # force installing the freshly built binary command: CYPRESS_INSTALL_BINARY=/tmp/urls/cypress.zip npm i /tmp/urls/cypress.tgz - run: name: Run test project working_directory: /tmp/cypress-test-tiny command: | CYPRESS_PROJECT_ID=$TEST_TINY_PROJECT_ID \ CYPRESS_RECORD_KEY=$TEST_TINY_RECORD_KEY \ CYPRESS_ENV=staging \ $(npm bin)/cypress run --record "test-binary-against-kitchensink": <<: *defaults steps: - attach_workspace: at: ~/ - attach_workspace: at: /tmp/urls - run: name: Cloning kitchensink project command: git clone --depth 1 https://github.com/cypress-io/cypress-example-kitchensink.git /tmp/kitchensink - run: command: npm install working_directory: /tmp/kitchensink - run: name: Install Cypress working_directory: /tmp/kitchensink # force installing the freshly built binary command: CYPRESS_INSTALL_BINARY=/tmp/urls/cypress.zip npm i /tmp/urls/cypress.tgz - run: working_directory: /tmp/kitchensink command: npm run build - run: working_directory: /tmp/kitchensink command: npm start background: true - run: working_directory: /tmp/kitchensink command: npm run e2e linux-workflow: &linux-workflow jobs: - build - lint: name: Linux lint requires: - build - lint-typescript: requires: - build # unit, integration and e2e tests - unit-tests: requires: - build - server-unit-tests: requires: - build - server-integration-tests: requires: - build - server-performance-tests: requires: - build - server-e2e-tests-1: requires: - build - server-e2e-tests-2: requires: - build - server-e2e-tests-3: requires: - build - server-e2e-tests-4: requires: - build - server-e2e-tests-5: requires: - build - server-e2e-tests-6: requires: - build - server-e2e-tests-7: requires: - build - server-e2e-tests-8: requires: - build - driver-integration-tests-3x: requires: - build - desktop-gui-integration-tests-2x: requires: - build - reporter-integration-tests: requires: - build - run-launcher: requires: - build # various testing scenarios, like building full binary # and testing it on a real project - test-against-staging: filters: branches: only: - develop requires: - build - test-kitchensink-against-staging: filters: branches: only: - develop requires: - build - build-npm-package: filters: branches: only: - develop - binary-metadata requires: - build - build-binary: filters: branches: only: - develop - binary-metadata requires: - build - test-binary-and-npm-against-other-projects: filters: branches: only: - develop - binary-metadata requires: - build-npm-package - build-binary - test-npm-module-and-verify-binary: filters: branches: only: - develop requires: - build-npm-package - build-binary - test-binary-against-staging: filters: branches: only: - develop requires: - build-npm-package - build-binary - test-binary-against-kitchensink: filters: branches: only: - develop requires: - build-npm-package - build-binary mac-workflow: &mac-workflow jobs: - build: name: Mac build executor: mac - lint: name: Mac lint executor: mac requires: - Mac build # maybe run unit tests? - build-npm-package: name: Mac NPM package executor: mac filters: branches: only: - develop requires: - Mac build - build-binary: name: Mac binary executor: mac context: org-global filters: branches: only: - develop - binary-metadata requires: - Mac build - test-binary-against-kitchensink: name: Test Mac binary against kitchensink executor: mac filters: branches: only: - develop requires: - Mac NPM package - Mac binary - test-binary-against-staging: name: Test Mac binary against staging executor: mac filters: branches: only: - develop requires: - Mac NPM package - Mac binary workflows: linux: <<: *linux-workflow mac: <<: *mac-workflow