diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 9c1090f02c104..32d6739518b00 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() ) { 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..1b5522358ebb9 --- /dev/null +++ b/tests/e2e/specs/fatal-error-handler.test.js @@ -0,0 +1,46 @@ +/** + * 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, 'fatal-error.php' ); + + test.beforeAll( async () => { + const muPluginCode = ` { + unlinkSync( muPluginFile ); + } ); + + test( 'should display fatal error notice', async ( { admin, page } ) => { + 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/ ), + 'should display WordPress fatal error handler message' + ).toBeVisible(); + } ); +} ); diff --git a/tests/e2e/specs/install.test.js b/tests/e2e/specs/install.test.js new file mode 100644 index 0000000000000..27bc56575ee32 --- /dev/null +++ b/tests/e2e/specs/install.test.js @@ -0,0 +1,85 @@ +/** + * External dependencies + */ +import { writeFileSync, readFileSync } from 'node:fs'; +import { join } from 'node:path'; + +/** + * WordPress dependencies + */ +import { test, expect } from '@wordpress/e2e-test-utils-playwright'; + +let wpConfigOriginal; + +test.describe( 'WordPress installation process', () => { + const wpConfig = join( + process.cwd(), + 'wp-config.php', + ); + + + 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.getByRole( 'button', { name: 'Continue' } ).click(); + + // Second page: enter site name, username & password. + + 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', { 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.getByRole( 'button', { name: 'Install WordPress' } ).click(); + + // Installation finished, can now log in. + + await expect( page.getByRole( 'heading', { name: 'Success!' } ) ).toBeVisible(); + + await page.getByRole( 'link', { name: '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', { exact: true } ).fill( 'password' ); + + await page.getByRole( 'button', { name: 'Log In' } ).click(); + + await expect( + page.getByRole( 'heading', { name: 'Welcome to WordPress', level: 2 }) + ).toBeVisible(); + } ); +} ); diff --git a/tests/e2e/specs/maintenance-mode.test.js b/tests/e2e/specs/maintenance-mode.test.js new file mode 100644 index 0000000000000..df9d409a07895 --- /dev/null +++ b/tests/e2e/specs/maintenance-mode.test.js @@ -0,0 +1,33 @@ +/** + * External dependencies + */ +import { 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', + ); + const maintenanceLockFile = join( documentRoot, '.maintenance' ); + + test.beforeAll( async () => { + writeFileSync( maintenanceLockFile, '' ); // Year 2286. + } ); + + 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(); + } ); +} );