From b5d9f536387102d2186e47a15575fa64e0398761 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Fri, 24 May 2024 16:38:39 +0200 Subject: [PATCH 01/13] Add test for maintenance mode --- tests/e2e/specs/maintenance-mode.test.js | 34 ++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/e2e/specs/maintenance-mode.test.js diff --git a/tests/e2e/specs/maintenance-mode.test.js b/tests/e2e/specs/maintenance-mode.test.js new file mode 100644 index 0000000000000..649953ece8375 --- /dev/null +++ b/tests/e2e/specs/maintenance-mode.test.js @@ -0,0 +1,34 @@ +/** + * External dependencies + */ +import { existsSync, mkdirSync, writeFileSync, unlinkSync } from 'node:fs'; +import { join } from 'node:path'; + +/** + * WordPress dependencies + */ +import { test, expect } from '@wordpress/e2e-test-utils-playwright'; + +test.describe( 'Maintenance mode', () => { + const documentRoot = join( + process.cwd(), + process.env.LOCAL_DIR ?? 'src', + 'wp-content/mu-plugins' + ); + const maintenanceLockFile = join( documentRoot, '.maintenance' ); + + test.beforeAll( async () => { + writeFileSync( maintenanceLockFile, '' ); + } ); + + test.afterAll( async () => { + unlinkSync( maintenanceLockFile ); + } ); + + test( 'should display maintenance mode page', async ( { page } ) => { + await page.goto( '/' ); + await expect( + page.getByText( /Briefly unavailable for scheduled maintenance\. Check back in a minute\./ ) + ).toBeVisible(); + } ); +} ); From eb4fb8cec2c978d40f64e9052973935a2cb57d4e Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Fri, 24 May 2024 16:52:44 +0200 Subject: [PATCH 02/13] Add e2e test for fatal error handler --- tests/e2e/specs/fatal-error-handler.test.js | 39 +++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/e2e/specs/fatal-error-handler.test.js diff --git a/tests/e2e/specs/fatal-error-handler.test.js b/tests/e2e/specs/fatal-error-handler.test.js new file mode 100644 index 0000000000000..965456ba2c41d --- /dev/null +++ b/tests/e2e/specs/fatal-error-handler.test.js @@ -0,0 +1,39 @@ +/** + * External dependencies + */ +import { existsSync, mkdirSync, writeFileSync, unlinkSync } from 'node:fs'; +import { join } from 'node:path'; + +/** + * WordPress dependencies + */ +import { test, expect } from '@wordpress/e2e-test-utils-playwright'; + +test.describe( 'Fatal error handler', () => { + const muPlugins = join( + process.cwd(), + process.env.LOCAL_DIR ?? 'src', + 'wp-content/mu-plugins' + ); + const muPluginFile = join( muPlugins, 'login-test.php' ); + + test.beforeAll( async () => { + const muPluginCode = ` { + unlinkSync( muPluginFile ); + } ); + + test( 'should display fatal error notice', async ( { page } ) => { + await page.goto( '/' ); + await expect( + page.getByText( /There has been a critical error on this website\./ ) + ).toBeVisible(); + } ); +} ); From 4188e24f02ed5ce5ca2088303932ac1d356fe572 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Fri, 24 May 2024 16:52:51 +0200 Subject: [PATCH 03/13] Prevent php warnings in fatal error handler --- src/wp-includes/functions.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 2b2e3379c71bd..1a4c350993665 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -3862,6 +3862,9 @@ function _default_wp_die_handler( $message, $title = '', $args = array() ) { From 99021b14e6eae2198ea0af97d4ce7c87e9562f5b Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Fri, 24 May 2024 17:12:07 +0200 Subject: [PATCH 04/13] Rename file --- tests/e2e/specs/fatal-error-handler.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/specs/fatal-error-handler.test.js b/tests/e2e/specs/fatal-error-handler.test.js index 965456ba2c41d..c417579ae78d2 100644 --- a/tests/e2e/specs/fatal-error-handler.test.js +++ b/tests/e2e/specs/fatal-error-handler.test.js @@ -15,7 +15,7 @@ test.describe( 'Fatal error handler', () => { process.env.LOCAL_DIR ?? 'src', 'wp-content/mu-plugins' ); - const muPluginFile = join( muPlugins, 'login-test.php' ); + const muPluginFile = join( muPlugins, 'fatal-error.php' ); test.beforeAll( async () => { const muPluginCode = ` Date: Fri, 24 May 2024 17:12:12 +0200 Subject: [PATCH 05/13] Update timestamp --- tests/e2e/specs/maintenance-mode.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/e2e/specs/maintenance-mode.test.js b/tests/e2e/specs/maintenance-mode.test.js index 649953ece8375..80ff7f8e49fdc 100644 --- a/tests/e2e/specs/maintenance-mode.test.js +++ b/tests/e2e/specs/maintenance-mode.test.js @@ -13,12 +13,11 @@ test.describe( 'Maintenance mode', () => { const documentRoot = join( process.cwd(), process.env.LOCAL_DIR ?? 'src', - 'wp-content/mu-plugins' ); const maintenanceLockFile = join( documentRoot, '.maintenance' ); test.beforeAll( async () => { - writeFileSync( maintenanceLockFile, '' ); + writeFileSync( maintenanceLockFile, '' ); // Year 2286. } ); test.afterAll( async () => { From ea0c9db2263159c318aff393952b4f00a4e0ba2e Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 17 Jun 2024 11:31:44 +0200 Subject: [PATCH 06/13] Remove unused import --- tests/e2e/specs/maintenance-mode.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/specs/maintenance-mode.test.js b/tests/e2e/specs/maintenance-mode.test.js index 80ff7f8e49fdc..df9d409a07895 100644 --- a/tests/e2e/specs/maintenance-mode.test.js +++ b/tests/e2e/specs/maintenance-mode.test.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { existsSync, mkdirSync, writeFileSync, unlinkSync } from 'node:fs'; +import { writeFileSync, unlinkSync } from 'node:fs'; import { join } from 'node:path'; /** From 49604e9b5d8c1703ee4d1f25880d42c700557978 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 17 Jun 2024 11:32:16 +0200 Subject: [PATCH 07/13] Add install test --- tests/e2e/specs/install-screen.test.js | 94 ++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 tests/e2e/specs/install-screen.test.js diff --git a/tests/e2e/specs/install-screen.test.js b/tests/e2e/specs/install-screen.test.js new file mode 100644 index 0000000000000..10d91851a3d3e --- /dev/null +++ b/tests/e2e/specs/install-screen.test.js @@ -0,0 +1,94 @@ +/** + * External dependencies + */ +import { writeFileSync, readFileSync } from 'node:fs'; +import { join } from 'node:path'; + +/** + * WordPress dependencies + */ +import { test, expect } from '@wordpress/e2e-test-utils-playwright'; + +test.describe( 'WordPress installation process', () => { + const wpConfig = join( + process.cwd(), + 'wp-config.php', + ); + + let wpConfigOriginal; + + test.beforeEach( async () => { + wpConfigOriginal = readFileSync( wpConfig, 'utf-8' ); + // Changing the table prefix tricks WP into new install mode. + writeFileSync( + wpConfig, + wpConfigOriginal.replace( `$table_prefix = 'wp_';`, `$table_prefix = 'wp_e2e_';` ) + ); + } ); + + test.afterEach( async () => { + writeFileSync( wpConfig, wpConfigOriginal ); + } ); + + test( 'should install WordPress with pre-existing database credentials', async ( { page } ) => { + await page.goto( '/' ); + + await expect( + page, + 'should redirect to the installation page' + ).toHaveURL( /wp-admin\/install\.php$/ ); + + await expect( + page.getByText( /WordPress database error/ ), + 'should not have any database errors' + ).not.toBeVisible(); + + // First page: language selector. Keep default English (US). + await page.getByLabel( 'Continue' ).click(); + + // Second page: enter site name, username & password. + + await expect( page.getByLabel( 'Welcome' ) ).toBeVisible(); + + await expect( + page.getByText( /WordPress database error/ ), + 'should not have any database errors' + ).not.toBeVisible(); + + // This information matches tools/local-env/scripts/install.js. + + await page.getByLabel( 'Site Title' ).fill( 'WordPress Develop' ); + await page.getByLabel( 'Username' ).fill( 'admin' ); + await page.getByLabel( 'Password' ).fill( '' ); + await page.getByLabel( 'Password' ).fill( 'password' ); + await page.getByLabel( /Confirm use of weak password/ ).check() + await page.getByLabel( 'Your Email' ).fill( 'test@test.com' ); + + await page.getByLabel( 'Install WordPress' ).click(); + + // Installation finished, can now log in. + + await expect( page.getByLabel( 'Success!' ) ).toBeVisible(); + + await expect( + page.getByText( /WordPress database error/ ), + 'should not have any database errors' + ).not.toBeVisible(); + + await page.getByLabel( 'Log In' ).click(); + + await expect( + page, + 'should redirect to the login page' + ).toHaveURL( /wp-login\.php$/ ); + + await page.getByLabel( 'Username or Email Address' ).fill( 'admin' ); + await page.getByLabel( 'Password' ).fill( 'password' ); + + await page.getByLabel( 'Log In' ).click(); + + await expect( + page.getByRole('heading', { name: 'Welcome to WordPress', level: 2 }) + ).toBeVisible(); + } ); +} ); From e356abbae2686bd8bc00c1261a45f9fdb6a4f791 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 17 Jun 2024 11:44:49 +0200 Subject: [PATCH 08/13] Visit admin page --- tests/e2e/specs/fatal-error-handler.test.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/e2e/specs/fatal-error-handler.test.js b/tests/e2e/specs/fatal-error-handler.test.js index c417579ae78d2..a81f5819b2190 100644 --- a/tests/e2e/specs/fatal-error-handler.test.js +++ b/tests/e2e/specs/fatal-error-handler.test.js @@ -31,9 +31,16 @@ test.describe( 'Fatal error handler', () => { } ); test( 'should display fatal error notice', async ( { page } ) => { - await page.goto( '/' ); + await admin.visitAdminPage( '/' ); + + await expect( + page.getByText( /^Fatal error:/ ), + 'should display PHP error message' + ).toBeVisible(); + await expect( - page.getByText( /There has been a critical error on this website\./ ) + page.getByText( /There has been a critical error on this website\./ ), + 'should display WordPress fatal error handler message' ).toBeVisible(); } ); } ); From 0da898deaa69b85ea6d56a3fbd9373f7dca4a7ef Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 17 Jun 2024 13:27:01 +0200 Subject: [PATCH 09/13] Use `admin` correctly --- tests/e2e/specs/fatal-error-handler.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/specs/fatal-error-handler.test.js b/tests/e2e/specs/fatal-error-handler.test.js index a81f5819b2190..cbb3a704211fc 100644 --- a/tests/e2e/specs/fatal-error-handler.test.js +++ b/tests/e2e/specs/fatal-error-handler.test.js @@ -30,7 +30,7 @@ test.describe( 'Fatal error handler', () => { unlinkSync( muPluginFile ); } ); - test( 'should display fatal error notice', async ( { page } ) => { + test( 'should display fatal error notice', async ( { admin, page } ) => { await admin.visitAdminPage( '/' ); await expect( From 32e1701931624ebbb898a3d4cfe0ef9c8e5e7375 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 17 Jun 2024 13:27:39 +0200 Subject: [PATCH 10/13] Disable check for now --- tests/e2e/specs/install-screen.test.js | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/tests/e2e/specs/install-screen.test.js b/tests/e2e/specs/install-screen.test.js index 10d91851a3d3e..7854aa8d6b35b 100644 --- a/tests/e2e/specs/install-screen.test.js +++ b/tests/e2e/specs/install-screen.test.js @@ -38,10 +38,11 @@ test.describe( 'WordPress installation process', () => { 'should redirect to the installation page' ).toHaveURL( /wp-admin\/install\.php$/ ); - await expect( - page.getByText( /WordPress database error/ ), - 'should not have any database errors' - ).not.toBeVisible(); + // Blocked by https://core.trac.wordpress.org/ticket/61312. + // await expect( + // page.getByText( /WordPress database error/ ), + // 'should not have any database errors' + // ).not.toBeVisible(); // First page: language selector. Keep default English (US). await page.getByLabel( 'Continue' ).click(); @@ -50,11 +51,6 @@ test.describe( 'WordPress installation process', () => { await expect( page.getByLabel( 'Welcome' ) ).toBeVisible(); - await expect( - page.getByText( /WordPress database error/ ), - 'should not have any database errors' - ).not.toBeVisible(); - // This information matches tools/local-env/scripts/install.js. await page.getByLabel( 'Site Title' ).fill( 'WordPress Develop' ); @@ -70,11 +66,6 @@ test.describe( 'WordPress installation process', () => { await expect( page.getByLabel( 'Success!' ) ).toBeVisible(); - await expect( - page.getByText( /WordPress database error/ ), - 'should not have any database errors' - ).not.toBeVisible(); - await page.getByLabel( 'Log In' ).click(); await expect( From 7570e9ca2c65eb677e6c54f753a48a18233f8dfa Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 17 Jun 2024 14:11:20 +0200 Subject: [PATCH 11/13] Improve regex --- tests/e2e/specs/fatal-error-handler.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/e2e/specs/fatal-error-handler.test.js b/tests/e2e/specs/fatal-error-handler.test.js index cbb3a704211fc..1b5522358ebb9 100644 --- a/tests/e2e/specs/fatal-error-handler.test.js +++ b/tests/e2e/specs/fatal-error-handler.test.js @@ -34,12 +34,12 @@ test.describe( 'Fatal error handler', () => { await admin.visitAdminPage( '/' ); await expect( - page.getByText( /^Fatal error:/ ), + page.getByText( /Fatal error:/ ), 'should display PHP error message' ).toBeVisible(); await expect( - page.getByText( /There has been a critical error on this website\./ ), + page.getByText( /There has been a critical error on this website/ ), 'should display WordPress fatal error handler message' ).toBeVisible(); } ); From 76e2c0de1b69ba8a478739c84a2038caf5a4446c Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 17 Jun 2024 14:27:55 +0200 Subject: [PATCH 12/13] Improve install test --- ...install-screen.test.js => install.test.js} | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) rename tests/e2e/specs/{install-screen.test.js => install.test.js} (71%) diff --git a/tests/e2e/specs/install-screen.test.js b/tests/e2e/specs/install.test.js similarity index 71% rename from tests/e2e/specs/install-screen.test.js rename to tests/e2e/specs/install.test.js index 7854aa8d6b35b..e585ec908cdf7 100644 --- a/tests/e2e/specs/install-screen.test.js +++ b/tests/e2e/specs/install.test.js @@ -9,13 +9,14 @@ import { join } from 'node:path'; */ import { test, expect } from '@wordpress/e2e-test-utils-playwright'; +let wpConfigOriginal; + test.describe( 'WordPress installation process', () => { const wpConfig = join( process.cwd(), 'wp-config.php', ); - let wpConfigOriginal; test.beforeEach( async () => { wpConfigOriginal = readFileSync( wpConfig, 'utf-8' ); @@ -45,28 +46,28 @@ test.describe( 'WordPress installation process', () => { // ).not.toBeVisible(); // First page: language selector. Keep default English (US). - await page.getByLabel( 'Continue' ).click(); + await page.getByRole( 'button', { name: 'Continue' } ).click(); // Second page: enter site name, username & password. - await expect( page.getByLabel( 'Welcome' ) ).toBeVisible(); + await expect( page.getByRole( 'heading', { name: 'Welcome' } ) ).toBeVisible(); // This information matches tools/local-env/scripts/install.js. await page.getByLabel( 'Site Title' ).fill( 'WordPress Develop' ); await page.getByLabel( 'Username' ).fill( 'admin' ); - await page.getByLabel( 'Password' ).fill( '' ); - await page.getByLabel( 'Password' ).fill( 'password' ); + await page.getByLabel( 'Password', { exact: true } ).fill( '' ); + await page.getByLabel( 'Password', { exact: true } ).fill( 'password' ); await page.getByLabel( /Confirm use of weak password/ ).check() await page.getByLabel( 'Your Email' ).fill( 'test@test.com' ); - await page.getByLabel( 'Install WordPress' ).click(); + await page.getByRole( 'button', { name: 'Install WordPress' } ).click(); // Installation finished, can now log in. - await expect( page.getByLabel( 'Success!' ) ).toBeVisible(); + await expect( page.getByRole( 'heading', { name: 'Success!' } ) ).toBeVisible(); - await page.getByLabel( 'Log In' ).click(); + await page.getByRole( 'link', { name: 'Log In' } ).click(); await expect( page, @@ -74,12 +75,12 @@ test.describe( 'WordPress installation process', () => { ).toHaveURL( /wp-login\.php$/ ); await page.getByLabel( 'Username or Email Address' ).fill( 'admin' ); - await page.getByLabel( 'Password' ).fill( 'password' ); + await page.getByLabel( 'Password', { exact: true } ).fill( 'password' ); - await page.getByLabel( 'Log In' ).click(); + await page.getByRole( 'button', { name: 'Log In' } ).click(); await expect( - page.getByRole('heading', { name: 'Welcome to WordPress', level: 2 }) + page.getByRole( 'heading', { name: 'Welcome to WordPress', level: 2 }) ).toBeVisible(); } ); } ); From 534e6404fd5dce2e3ccbe3c2e564cc999bd20aa0 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 18 Jun 2024 09:22:16 +0200 Subject: [PATCH 13/13] Uncomment db error check --- tests/e2e/specs/install.test.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/e2e/specs/install.test.js b/tests/e2e/specs/install.test.js index e585ec908cdf7..27bc56575ee32 100644 --- a/tests/e2e/specs/install.test.js +++ b/tests/e2e/specs/install.test.js @@ -39,11 +39,10 @@ test.describe( 'WordPress installation process', () => { 'should redirect to the installation page' ).toHaveURL( /wp-admin\/install\.php$/ ); - // Blocked by https://core.trac.wordpress.org/ticket/61312. - // await expect( - // page.getByText( /WordPress database error/ ), - // 'should not have any database errors' - // ).not.toBeVisible(); + await expect( + page.getByText( /WordPress database error/ ), + 'should not have any database errors' + ).not.toBeVisible(); // First page: language selector. Keep default English (US). await page.getByRole( 'button', { name: 'Continue' } ).click();