From 62da9c929e931f7a3ffad74df431657598c83dec Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 11 Oct 2026 07:26:52 +0300 Subject: [PATCH 1/3] Test Selenium 3 with latest browser versions Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01MqZBAjVsaHhnSadusMUzuu --- .github/workflows/tests.yml | 43 +++++++++++++++++++++++++++++++------ tests/Selenium2Config.php | 8 ++++++- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a696b09c..863555c3 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -40,6 +40,9 @@ jobs: tests: name: "Tests (PHP ${{ matrix.php }}, ${{ matrix.browser }}, Selenium ${{ matrix.selenium_version }})${{ matrix.with_coverage == true && ' with coverage' || ''}}" runs-on: ubuntu-latest + env: + # Selenium 3 runs on the runner with latest browser versions, other versions use Docker images with bundled browsers + SELENIUM_IN_DOCKER: ${{ matrix.selenium_version != '3' }} strategy: matrix: browser: [ 'firefox' ] @@ -103,9 +106,35 @@ jobs: mkdir ./logs ./vendor/bin/mink-test-server &> ./logs/mink-test-server.log & - - name: Start Selenium + - name: Setup Chrome + id: setup-chrome + if: ${{ env.SELENIUM_IN_DOCKER == 'false' && matrix.browser == 'chrome' }} + uses: browser-actions/setup-chrome@v2 + with: + install-chromedriver: true + + - name: Setup Firefox + id: setup-firefox + if: ${{ env.SELENIUM_IN_DOCKER == 'false' && matrix.browser == 'firefox' }} + uses: browser-actions/setup-firefox@v1 + + - name: Start Selenium in Docker + if: ${{ env.SELENIUM_IN_DOCKER == 'true' }} run: | SELENIUM_IMAGE=selenium/standalone-${{ matrix.browser }}:${{ matrix.selenium_version }} docker compose up --wait + echo "WEB_FIXTURES_HOST=http://host.docker.internal:8002" >> "$GITHUB_ENV" + echo "DRIVER_MACHINE_BASE_PATH=/fixtures/" >> "$GITHUB_ENV" + + - name: Start Selenium on runner + if: ${{ env.SELENIUM_IN_DOCKER == 'false' }} + env: + BROWSER_BINARY: ${{ steps.setup-chrome.outputs.chrome-path || steps.setup-firefox.outputs.firefox-path }} + CHROMEDRIVER_PATH: ${{ steps.setup-chrome.outputs.chromedriver-path }} + run: | + curl -sSLO https://github.com/SeleniumHQ/selenium/releases/download/selenium-3.141.59/selenium-server-standalone-3.141.59.jar + xvfb-run -a java -Dwebdriver.chrome.driver="$CHROMEDRIVER_PATH" -Dwebdriver.gecko.driver="$GECKOWEBDRIVER/geckodriver" -jar selenium-server-standalone-3.141.59.jar &> ./logs/selenium.log & + echo "WEB_FIXTURES_HOST=http://localhost:8002" >> "$GITHUB_ENV" + echo "BROWSER_BINARY=$BROWSER_BINARY" >> "$GITHUB_ENV" - name: Wait for browser & PHP to start run: | @@ -114,16 +143,18 @@ jobs: - name: Show browser version run: | - docker compose exec selenium sh -c 'google-chrome --version || chromium --version || microsoft-edge --version || firefox --version' 2>/dev/null + if [ "$SELENIUM_IN_DOCKER" = true ]; then + docker compose exec selenium sh -c 'google-chrome --version || chromium --version || microsoft-edge --version || firefox --version' 2>/dev/null + else + "$BROWSER_BINARY" --version + fi - name: Run tests with Coverage if: "${{ matrix.with_coverage == true }}" env: SELENIUM_VERSION: ${{ matrix.selenium_version }} DRIVER_URL: http://localhost:4444/wd/hub - WEB_FIXTURES_HOST: http://host.docker.internal:8002 WEB_FIXTURES_BROWSER: ${{ matrix.browser }} - DRIVER_MACHINE_BASE_PATH: /fixtures/ run: | vendor/bin/phpunit -v --coverage-clover=coverage.xml --log-junit junit.xml @@ -132,9 +163,7 @@ jobs: env: SELENIUM_VERSION: ${{ matrix.selenium_version }} DRIVER_URL: http://localhost:4444/wd/hub - WEB_FIXTURES_HOST: http://host.docker.internal:8002 WEB_FIXTURES_BROWSER: ${{ matrix.browser }} - DRIVER_MACHINE_BASE_PATH: /fixtures/ run: | vendor/bin/phpunit -v --log-junit junit.xml @@ -154,7 +183,7 @@ jobs: report_type: test_results - name: Extract docker logs - if: ${{ failure() }} + if: ${{ failure() && env.SELENIUM_IN_DOCKER == 'true' }} run: | docker compose logs --no-color &> ./logs/selenium.log diff --git a/tests/Selenium2Config.php b/tests/Selenium2Config.php index 89dcc1f8..e2d06a0f 100644 --- a/tests/Selenium2Config.php +++ b/tests/Selenium2Config.php @@ -35,8 +35,14 @@ public function createDriver(): DriverInterface { $browser = getenv('WEB_FIXTURES_BROWSER') ?: 'firefox'; $seleniumHost = $_SERVER['DRIVER_URL']; + $desiredCapabilities = null; - return new Selenium2Driver($browser, null, $seleniumHost); + if (isset($_SERVER['BROWSER_BINARY'])) { + $optionsKey = $browser === 'chrome' ? 'goog:chromeOptions' : 'moz:firefoxOptions'; + $desiredCapabilities = array($optionsKey => array('binary' => $_SERVER['BROWSER_BINARY'])); + } + + return new Selenium2Driver($browser, $desiredCapabilities, $seleniumHost); } public function mapRemoteFilePath($file): string From d6b06509dc41380d461dcbe8aef909bfc0deb7fa Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 11 Oct 2026 07:47:18 +0300 Subject: [PATCH 2/3] Allow Chrome sandbox on CI runner Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01MqZBAjVsaHhnSadusMUzuu --- .github/workflows/tests.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 863555c3..620b8717 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -113,6 +113,12 @@ jobs: with: install-chromedriver: true + # Chrome sandbox needs user namespaces, which AppArmor restricts on Ubuntu 24.04 + # (see https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md) + - name: Allow Chrome sandbox + if: ${{ env.SELENIUM_IN_DOCKER == 'false' && matrix.browser == 'chrome' }} + run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 + - name: Setup Firefox id: setup-firefox if: ${{ env.SELENIUM_IN_DOCKER == 'false' && matrix.browser == 'firefox' }} From 7faaa94ca9aea31f8266edda5a3ed06a8b01ac58 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 11 Oct 2026 16:00:57 +0300 Subject: [PATCH 3/3] Use runner's preinstalled browsers for Selenium 3 They can be up to about a week behind the latest release, but come with matching drivers and need no install steps. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/tests.yml | 28 +++------------------------- tests/Selenium2Config.php | 8 +------- 2 files changed, 4 insertions(+), 32 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 620b8717..91295e30 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,7 +41,7 @@ jobs: name: "Tests (PHP ${{ matrix.php }}, ${{ matrix.browser }}, Selenium ${{ matrix.selenium_version }})${{ matrix.with_coverage == true && ' with coverage' || ''}}" runs-on: ubuntu-latest env: - # Selenium 3 runs on the runner with latest browser versions, other versions use Docker images with bundled browsers + # Selenium 3 runs on the runner with its preinstalled browsers, other versions use Docker images with bundled browsers SELENIUM_IN_DOCKER: ${{ matrix.selenium_version != '3' }} strategy: matrix: @@ -106,24 +106,6 @@ jobs: mkdir ./logs ./vendor/bin/mink-test-server &> ./logs/mink-test-server.log & - - name: Setup Chrome - id: setup-chrome - if: ${{ env.SELENIUM_IN_DOCKER == 'false' && matrix.browser == 'chrome' }} - uses: browser-actions/setup-chrome@v2 - with: - install-chromedriver: true - - # Chrome sandbox needs user namespaces, which AppArmor restricts on Ubuntu 24.04 - # (see https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md) - - name: Allow Chrome sandbox - if: ${{ env.SELENIUM_IN_DOCKER == 'false' && matrix.browser == 'chrome' }} - run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 - - - name: Setup Firefox - id: setup-firefox - if: ${{ env.SELENIUM_IN_DOCKER == 'false' && matrix.browser == 'firefox' }} - uses: browser-actions/setup-firefox@v1 - - name: Start Selenium in Docker if: ${{ env.SELENIUM_IN_DOCKER == 'true' }} run: | @@ -133,14 +115,10 @@ jobs: - name: Start Selenium on runner if: ${{ env.SELENIUM_IN_DOCKER == 'false' }} - env: - BROWSER_BINARY: ${{ steps.setup-chrome.outputs.chrome-path || steps.setup-firefox.outputs.firefox-path }} - CHROMEDRIVER_PATH: ${{ steps.setup-chrome.outputs.chromedriver-path }} run: | curl -sSLO https://github.com/SeleniumHQ/selenium/releases/download/selenium-3.141.59/selenium-server-standalone-3.141.59.jar - xvfb-run -a java -Dwebdriver.chrome.driver="$CHROMEDRIVER_PATH" -Dwebdriver.gecko.driver="$GECKOWEBDRIVER/geckodriver" -jar selenium-server-standalone-3.141.59.jar &> ./logs/selenium.log & + xvfb-run -a java -Dwebdriver.chrome.driver="$CHROMEWEBDRIVER/chromedriver" -Dwebdriver.gecko.driver="$GECKOWEBDRIVER/geckodriver" -jar selenium-server-standalone-3.141.59.jar &> ./logs/selenium.log & echo "WEB_FIXTURES_HOST=http://localhost:8002" >> "$GITHUB_ENV" - echo "BROWSER_BINARY=$BROWSER_BINARY" >> "$GITHUB_ENV" - name: Wait for browser & PHP to start run: | @@ -152,7 +130,7 @@ jobs: if [ "$SELENIUM_IN_DOCKER" = true ]; then docker compose exec selenium sh -c 'google-chrome --version || chromium --version || microsoft-edge --version || firefox --version' 2>/dev/null else - "$BROWSER_BINARY" --version + ${{ matrix.browser == 'chrome' && 'google-chrome' || 'firefox' }} --version fi - name: Run tests with Coverage diff --git a/tests/Selenium2Config.php b/tests/Selenium2Config.php index e2d06a0f..89dcc1f8 100644 --- a/tests/Selenium2Config.php +++ b/tests/Selenium2Config.php @@ -35,14 +35,8 @@ public function createDriver(): DriverInterface { $browser = getenv('WEB_FIXTURES_BROWSER') ?: 'firefox'; $seleniumHost = $_SERVER['DRIVER_URL']; - $desiredCapabilities = null; - if (isset($_SERVER['BROWSER_BINARY'])) { - $optionsKey = $browser === 'chrome' ? 'goog:chromeOptions' : 'moz:firefoxOptions'; - $desiredCapabilities = array($optionsKey => array('binary' => $_SERVER['BROWSER_BINARY'])); - } - - return new Selenium2Driver($browser, $desiredCapabilities, $seleniumHost); + return new Selenium2Driver($browser, null, $seleniumHost); } public function mapRemoteFilePath($file): string