From 4a931770642c148508baf8134306a4126cd1722e Mon Sep 17 00:00:00 2001 From: Jan Jakes Date: Mon, 28 Jul 2025 13:49:20 +0200 Subject: [PATCH 1/4] Unify test command naming with wordpress-develop test commands --- .github/workflows/wp-tests-phpunit-run.js | 4 ++-- .github/workflows/wp-tests-phpunit.yml | 2 +- composer.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/wp-tests-phpunit-run.js b/.github/workflows/wp-tests-phpunit-run.js index ff4d873c..03ce2697 100644 --- a/.github/workflows/wp-tests-phpunit-run.js +++ b/.github/workflows/wp-tests-phpunit-run.js @@ -1,5 +1,5 @@ /* - * Wrap the "composer run wp-tests-phpunit" command to process tests + * Wrap the "composer run wp-tests-php" command to process tests * that are expected to error and fail at the moment. * * This makes sure that the CI job passes, while explicitly tracking @@ -108,7 +108,7 @@ console.log( 'Expected failures:', expectedFailures ); try { try { execSync( - `composer run wp-test-phpunit -- --log-junit=phpunit-results.xml --verbose`, + `composer run wp-test-php -- --log-junit=phpunit-results.xml --verbose`, { stdio: 'inherit' } ); console.log( '\n⚠️ All tests passed, checking if expected errors/failures occurred...' ); diff --git a/.github/workflows/wp-tests-phpunit.yml b/.github/workflows/wp-tests-phpunit.yml index 0bf5c511..840deb84 100644 --- a/.github/workflows/wp-tests-phpunit.yml +++ b/.github/workflows/wp-tests-phpunit.yml @@ -1,4 +1,4 @@ -name: WordPress Tests +name: WordPress PHPUnit Tests on: push: diff --git a/composer.json b/composer.json index 1d27a626..70c6aaea 100644 --- a/composer.json +++ b/composer.json @@ -49,7 +49,7 @@ "npm --prefix wordpress run env:start", "npm --prefix wordpress run env:install" ], - "wp-test-phpunit": [ + "wp-test-php": [ "rm -rf wordpress/src/wp-content/database && npm --prefix wordpress run test:php --" ], "wp-test-clean": [ From 5502d1e0adb5f9dce67a02ffbb718d63684d25db Mon Sep 17 00:00:00 2001 From: Jan Jakes Date: Mon, 28 Jul 2025 13:53:50 +0200 Subject: [PATCH 2/4] Run WordPress E2E tests with SQLite --- .github/workflows/wp-tests-end-to-end.yml | 41 +++++++++++++++++++++++ composer.json | 7 +++- wp-setup.sh | 1 + 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/wp-tests-end-to-end.yml diff --git a/.github/workflows/wp-tests-end-to-end.yml b/.github/workflows/wp-tests-end-to-end.yml new file mode 100644 index 00000000..4bf0f5cd --- /dev/null +++ b/.github/workflows/wp-tests-end-to-end.yml @@ -0,0 +1,41 @@ +name: WordPress End-to-end Tests + +on: + push: + branches: + - main + pull_request: + +jobs: + test: + name: WordPress End-to-end Tests + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Set UID and GID for PHP in WordPress images + run: | + echo "PHP_FPM_UID=$(id -u)" >> $GITHUB_ENV + echo "PHP_FPM_GID=$(id -g)" >> $GITHUB_ENV + + - name: Install Playwright browsers + run: npx playwright install --with-deps + + - name: Setup WordPress test environment + run: composer run wp-setup + + - name: Start WordPress test environment + run: composer run wp-test-start + + - name: Run WordPress end-to-end tests + run: composer run wp-test-e2e + + - name: Stop Docker containers + if: always() + run: composer run wp-test-clean diff --git a/composer.json b/composer.json index 70c6aaea..a68f247a 100644 --- a/composer.json +++ b/composer.json @@ -47,11 +47,16 @@ ], "wp-test-start": [ "npm --prefix wordpress run env:start", - "npm --prefix wordpress run env:install" + "npm --prefix wordpress run env:install", + "npm --prefix wordpress run env:cli -- plugin install gutenberg", + "npm --prefix wordpress run env:cli -- plugin install query-monitor" ], "wp-test-php": [ "rm -rf wordpress/src/wp-content/database && npm --prefix wordpress run test:php --" ], + "wp-test-e2e": [ + "npm --prefix wordpress run test:e2e --" + ], "wp-test-clean": [ "npm --prefix wordpress run env:clean" ] diff --git a/wp-setup.sh b/wp-setup.sh index b3e00de7..44b8c016 100755 --- a/wp-setup.sh +++ b/wp-setup.sh @@ -65,3 +65,4 @@ sed -i.bak "s#class WpdbExposedMethodsForTesting extends wpdb {#class WpdbExpose # 6. Install dependencies. echo "Installing dependencies..." npm --prefix "$WP_DIR" install +npm --prefix "$WP_DIR" run build:dev From 8f7f203f53a9e104808014d2c2347a166067e0cc Mon Sep 17 00:00:00 2001 From: Jan Jakes Date: Wed, 6 Aug 2025 15:18:55 +0200 Subject: [PATCH 3/4] Automatically set up test environment, improve config --- .github/workflows/wp-tests-end-to-end.yml | 6 ------ .github/workflows/wp-tests-phpunit.yml | 6 ------ composer.json | 15 ++++++++++++--- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/.github/workflows/wp-tests-end-to-end.yml b/.github/workflows/wp-tests-end-to-end.yml index 4bf0f5cd..2b32a5a0 100644 --- a/.github/workflows/wp-tests-end-to-end.yml +++ b/.github/workflows/wp-tests-end-to-end.yml @@ -27,12 +27,6 @@ jobs: - name: Install Playwright browsers run: npx playwright install --with-deps - - name: Setup WordPress test environment - run: composer run wp-setup - - - name: Start WordPress test environment - run: composer run wp-test-start - - name: Run WordPress end-to-end tests run: composer run wp-test-e2e diff --git a/.github/workflows/wp-tests-phpunit.yml b/.github/workflows/wp-tests-phpunit.yml index 840deb84..d2746fdc 100644 --- a/.github/workflows/wp-tests-phpunit.yml +++ b/.github/workflows/wp-tests-phpunit.yml @@ -24,12 +24,6 @@ jobs: echo "PHP_FPM_UID=$(id -u)" >> $GITHUB_ENV echo "PHP_FPM_GID=$(id -g)" >> $GITHUB_ENV - - name: Setup WordPress test environment - run: composer run wp-setup - - - name: Start WordPress test environment - run: composer run wp-test-start - - name: Run WordPress PHPUnit tests run: node .github/workflows/wp-tests-phpunit-run.js diff --git a/composer.json b/composer.json index a68f247a..9b4c8a15 100644 --- a/composer.json +++ b/composer.json @@ -51,14 +51,23 @@ "npm --prefix wordpress run env:cli -- plugin install gutenberg", "npm --prefix wordpress run env:cli -- plugin install query-monitor" ], + "wp-test-ensure-env": [ + "if [ ! -f wordpress/src/wp-load.php ]; then composer run wp-setup; fi", + "@putenv COMPOSE_IGNORE_ORPHANS=true", + "cd wordpress && if [ -z \"$(node tools/local-env/scripts/docker.js ps -q)\" ]; then cd ..; composer run wp-test-start; fi" + ], "wp-test-php": [ - "rm -rf wordpress/src/wp-content/database && npm --prefix wordpress run test:php --" + "@wp-test-ensure-env @no_additional_args", + "rm -rf wordpress/src/wp-content/database/.ht.sqlite @no_additional_args", + "npm --prefix wordpress run test:php -- @additional_args" ], "wp-test-e2e": [ - "npm --prefix wordpress run test:e2e --" + "@wp-test-ensure-env @no_additional_args", + "npm --prefix wordpress run test:e2e -- @additional_args" ], "wp-test-clean": [ - "npm --prefix wordpress run env:clean" + "npm --prefix wordpress run env:clean", + "rm -rf wordpress/src/wp-content/database/.ht.sqlite" ] } } From c37f76d6a5f20019eb454fd4807ff1756ac86b11 Mon Sep 17 00:00:00 2001 From: Jan Jakes Date: Thu, 7 Aug 2025 10:07:31 +0200 Subject: [PATCH 4/4] Setup SQLite driver E2E tests and add an E2E test for Query Monitor --- .github/workflows/end-to-end-tests.yml | 35 +++++++++++++++ composer.json | 7 +++ tests/e2e/.gitignore | 3 ++ tests/e2e/playwright.config.js | 27 +++++++++++ tests/e2e/specs/query-monitor-plugin.test.js | 47 ++++++++++++++++++++ 5 files changed, 119 insertions(+) create mode 100644 .github/workflows/end-to-end-tests.yml create mode 100644 tests/e2e/.gitignore create mode 100644 tests/e2e/playwright.config.js create mode 100644 tests/e2e/specs/query-monitor-plugin.test.js diff --git a/.github/workflows/end-to-end-tests.yml b/.github/workflows/end-to-end-tests.yml new file mode 100644 index 00000000..64cf4b12 --- /dev/null +++ b/.github/workflows/end-to-end-tests.yml @@ -0,0 +1,35 @@ +name: End-to-end Tests + +on: + push: + branches: + - main + pull_request: + +jobs: + test: + name: End-to-end Tests + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Set UID and GID for PHP in WordPress images + run: | + echo "PHP_FPM_UID=$(id -u)" >> $GITHUB_ENV + echo "PHP_FPM_GID=$(id -g)" >> $GITHUB_ENV + + - name: Install Playwright browsers + run: npx playwright install --with-deps + + - name: Run end-to-end tests + run: composer run test-e2e + + - name: Stop Docker containers + if: always() + run: composer run wp-test-clean diff --git a/composer.json b/composer.json index 9b4c8a15..4ac7fc76 100644 --- a/composer.json +++ b/composer.json @@ -39,6 +39,13 @@ "test": [ "phpunit" ], + "test-e2e": [ + "@wp-test-ensure-env @no_additional_args", + "rm -f tests/e2e/package.json tests/e2e/node_modules @no_additional_args", + "ln -s ../../wordpress/package.json tests/e2e/package.json @no_additional_args", + "ln -s ../../wordpress/node_modules tests/e2e/node_modules @no_additional_args", + "npm --prefix tests/e2e run test:e2e -- --config . @additional_args" + ], "wp-setup": [ "./wp-setup.sh" ], diff --git a/tests/e2e/.gitignore b/tests/e2e/.gitignore new file mode 100644 index 00000000..a5dd015f --- /dev/null +++ b/tests/e2e/.gitignore @@ -0,0 +1,3 @@ +/artifacts +/node_modules +/package.json diff --git a/tests/e2e/playwright.config.js b/tests/e2e/playwright.config.js new file mode 100644 index 00000000..531b6a1d --- /dev/null +++ b/tests/e2e/playwright.config.js @@ -0,0 +1,27 @@ +/** + * External dependencies + */ +import path from 'node:path'; +import { defineConfig } from '@playwright/test'; + +/** + * WordPress dependencies + */ +const baseConfig = require( '@wordpress/scripts/config/playwright.config' ); + +process.env.WP_ARTIFACTS_PATH ??= path.join( process.cwd(), 'artifacts' ); +process.env.STORAGE_STATE_PATH ??= path.join( + process.env.WP_ARTIFACTS_PATH, + 'storage-states/admin.json' +); + +const config = defineConfig( { + ...baseConfig, + globalSetup: require.resolve( '../../wordpress/tests/e2e/config/global-setup.js' ), + webServer: { + ...baseConfig.webServer, + command: 'npm run env:start', + }, +} ); + +export default config; diff --git a/tests/e2e/specs/query-monitor-plugin.test.js b/tests/e2e/specs/query-monitor-plugin.test.js new file mode 100644 index 00000000..64b13213 --- /dev/null +++ b/tests/e2e/specs/query-monitor-plugin.test.js @@ -0,0 +1,47 @@ +/** + * WordPress dependencies + */ +import { test, expect } from '@wordpress/e2e-test-utils-playwright'; + +test.describe( 'Query Monitor plugin', () => { + async function deactivateQueryMonitor( requestUtils ) { + await requestUtils.deactivatePlugin( 'query-monitor' ); + const plugin = await requestUtils.rest( { + path: 'wp/v2/plugins/query-monitor/query-monitor', + } ); + expect( plugin.status ).toBe( 'inactive' ); + } + + test.beforeEach( async ( { requestUtils }) => { + await deactivateQueryMonitor( requestUtils ); + } ); + + test.afterEach( async ( { requestUtils }) => { + await deactivateQueryMonitor( requestUtils ); + } ); + + test( 'should activate', async ( { admin, page } ) => { + // Activate the Query Monitor plugin on the plugins page. + await admin.visitAdminPage( '/plugins.php' ); + await page.getByLabel( 'Activate Query Monitor', { exact: true } ).click(); + await page.getByText( 'Plugin activated.', { exact: true } ).waitFor(); + + // Click on the Query Monitor menu item in the WordPress admin bar. + await page.locator('a[role="menuitem"][href="#qm-overview"][aria-expanded="false"]').click(); + + // Wait for the Query Monitor panel to open. + await page.locator( '#query-monitor-main' ).waitFor(); + await page.getByRole( 'heading', { name: 'Query Monitor', exact: true } ).waitFor(); + + // Click on the Database Queries tab. + await page.getByRole( 'tab', { name: 'Database Queries' } ).click(); + + // Verify the first logged query. + const sqlCell = page.locator( '.qm-row-sql' ).first(); + await expect( sqlCell ).toContainText( 'SELECT option_name, option_value' ); + + // Check that the query is logged with SQLite information. + await sqlCell.getByLabel( 'Toggle SQLite queries' ).click(); + expect( page.locator('.qm-sqlite-query', { hasText: 'SELECT `option_name` , `option_value` FROM `wp_options`' }).first() ).toBeVisible(); + } ); +} );