From 7000b1c24a3daff8d74005b7a63a9a7387e3a791 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Tue, 6 Jan 2026 11:13:47 +1100 Subject: [PATCH 1/5] Add visual regression test to E2E test suite. --- .github/workflows/reusable-end-to-end-tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/reusable-end-to-end-tests.yml b/.github/workflows/reusable-end-to-end-tests.yml index 620949d7a6717..dfbaf3e23b633 100644 --- a/.github/workflows/reusable-end-to-end-tests.yml +++ b/.github/workflows/reusable-end-to-end-tests.yml @@ -144,6 +144,9 @@ jobs: - name: Run E2E tests run: npm run test:e2e + - name: Run visual regression tests + run: npm run test:visual + - name: Archive debug artifacts (screenshots, HTML snapshots) uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 if: always() From 48c9e8fbbfec0b9793bd8b0099ee1d8ae1bf6fb3 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Tue, 6 Jan 2026 11:24:45 +1100 Subject: [PATCH 2/5] =?UTF-8?q?Revert=20"Add=20visual=20regression=20test?= =?UTF-8?q?=20to=20E2E=20test=20suite."=20That=20won=E2=80=99t=20work,=20s?= =?UTF-8?q?illy.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 7000b1c24a3daff8d74005b7a63a9a7387e3a791. --- .github/workflows/reusable-end-to-end-tests.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/reusable-end-to-end-tests.yml b/.github/workflows/reusable-end-to-end-tests.yml index dfbaf3e23b633..620949d7a6717 100644 --- a/.github/workflows/reusable-end-to-end-tests.yml +++ b/.github/workflows/reusable-end-to-end-tests.yml @@ -144,9 +144,6 @@ jobs: - name: Run E2E tests run: npm run test:e2e - - name: Run visual regression tests - run: npm run test:visual - - name: Archive debug artifacts (screenshots, HTML snapshots) uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 if: always() From b4c7cd02cb786a706792206d6bfe4ff7a7980c2f Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Tue, 6 Jan 2026 12:08:14 +1100 Subject: [PATCH 3/5] Add verification steps for CSS and JS to build. --- Gruntfile.js | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/Gruntfile.js b/Gruntfile.js index f72c93856e6b2..177d0885c43f3 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1788,6 +1788,8 @@ module.exports = function(grunt) { grunt.registerTask( 'verify:build', [ 'verify:old-files', 'verify:source-maps', + 'verify:compressed-css', + 'verify:compressed-js', ] ); /** @@ -1845,6 +1847,106 @@ module.exports = function(grunt) { }); } ); + grunt.registerTask( 'verify:compressed-css', function() { + // Get all CSS files that do not end in *.min.css. + const files = glob.sync( `${ BUILD_DIR }/wp-*/css/**/*.css`, { + ignore: [ '**/*.min.css' ], + } ); + + var errorLog = ''; + + // For each of the files, verify that a minified version also exists. + files.forEach( function( file ) { + const minifiedFile = file.replace( /\.css$/, '.min.css' ); + + if ( ! fs.existsSync( minifiedFile ) ) { + errorLog += `The minified CSS file ${ minifiedFile } does not exist.\n`; + } + } ); + + // Now get all the css files ending in *.min.css + const minifiedFiles = glob.sync( `${ BUILD_DIR }/wp-*/css/**/*.min.css` ); + + // For each of the minified files, verify that an unminified version also exists. + minifiedFiles.forEach( function( file ) { + const unminifiedFile = file.replace( /\.min\.css$/, '.css' ); + + if ( ! fs.existsSync( unminifiedFile ) ) { + errorLog += `The unminified CSS file ${ unminifiedFile } does not exist.\n`; + } + } ); + + assert( + errorLog.length === 0, + errorLog + ); + } ); + + grunt.registerTask( 'verify:compressed-js', function() { + // Get all JavaScript files that do not end in *.min.js. + const files = glob.sync( `${ BUILD_DIR }/wp-*/js/**/*.js`, { + ignore: [ + '**/*.min.js', + '**/wp-admin/js/custom-header.js', + '**/wp-admin/js/farbtastic.js', + '**/wp-includes/js/codemirror/*.js', + '**/wp-includes/js/crop/**', + '**/wp-includes/js/jquery/jquery.query.js', + '**/wp-includes/js/jquery/jquery.schedule.js', + '**/wp-includes/js/jquery/jquery.serialize-object.js', + '**/wp-includes/js/jquery/jquery.ui.touch-punch.js', + '**/wp-includes/js/swfupload/swfupload.js', + '**/wp-includes/js/thickbox/thickbox.js', + '**/wp-includes/js/tinymce/*.js', + '**/wp-includes/js/tinymce/langs/**', + '**/wp-includes/js/tinymce/utils/**', + ], + } ); + + var errorLog = ''; + + // For each of the files, verify that a minified version also exists. + files.forEach( function( file ) { + const minifiedFile = file.replace( /\.js$/, '.min.js' ); + + if ( ! fs.existsSync( minifiedFile ) ) { + errorLog += `The minified JS file ${ minifiedFile } does not exist.\n`; + } + } ); + + // Now get all the js files ending in *.min.js + const minifiedFiles = glob.sync( `${ BUILD_DIR }/wp-*/js/**/*.min.js`, { + ignore: [ + '**/wp-admin/js/iris.min.js', + '**/wp-includes/js/codemirror/codemirror.min.js', + '**/wp-includes/js/dist/react-refresh-entry.min.js', + '**/wp-includes/js/dist/react-refresh-runtime.min.js', + '**/wp-includes/js/hoverintent-js.min.js', + '**/wp-includes/js/imagesloaded.min.js', + '**/wp-includes/js/jcrop/jquery.Jcrop.min.js', + '**/wp-includes/js/jquery/jquery.color.min.js', + '**/wp-includes/js/jquery/jquery.masonry.min.js', + '**/wp-includes/js/masonry.min.js', + '**/wp-includes/js/tinymce/tinymce.min.js', + '**/wp-includes/js/wp-emoji-release.min.js', + '**/wp-includes/js/zxcvbn.min.js', + ], + } ); + + // For each of the minified files, verify that an unminified version also exists. + minifiedFiles.forEach( function( file ) { + const unminifiedFile = file.replace( /\.min\.js$/, '.js' ); + if ( ! fs.existsSync( unminifiedFile ) ) { + errorLog += `The unminified JS file ${ unminifiedFile } does not exist.\n`; + } + } ); + + assert( + errorLog.length === 0, + errorLog + ); + } ); + /** * Compiled JavaScript files may link to sourcemaps. In some cases, * the source map may not be available, which can cause 404 errors when From 1e4bb06faa587f78ac06fdb58e7d5cace7812d74 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Tue, 6 Jan 2026 12:17:11 +1100 Subject: [PATCH 4/5] Chagne order of operations for CSS build. --- Gruntfile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 177d0885c43f3..91b99b03a6803 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1996,9 +1996,9 @@ module.exports = function(grunt) { if ( grunt.option( 'dev' ) ) { grunt.task.run( [ 'build:js', - 'build:css', 'gutenberg-integrate', 'copy-vendor-scripts', + 'build:css', 'build:certificates' ] ); } else { @@ -2006,9 +2006,9 @@ module.exports = function(grunt) { 'build:certificates', 'build:files', 'build:js', - 'build:css', 'gutenberg-integrate', 'copy-vendor-scripts', + 'build:css', 'replace:source-maps', 'verify:build' ] ); From 64452211f51d842d330aa1122310fac489f75849 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Tue, 6 Jan 2026 12:23:31 +1100 Subject: [PATCH 5/5] Compress Gutenberg CSS in build script. --- Gruntfile.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Gruntfile.js b/Gruntfile.js index 91b99b03a6803..9c9e3e53db41a 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -571,6 +571,7 @@ module.exports = function(grunt) { 'wp-admin/css/*.css', '!wp-admin/css/wp-admin*.css', 'wp-includes/css/*.css', + 'wp-includes/css/**/*.css', 'wp-includes/js/mediaelement/wp-mediaelement.css' ] },