diff --git a/.github/actions/setup-webdriverio/action.yml b/.github/actions/setup-webdriverio/action.yml new file mode 100644 index 000000000000..c89cb47731f2 --- /dev/null +++ b/.github/actions/setup-webdriverio/action.yml @@ -0,0 +1,65 @@ +name: Setup WebDriverIO Browsers +description: Setup Chrome, ChromeDriver, and optional Firefox for WebDriverIO tests + +inputs: + chrome-version: + description: Chrome for Testing version to install, or false to skip + # Pin to Chrome 148 while Chrome for Testing 149 Linux downloads/install are broken. + default: '148' + firefox-version: + description: Firefox version to install, or false to skip + default: latest + +runs: + using: composite + steps: + - uses: browser-actions/setup-chrome@4f8e94349a351df0f048634f25fec36c3c91eded # v2.1.1 + if: inputs.chrome-version != 'false' + id: setup-chrome + with: + chrome-version: ${{ inputs.chrome-version }} + install-chromedriver: true + + - name: Export Chrome binaries + if: inputs.chrome-version != 'false' + shell: bash + env: + CHROME_PATH: ${{ steps.setup-chrome.outputs.chrome-path }} + CHROMEDRIVER_PATH_VALUE: ${{ steps.setup-chrome.outputs.chromedriver-path }} + run: | # zizmor: ignore[github-env] values come from pinned browser-actions/setup-chrome outputs. + echo "CHROME_BIN=$CHROME_PATH" >> "$GITHUB_ENV" + echo "CHROMEDRIVER_PATH=$CHROMEDRIVER_PATH_VALUE" >> "$GITHUB_ENV" + + - name: Allow setup-chrome sandbox + if: inputs.chrome-version != 'false' && runner.os == 'Linux' + shell: bash + env: + CHROME_PATH: ${{ steps.setup-chrome.outputs.chrome-path }} + run: | + # Chrome for Testing is not covered by Ubuntu's AppArmor sandbox policy on CI. + # https://pptr.dev/troubleshooting#issues-with-apparmor-on-ubuntu + # https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md + # https://github.com/browser-actions/setup-chrome/issues/639 + cat <, + include + + profile chrome-for-testing "$CHROME_PATH" flags=(unconfined) { + userns, + include if exists + } + EOF + sudo apparmor_parser -r /etc/apparmor.d/chrome-for-testing + + - uses: browser-actions/setup-firefox@fcf821c621167805dd63a29662bd7cb5676c81a8 # v1.7.1 + if: inputs.firefox-version != 'false' + id: setup-firefox + with: + firefox-version: ${{ inputs.firefox-version }} + + - name: Export Firefox binary + if: inputs.firefox-version != 'false' + shell: bash + env: + FIREFOX_PATH: ${{ steps.setup-firefox.outputs.firefox-path }} + run: echo "FIREFOX_BIN=$FIREFOX_PATH" >> "$GITHUB_ENV" # zizmor: ignore[github-env] value comes from pinned browser-actions/setup-firefox output. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 670e7821a264..34f67ec92f5a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -109,7 +109,10 @@ jobs: with: node-version: ${{ matrix.node_version }} - - uses: browser-actions/setup-chrome@4f8e94349a351df0f048634f25fec36c3c91eded # v2.1.1 + - uses: ./.github/actions/setup-webdriverio + id: setup-webdriverio + with: + firefox-version: false - name: Install run: pnpm i @@ -176,7 +179,10 @@ jobs: with: node-version: ${{ matrix.node_version }} - - uses: browser-actions/setup-chrome@4f8e94349a351df0f048634f25fec36c3c91eded # v2.1.1 + - uses: ./.github/actions/setup-webdriverio + id: setup-webdriverio + with: + firefox-version: false - name: Install run: pnpm i @@ -214,8 +220,8 @@ jobs: with: node-version: ${{ matrix.node_version }} - - uses: browser-actions/setup-chrome@4f8e94349a351df0f048634f25fec36c3c91eded # v2.1.1 - - uses: browser-actions/setup-firefox@fcf821c621167805dd63a29662bd7cb5676c81a8 # v1.7.1 + - uses: ./.github/actions/setup-webdriverio + id: setup-webdriverio - name: Install run: pnpm i @@ -249,7 +255,10 @@ jobs: with: node-version: 24 - - uses: browser-actions/setup-chrome@4f8e94349a351df0f048634f25fec36c3c91eded # v2.1.1 + - uses: ./.github/actions/setup-webdriverio + id: setup-webdriverio + with: + firefox-version: false - name: Install run: | @@ -312,6 +321,7 @@ jobs: - name: Merge reports continue-on-error: true run: | + set +e pnpm --filter=./packages/ui --no-bail test:ui --merge-reports cp ./packages/ui/.vitest/html/index.html ./packages/ui/.vitest/html/test-ui.html pnpm --filter=./test/unit --filter=./test/e2e --no-bail --sequential test --merge-reports diff --git a/packages/ui/vitest.config.ts b/packages/ui/vitest.config.ts index cb311ff7977a..deb1191a22f9 100644 --- a/packages/ui/vitest.config.ts +++ b/packages/ui/vitest.config.ts @@ -49,7 +49,20 @@ const testConfig = defineConfig({ providerName === 'preview' ? preview() : providerName === 'webdriverio' - ? webdriverio() + ? webdriverio({ + ...(process.env.CHROMEDRIVER_PATH && process.env.CHROME_BIN + ? { + 'wdio:chromedriverOptions': { + binary: process.env.CHROMEDRIVER_PATH, + }, + 'capabilities': { + 'goog:chromeOptions': { + binary: process.env.CHROME_BIN, + }, + }, + } + : {}), + }) : playwright({ actionTimeout: 5000, }), diff --git a/test/browser/settings.ts b/test/browser/settings.ts index cdb4bc3df8a4..6857fedaa0d5 100644 --- a/test/browser/settings.ts +++ b/test/browser/settings.ts @@ -18,7 +18,41 @@ export const providers = { } : options), preview, - webdriverio, + webdriverio: (options?: Parameters[0]) => { + const capabilities = options?.capabilities || {} + + return webdriverio({ + ...options, + capabilities: { + ...capabilities, + // Explicit browser/driver binaries keep WebDriverIO from auto-downloading mismatched versions. + // https://webdriver.io/docs/driverbinaries + // https://webdriver.io/docs/capabilities#webdriverio-capabilities-to-manage-browser-driver-options + ...(process.env.CHROMEDRIVER_PATH && process.env.CHROME_BIN + ? { + 'wdio:chromedriverOptions': { + ...(capabilities as any)['wdio:chromedriverOptions'], + binary: process.env.CHROMEDRIVER_PATH, + }, + // https://developer.chrome.com/docs/chromedriver/capabilities#chromeoptions-object + 'goog:chromeOptions': { + ...(capabilities as any)['goog:chromeOptions'], + binary: process.env.CHROME_BIN, + }, + } + : {}), + ...(process.env.FIREFOX_BIN + ? { + // https://developer.mozilla.org/en-US/docs/Web/WebDriver/Reference/Capabilities/firefoxOptions + 'moz:firefoxOptions': { + ...(capabilities as any)['moz:firefoxOptions'], + binary: process.env.FIREFOX_BIN, + }, + } + : {}), + }, + }) + }, } export const provider = providers[providerName]() diff --git a/test/browser/specs/failure-screenshot.test.ts b/test/browser/specs/failure-screenshot.test.ts index 1024828fe714..08f743c82151 100644 --- a/test/browser/specs/failure-screenshot.test.ts +++ b/test/browser/specs/failure-screenshot.test.ts @@ -2,7 +2,6 @@ import type { TestFsStructure } from '../../test-utils' import { describe, expect, test } from 'vitest' import { runInlineTests } from '../../test-utils' import utilsContent from '../fixtures/expect-dom/utils?raw' -import { instances, provider } from '../settings' const testFilename = 'basic.test.ts' @@ -12,16 +11,17 @@ async function runBrowserTests( return runInlineTests({ ...structure, 'vitest.config.js': ` - import { ${provider.name} } from '@vitest/browser-${provider.name}' + import { instances, provider } from '../settings.ts' + export default { test: { browser: { enabled: true, screenshotFailures: true, - provider: ${provider.name}(), + provider, ui: false, headless: true, - instances: ${JSON.stringify(instances.slice(0, 1) /* logic not bound to browser instance */)}, + instances: instances.slice(0, 1), // logic not bound to browser instance }, reporters: ['verbose'], update: 'new', diff --git a/test/e2e/test/mocking.test.ts b/test/e2e/test/mocking.test.ts index 3cbb181eda13..c3a14c8d2c5e 100644 --- a/test/e2e/test/mocking.test.ts +++ b/test/e2e/test/mocking.test.ts @@ -170,7 +170,20 @@ function modeToConfig(mode: string): RunVitestConfig { return { browser: { enabled: true, - provider: webdriverio(), + provider: webdriverio({ + ...(process.env.CHROMEDRIVER_PATH && process.env.CHROME_BIN + ? { + 'wdio:chromedriverOptions': { + binary: process.env.CHROMEDRIVER_PATH, + }, + 'capabilities': { + 'goog:chromeOptions': { + binary: process.env.CHROME_BIN, + }, + }, + } + : {}), + }), instances: [{ browser: 'chrome' }], headless: true, },