laravel / dusk

Laravel Dusk provides simple end-to-end testing and browser automation.
https://laravel.com/docs/dusk
MIT License
1.88k stars 322 forks source link

Failed dusk test of the ci/cd pipeline on Github #1126

Closed shu-maegawa closed 1 month ago

shu-maegawa commented 1 month ago

Dusk Version

7.9

Laravel Version

9.52.16

PHP Version

8.1

PHPUnit Version

9.5.10

Database Driver & Version

8.0.26

Description

Even if you specify chrome-driver's version as 128 I get the following error in the dusk test of the ci/cd pipeline on Github

laravel.yml run: php artisan dusk:chrome-driver 128

CI/CD error

2) Tests\Browser\Browser\EBilling\Invoice\Detail\PdfDownloadTest::email_download_pdf_button
RuntimeException: Invalid path to Chromedriver [/home/runner/work/system_le-techs/system_le-techs/backend/vendor/laravel/dusk/src/Chrome/../../bin/chromedriver-linux]. Make sure to install the Chromedriver first by running the dusk:chrome-driver command. in /home/runner/work/system_le-techs/system_le-techs/backend/vendor/laravel/dusk/src/Chrome/ChromeProcess.php:56
スクリーンショット 2024-09-09 11 36 41

Steps To Reproduce

name: Laravel CI

on:
  push:
    branches: [ "main" ]
    paths:
      - backend/**
  pull_request:
    types: [ opened, synchronize, reopened ]

env:
  CI: 1
  DB_CONNECTION: mysql
  DB_HOST: 127.0.0.1
  DB_PORT: 3306
  DB_DATABASE: test
  DB_USERNAME: root
  DB_PASSWORD: password
  APP_DEBUG: 0
  APP_ENV: testing
  APP_URL: "http://127.0.0.1:8000"
  BROWSER: chrome
  MAIL_MAILER: log
  SELENIUM_URL: "http://localhost:9515"
  XDEBUG_MODE: off
  ONEDIGI_API_URL: "http://127.0.0.1:3000"
  EXPRESS_PORT: 3000

jobs:
  setups:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: backend
    steps:
      - uses: actions/checkout@v4
      - uses: ./.github/workflows/composite/setup
        with:
          setasign_username: ${{ secrets.SETASIGN_USERNAME }}
          setasign_password: ${{ secrets.SETASIGN_PASSWORD }}
          test_crt_pem: ${{ secrets.TESTCRTPEM }}
          test_key_pem: ${{ secrets.TESTKEYPEM }}
          test_root_ca_pem: ${{ secrets.TESTTSROOTCAPEM }}
  unit-and-feature-tests:
    runs-on: ubuntu-latest
    needs: [ setups ]
    defaults:
      run:
        working-directory: backend

    services:
      mysql:
        image: mysql:8.0.26
        ports:
          - 3306:3306
        options: --health-cmd "mysqladmin ping -h localhost" --health-interval 10s --health-timeout 5s --health-retries 5
        env:
          MYSQL_ROOT_PASSWORD: ${{ env.DB_PASSWORD }}
          MYSQL_DATABASE: ${{ env.DB_DATABASE }}
          TZ: Asia/Tokyo

    steps:
      - uses: actions/checkout@v4
      - uses: ./.github/workflows/composite/setup
        with:
          setasign_username: ${{ secrets.SETASIGN_USERNAME }}
          setasign_password: ${{ secrets.SETASIGN_PASSWORD }}
          test_crt_pem: ${{ secrets.TESTCRTPEM }}
          test_key_pem: ${{ secrets.TESTKEYPEM }}
          test_root_ca_pem: ${{ secrets.TESTTSROOTCAPEM }}
      - name: Migrate & Seed db
        run: php artisan migrate --seed --force
      - name: Unit test
        # run: php artisan test --testsuite=Unit,Feature
        run: php -dpcov.enabled=1 ./vendor/bin/phpunit --testsuite=Unit,Feature --coverage-php /tmp/phpunit-99.cov
      - name: Upload Web Access Logs
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: Unit-web-access-log
          path: backend/storage/logs
      - name: Upload Unit and Feature Coverage
        if: success()
        uses: actions/upload-artifact@v4
        with:
          name: phpunit-coverage-99
          path: /tmp/phpunit-99.cov

  dusk-tests:
    runs-on: ubuntu-latest
    needs: [ setups ]
    defaults:
      run:
        working-directory: backend
    strategy:
      fail-fast: false
      matrix:
        parallelism: [ 6 ]
        id: [ 0,1,2,3,4,5 ]

    services:
      mysql:
        image: mysql:8.0.26
        ports:
          - 3306:3306
        options: --health-cmd "mysqladmin ping -h localhost" --health-interval 10s --health-timeout 5s --health-retries 5
        env:
          MYSQL_ROOT_PASSWORD: ${{ env.DB_PASSWORD }}

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v3
        with:
          node-version: '20'
      - uses: ./.github/workflows/composite/setup
        with:
          setasign_username: ${{ secrets.SETASIGN_USERNAME }}
          setasign_password: ${{ secrets.SETASIGN_PASSWORD }}
          test_crt_pem: ${{ secrets.TESTCRTPEM }}
          test_key_pem: ${{ secrets.TESTKEYPEM }}
          test_root_ca_pem: ${{ secrets.TESTTSROOTCAPEM }}
      - name: Update APT repository
        run: sudo apt update
      - name: Install fonts-ipafont fonts-ipaexfont
        run: sudo apt install fonts-ipafont fonts-ipaexfont
      - name: Install wkhtmltopdf
        run: sudo apt install wkhtmltopdf
      - name: Upgrade Chrome Driver
        run: php artisan dusk:chrome-driver 128
      - name: Start Chrome Driver
        run: ./vendor/laravel/dusk/bin/chromedriver-linux &
      - name: Run Laravel Server
        run: php artisan serve --no-reload &
      - name: Run Laravel Server for PDF generation
        run: php artisan serve --port=8001 --no-reload &
      - name: Migrate & Seed db
        run: php artisan migrate --seed --force
      - name: Set Storage Permissions
        run: chmod -R 777 storage bootstrap/cache
      - name: Create and Copy .env Files
        shell: bash
        run: |
          echo "AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }}" >> .env.sample
          echo "AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }}" >> .env.sample
          echo "LEDGER_DB_NAME=dev-ledger" >> .env.sample
          echo "S3_BUCKET_NAME=one-digit-local-072875515557" >> .env.sample
          cp .env.sample .env
        working-directory: node/app
      - name: Node install
        shell: bash
        run: npm install
        working-directory: node/app
      - name: Start npm run dev
        run: PORT=${{ env.EXPRESS_PORT }} npm run dev &
        working-directory: node/app
      - name: Run Dusk Tests
        # run: php artisan dusk --env=testing
        # run: php artisan test --testsuite=Browser
        # 外部サービスを使って、テストファイルを実行時間ベースで均等に分ける
        run: |
          set -xv
          test_target=$(find tests/Browser/Browser/EBilling/Invoice -name '*Test.php' -type f -printf '%s\t%p\n' \
                    | sort -nr \
                    | cut -f2- \
                    | awk "NR % ${{ matrix.parallelism }} == ${{ matrix.id }}" \
                    | sed -e 's/^/<file>/' -e 's;$;</file>;' \
                    | tr -d '\n')
          sed -i '/\.\/tests\/Unit/c\''' phpunit.xml
          sed -i '/\.\/tests\/Feature/c\''' phpunit.xml
          sed -i '/\.\/tests\/Browser/c\'$test_target'' phpunit.xml
          php -dpcov.enabled=1 ./vendor/bin/phpunit -d memory_limit=-1 --coverage-php /tmp/phpunit-${{ matrix.id }}.cov

      - name: Upload Dusk Screenshots
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: Dusk-screenshots-${{ matrix.id }}
          path: backend/tests/Browser/screenshots
      - name: Upload Console Logs
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: Browser-console-log-${{ matrix.id }}
          path: backend/tests/Browser/console
      - name: Upload Web Access Logs
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: Browser-web-access-log-${{ matrix.id }}
          path: backend/storage/logs
      - name: Upload Dusk Coverage
        uses: actions/upload-artifact@v4
        if: success()
        with:
          name: phpunit-coverage-${{ matrix.id }}
          path: /tmp/phpunit-${{ matrix.id }}.cov
      - name: Stop npm run dev
        run: |
          pkill -f "npm run dev"
        working-directory: node/app

  coverage:
    runs-on: ubuntu-latest
    needs:
      - unit-and-feature-tests
      - dusk-tests
    defaults:
      run:
        working-directory: backend

    steps:
      - uses: actions/checkout@v4
      - uses: ./.github/workflows/composite/setup
        with:
          setasign_username: ${{ secrets.SETASIGN_USERNAME }}
          setasign_password: ${{ secrets.SETASIGN_PASSWORD }}
          test_crt_pem: ${{ secrets.TESTCRTPEM }}
          test_key_pem: ${{ secrets.TESTKEYPEM }}
          test_root_ca_pem: ${{ secrets.TESTTSROOTCAPEM }}
      - name: Download Coverage File
        uses: actions/download-artifact@v4
        with:
          path: ./backend/tmp/
          pattern: phpunit-coverage-*
          merge-multiple: true
      - name: Merge Coverage Files
        run: ./vendor/bin/phpcov merge --html ./tmp/coverage/coverage.html --clover ./tmp/coverage/coverage.xml ./tmp/
      - name: Upload Coverage
        uses: actions/upload-artifact@v4
        with:
          name: final-phpunit-coverage
          path: backend/tmp/coverage

  phpstan-and-codesniffer-check:
    runs-on: ubuntu-latest
    needs: [ setups ]
    defaults:
      run:
        working-directory: backend

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: ./.github/workflows/composite/setup
        with:
          setasign_username: ${{ secrets.SETASIGN_USERNAME }}
          setasign_password: ${{ secrets.SETASIGN_PASSWORD }}
      - name: Fetch base branch
        run: git fetch origin ${{ github.event.pull_request.base.ref }}:${{ github.event.pull_request.base.ref }}
      - name: Get changed PHP files
        id: get-changed-php-files
        run: |
          changed_files=$(git diff --name-only --diff-filter=d ${{ github.event.pull_request.base.sha }} ${{ github.sha }} | grep '.php$' | sed 's/backend\///g' | tr '\n' ' ')
          echo "changed_files=$changed_files" >> $GITHUB_OUTPUT
          if [ "$changed_files" != "" ]; then
            echo "detected=1" >> $GITHUB_OUTPUT
          else
            echo "detected=0" >> $GITHUB_OUTPUT
          fi
      - name: Run PHPStan on changed files
        if: steps.get-changed-php-files.outputs.detected == 1
        run: ./vendor/bin/phpstan analyse ${{ steps.get-changed-php-files.outputs.changed_files }} || echo "PHPSTAN_ERROR_FLAG=1" >> $GITHUB_ENV
      - name: Run CodeSniffer on changed files
        if: steps.get-changed-php-files.outputs.detected == 1
        run: vendor/bin/phpcs ${{ steps.get-changed-php-files.outputs.changed_files }} || echo "CODESNIFFER_ERROR_FLAG=1" >> $GITHUB_ENV
      - name: Check whether PHPStan or PHPCodeSniffer failed
        run: |
          PHPSTAN_ERROR_FLAG="${{ env.PHPSTAN_ERROR_FLAG }}"
          CODESNIFFER_ERROR_FLAG="${{ env.CODESNIFFER_ERROR_FLAG }}"
          if [ "$PHPSTAN_ERROR_FLAG" == '1' ] && [ "$CODESNIFFER_ERROR_FLAG" == '1' ]; then
            echo "Errors detected in PHPStan and CodeSniffer"
            exit 1
          elif [ "$PHPSTAN_ERROR_FLAG" == '1' ]; then
            echo "Errors detected in PHPStan"
            exit 1
          elif [ "$CODESNIFFER_ERROR_FLAG" == '1' ]; then
            echo "Errors detected in CodeSniffer"
            exit 1
          fi

  eslint-and-stylelint-check:
    runs-on: ubuntu-latest
    needs: [ setups ]
    defaults:
      run:
        working-directory: backend

    steps:
      - uses: actions/checkout@v4
      - uses: ./.github/workflows/composite/setup
        with:
          setasign_username: ${{ secrets.SETASIGN_USERNAME }}
          setasign_password: ${{ secrets.SETASIGN_PASSWORD }}
      - name: RUN eslint
        run: bun run eslint
      - name: RUN stylelint
        run: bun run stylelint

  # security-check:
  #   runs-on: ubuntu-latest
  #   defaults:
  #     run:
  #       working-directory: backend
  #   steps:
  #     - uses: actions/checkout@v4
  #     - name: Setup PHP with PECL extension
  #       uses: shivammathur/setup-php@v2
  #       with:
  #         php-version: '8.1'
  #         tools: phpmd
  #     - name: Run composer audit
  #       continue-on-error: true
  #       run: composer audit --locked
  #     - name: Run PhpMD
  #       run: phpmd ./ html phpmd.xml --reportfile ./phpmd.report.html
  #     - name: Upload PhpMD report files
  #       if: always()
  #       uses: actions/upload-artifact@v4
  #       with:
  #         name: PhpMD-report-file
  #         path: backend/phpmd.report.html
crynobone commented 1 month ago

Hey there,

Unfortunately we don't support this version of the library anymore. Please check out our support policy on which versions we are currently supporting. Can you please try to upgrade to the latest version and see if your problem persists? If so, please open up a new issue and we'll help you out.

Thanks!

crynobone commented 1 month ago

@shu-maegawa you should upgrade to latest Laravel Dusk 8 as soon as possible or utilise alternative Chrome Driver installation such as https://github.com/orchestral/dusk-updater