cypress-io / circleci-orb

Install, cache and run Cypress.io tests on CircleCI with minimal configuration.
https://circleci.com/orbs/registry/orb/cypress-io/cypress
MIT License
161 stars 101 forks source link

React + Cypress + Django Setup #372

Closed Thorbenl closed 1 year ago

Thorbenl commented 2 years ago

Hi :)

I want to preface this with: Cypress is amazing. We would really want to use it, but hit a roadblock along the way, which we hope you can help us with/assist a bit.

Our setup

The setup works like this: We have a Django backend, and a React frontend. We built the React + other client files we need and put the relevant info in the static/dist folder, which is cached. Basically a compiled react-app with a few bundles.. Then we boot the django server to serve these static frontend files, since we also need a DB for these functional tests to run, and want to run Cypress against this. We also cache the node_modules folder after installation, because that also has the cypress files. Here is the config:

Orb verison 1.29.0

CircleCI Config:

version: 2.1

orbs:
  node: circleci/node@5.0.2
  python: circleci/python@2.0.3
  browser-tools: circleci/browser-tools@1.2.5
  git-shallow-clone: guitarrapc/git-shallow-clone@2.0.3
  cypress: cypress-io/cypress@1.29.0

workflows:
  version: 2
  build:
    jobs:
      - build_frontend
      - build_backend_and_test
      - functional_test:
          requires:
            - build_backend_and_test
            - build_frontend

executors:
  backend:
    docker:
    - image: cimg/python:3.9.9-browsers
      environment:
        DATABASE_URL: postgres://postgres:postgres@localhost/postgres?sslmode=disable
        USE_DEVEX: 1
        PARALLEL_BUILD_FRONTEND: 1
    - image: '''/''''':circle_ci_db_image-12.9
      auth:
        username: ''''''
        password: $PRIVATE_DOCKER_PASS

jobs:

  build_frontend:
    executor:
      name: node/default
      tag: "16.14.0"
    working_directory: /mnt/ramdisk/
    resource_class: large
    steps:
      - git-shallow-clone/checkout
      - run: git log --format="%H" -n1 frontend > frontend-git-revision.txt && cat frontend-git-revision.txt
      - restore_cache:
          key: frontendbuild-{{ .Environment.FR_CACHE_VERSION }}-{{ checksum "frontend-git-revision.txt" }}
      - restore_cache:
          key: npm-deps-{{ .Environment.FR_DEPS_CACHE_VERSION }}-{{ checksum "frontend/package-lock.json" }}
      - run:
          name: "Build frontend with custom script"
          command: |
            ./scripts/build_frontend.sh
      - save_cache:
          key: frontendbuild-{{ .Environment.FR_CACHE_VERSION }}-{{ checksum "frontend-git-revision.txt" }}
          paths:
            - locale
            - frontend
            - frontend/cypress.json
            - static/dist
            - frontend/locale/messages.pot
      - save_cache:
          key: npm-deps-{{ .Environment.FR_DEPS_CACHE_VERSION }}-{{ checksum "frontend/package-lock.json" }}
          paths:
            - frontend/node_modules
            - .npm
            - .cache
      - persist_to_workspace:
          root: /mnt/ramdisk
          paths:
            - locale
            - frontend
            - static/dist
            - frontend/node_modules

  build_backend_and_test:
    executor: backend
    resource_class: large
    steps:
      - git-shallow-clone/checkout
      - run:
          name: "Install system dependencies"
          command: |
            sudo apt-get update && sudo apt-get install -y gettext
      - python/install-packages:
          pkg-manager: pip
          pip-dependency-file: requirements-dev.txt
          pypi-cache: true
          cache-version: venv-{{ .Environment.BE_CACHE_VERSION }}-{{ checksum "requirements-dev.txt" }}
      - run:
          name: "Backend tests"
          command: |
            #./manage.py test --keepdb --parallel 8 --exclude-tag=functional --timing
       - store_artifacts:
          path: /tmp/artifacts
      - store_artifacts:
          path: test-results
      - store_test_results:
          path: test-results

  functional_test:
    executor: backend
    resource_class: large
    steps:
      - git-shallow-clone/checkout
      - run:
          name: "Install gettext"
          command: |
            sudo apt-get update && sudo apt-get install -y gettext
      - python/install-packages:
          pkg-manager: pip
          pip-dependency-file: requirements-dev.txt
          pypi-cache: true
          cache-version: venv-{{ .Environment.BE_CACHE_VERSION }}-{{ checksum "requirements-dev.txt" }}
      - run:
          name: "Run Functional test server"
          background: true
          command: |
            ./manage.py migrate &&  ./manage.py runserver

      - browser-tools/install-chrome
      - browser-tools/install-chromedriver
      - run: git log --format="%H" -n1 web_ui/frontend > frontend-git-revision.txt && cat frontend-git-revision.txt
      - restore_cache:
          key: frontendbuild-{{ .Environment.FR_CACHE_VERSION }}-{{ checksum "frontend-git-revision.txt" }}
      - run:
          name: "Functional tests"
          command: |
           #npm run cy:run --prefix frontend/ -- --spec "cypress/integration/2-advanced-examples/*.spec.js" --browser chrome
      - store_artifacts:
          path: /tmp/artifacts
      - store_artifacts:
          path: test-results
      - store_test_results:
          path: test-results

Problem Description

We would like to use the orb, so we can use its caching, and also parallel running is important for us, as we have up to 50 functional tests running now.

We aren't sure on how we can achieve this. We know we can use the cypress/run`` job, but we dont know how to tell it "hey orb, use thenode_modulescache from the previous job (build_frontendjob), since we dont want to runcypress/install, since cypress is already available and installed in thebuild_frontendjob. We tried:

      - cypress/run:
          record: false
          parallel: true
          parallelism: 4
          group: 4 machines
          browser: chrome
          spec: "cypress/integration/2-advanced-examples/*.spec.js"
          attach-workspace: true
          working_directory: "web_ui/frontend"
          store_artifacts: true
          cache-key: npm-deps-{{ .Environment.FR_DEPS_CACHE_VERSION }}-{{ checksum "frontend/package-lock.json" }}

and do that in the steps inside the functional_test job.

Sorry if this is a bit cluttered. I am happy to explain further, if necessary.

jordanpowell88 commented 1 year ago

They @Thorbenl sorry for the late response on this. You need to be able to separate this out into 2 jobs.

  1. cypress/install job
  2. cypress/run job

You can see an example here: https://github.com/cypress-io/circleci-orb#parallel

This should provide you want you are looking for