Search code examples
javascriptgoogle-chromegithub-actionscypress

Running canary and stable chrome versions on Cypress in CI


For cypress, I have a regular github CI workflow running chrome and a cron job running chrome' canary version. My initial thought was to use a cypress/included image for chrome and then install chrome canary, but when I did that, github could not find the canary unless I explicitly set it in cypress.config.ts. But then my non-cron job started failing unless i also explictly set chrome in cypress.config.ts, forcing me to expand the config.ts array.

My questions:

  1. How can I make the cypress.config just download the latest stable versions of the chrome and edge browsers instead of pinning it to a specific image
  2. Why do I need to add the canary versions in the config.ts file at all, why didn't the install of the canary versions in the ci.yaml just work? (I kept getting the cypress error that the browser was not installed). This browsers workaround is nice in that it avoids running electron by default, but I didn't want to hard code these browser versions in the first place. This is just the first thing I tried that worked.

I posted in the cypress discord but no response. I also don't see much info in the cypress docs on what to put in the browser array in config.ts except browser: 'chrome'. The other params came from chatgpt and I'm not sure where chatgpt found them.

Here's a shortened version of my non-cron yaml, I've only put the steps related to cypress and not for the build etc:

name: 🧪 Run Cypress Tests for App
on:
  workflow_call:
 
  cypress_tests_consumer_app:
    name: 🧪 Cypress Test Matrix
    if: ${{ inputs.consumer_app_changes_made || inputs.packages_change_made }}
    strategy:
      fail-fast: false
      matrix:
        browser: [chrome, edge]
        runner: [1, 2, 3, 4, 5, 6, 7, 8]
    runs-on: ubuntu-20.04
    container:
      image: cypress/included:cypress-14.0.0-node-22.13.1-chrome-132.0.6834.83-1-ff-134.0.2-edge-132.0.2957.115-1
    env:
      GH_REGISTRY_TOKEN: ${{ secrets.GH_REGISTRY_TOKEN }}
      NODE_OPTIONS: '--max-old-space-size=4096'
    steps:
      - name: 🔄 [Git] Checkout Repository (LFS)
        uses: actions/checkout@v4
        with:
          fetch-depth: 1
          lfs: true

      - name: 🧪 [Test] Execute Cypress Tests
        uses: cypress-io/github-action@v6
        with:
          install: false
          working-directory: apps/consumer-app
          start: yarn next start
          command: yarn run --binaries-only cypress run
            --config baseUrl=http://127.0.0.1:3000/
            --record
            --parallel
            --headless
            --group consumer-app-${{ matrix.browser }}
            --tag local
            --ci-build-id '${{ github.sha }}-consumer-app'
            --browser ${{ matrix.browser }}
            --spec cypress/e2e/**/*cy.ts
            --env CYPRESS_ENV=test
          wait-on: 'http://127.0.0.1:3000/'
          wait-on-timeout: 120
        env:
          CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_DASHBOARD_FRONTEND_CORE_CONSUMER_API_KEY }}
          COMMIT_INFO_MESSAGE: ${{ github.event.head_commit.message }}  

And here's my cron yaml:

name: 🕒 Scheduled Cypress Tests for Consumer App -- Canary
on:
  workflow_call:
  workflow_dispatch: #adds ability to run jobs manually

jobs:
  test_cypress_consumer_cron:
    name: 🕒 Run Consumer App Cypress Tests 🧪
    strategy:
      fail-fast: false
      matrix:
        browser: ["edge:dev", "chrome:canary"]
        runner: [1, 2, 3, 4, 5, 6, 7, 8]
    runs-on: ubuntu-20.04
    container:
      image: cypress/included:cypress-14.0.0-node-22.13.1-chrome-132.0.6834.83-1-ff-134.0.2-edge-132.0.2957.115-1
    env:
      GH_REGISTRY_TOKEN: ${{ secrets.GH_REGISTRY_TOKEN }}
      NODE_OPTIONS: '--max-old-space-size=4096'
    steps:
    - name: 📦 [Deps] Install gnupg
      run: |
        apt-get update -qq && apt-get install -y gnupg
       
    - name: 📦 [Deps] Install Chrome Canary
      run: |
        wget -O google-chrome-canary.deb https://dl.google.com/linux/direct/google-chrome-unstable_current_amd64.deb
        dpkg -i google-chrome-canary.deb
        apt-get install -f

    - name: 📦 [Deps] Install Edge Dev
      run: |
          wget -q -O - https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
          sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/edge stable main" > /etc/apt/sources.list.d/microsoft-edge.list'
          apt-get update -qq
          apt-get install -y microsoft-edge-dev
    
    - name: 🧪 [Test] Run Cypress Tests for Consumer App
      uses: cypress-io/github-action@v6
      with:
        install: false
        working-directory: apps/consumer-app
        command: |
          yarn run --binaries-only cypress run \
          --config baseUrl=http://127.0.0.1:3000 \
          --browser ${{ matrix.browser }} \
          --spec cypress/e2e/*/*cy.ts \
          --env CYPRESS_ENV=test \
          --headless \
          --parallel \
          --group consumer-app-cron--${{ matrix.browser }} \
          --record
        wait-on: 'http://127.0.0.1:3000/'
        wait-on-timeout: 120    
      env:
        CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_DASHBOARD_FRONTEND_CORE_CONSUMER_API_KEY }} 
        COMMIT_INFO_MESSAGE: ${{ github.event.head_commit.message }}  

And here's what's in my config file

browsers: [
    {
      name: 'chrome',
      family: 'chromium',
      displayName: 'Chrome',
      version: '132.0.6834.83-1',
      majorVersion: 132,
      path: '/usr/bin/google-chrome',
      channel: 'stable',
    },
    {
      name: 'chrome',
      channel: 'canary',
      family: 'chromium',
      displayName: 'Chrome Canary',
      version: '132.0.6805.0',
      majorVersion: 132,
      path: '/usr/bin/google-chrome-unstable',
    },
    {
      name: 'edge',
      family: 'chromium',
      displayName: 'Edge',
      version: '132.0.2957.115-1',
      majorVersion: 132,
      path: '/usr/bin/microsoft-edge',
      channel: 'stable',
    },
    {
      name: 'edge',
      channel: 'dev',
      family: 'chromium',
      displayName: 'Edge Dev',
      version: '92.0.902.2', // Example version, replace with the actual version
      majorVersion: 92, // Example major version, replace with the actual major version
      path: '/usr/bin/microsoft-edge-dev',
    },
  ],

Solution

  • For the question How do I get the version of the currently installed browser.

    The answer is here Customize available browsers (second block).

    Essentially, the config reaches out to the OS using execa() to find the current version of the specified browser.

    You seem to have multiple browser types, so some adjustment to this code will be needed

    const { defineConfig } = require('cypress')
    const execa = require('execa')
    
    const findBrowser = () => {
      // the path is hard-coded for simplicity
      const browserPath =
        '/Applications/Brave Browser.app/Contents/MacOS/Brave Browser'
    
      return execa(browserPath, ['--version']).then((result) => {
        // STDOUT will be like "Brave Browser 77.0.69.135"
        const [, version] = /Brave Browser (\d+\.\d+\.\d+\.\d+)/.exec(result.stdout)
        const majorVersion = parseInt(version.split('.')[0])
    
        return {
          name: 'Brave',
          channel: 'stable',
          family: 'chromium',
          displayName: 'Brave',
          version,
          path: browserPath,
          majorVersion,
        }
      })
    }
    
    module.exports = defineConfig({
      // setupNodeEvents can be defined in either
      // the e2e or component configuration
      e2e: {
        setupNodeEvents(on, config) {
          return findBrowser().then((browser) => {
            return {
              browsers: config.browsers.concat(browser),
            }
          })
        },
      },
    })
    

    For the question How can I make the cypress.config just download the latest stable.

    • Not sure you want to since it's not a quick step.
    • Not sure you could install things from Cypress config.