diff --git a/.github/files/e2e-tests/e2e-matrix.js b/.github/files/e2e-tests/e2e-matrix.js index 7e562a5fa8ee4..f52249d62eda2 100644 --- a/.github/files/e2e-tests/e2e-matrix.js +++ b/.github/files/e2e-tests/e2e-matrix.js @@ -58,6 +58,14 @@ const projects = [ suite: '', buildGroup: 'jetpack-boost', }, + { + project: 'Jetpack Boost - Concatenate JS/CSS', + path: 'projects/plugins/boost/tests/e2e', + testArgs: [ 'specs/concatenate', '--retries=1' ], + targets: [ 'plugins/boost' ], + suite: '', + buildGroup: 'jetpack-boost', + }, { project: 'Jetpack Boost - Image CDN', path: 'projects/plugins/boost/tests/e2e', diff --git a/projects/plugins/boost/app/assets/src/js/features/minify-meta/minify-meta.tsx b/projects/plugins/boost/app/assets/src/js/features/minify-meta/minify-meta.tsx index aaa94271d1fce..af5db8a873745 100644 --- a/projects/plugins/boost/app/assets/src/js/features/minify-meta/minify-meta.tsx +++ b/projects/plugins/boost/app/assets/src/js/features/minify-meta/minify-meta.tsx @@ -22,7 +22,7 @@ const MetaComponent = ( { inputLabel, buttonText, placeholder, datasyncKey }: Pr const htmlId = `jb-minify-meta-${ datasyncKey }`; return ( -
+
{ isEditing ? (
diff --git a/projects/plugins/boost/app/lib/class-cli.php b/projects/plugins/boost/app/lib/class-cli.php index f42e1736633c6..3c8650b956431 100644 --- a/projects/plugins/boost/app/lib/class-cli.php +++ b/projects/plugins/boost/app/lib/class-cli.php @@ -24,7 +24,7 @@ class CLI { */ private $jetpack_boost; - const MAKE_E2E_TESTS_WORK_MODULES = array( 'critical_css', 'render_blocking_js', 'image_cdn', 'image_guide' ); + const MAKE_E2E_TESTS_WORK_MODULES = array( 'critical_css', 'render_blocking_js', 'minify_js', 'minify_css', 'image_cdn', 'image_guide' ); /** * CLI constructor. diff --git a/projects/plugins/boost/changelog/add-e2e-tests-concatenate-js-css b/projects/plugins/boost/changelog/add-e2e-tests-concatenate-js-css new file mode 100644 index 0000000000000..49dc9f80d53e1 --- /dev/null +++ b/projects/plugins/boost/changelog/add-e2e-tests-concatenate-js-css @@ -0,0 +1,5 @@ +Significance: patch +Type: added +Comment: Add e2e tests for Concatenate JS/CSS modules. + + diff --git a/projects/plugins/boost/tests/e2e/lib/env/prerequisites.js b/projects/plugins/boost/tests/e2e/lib/env/prerequisites.js index 5e683ab32a4a1..b43c3731de765 100644 --- a/projects/plugins/boost/tests/e2e/lib/env/prerequisites.js +++ b/projects/plugins/boost/tests/e2e/lib/env/prerequisites.js @@ -12,6 +12,7 @@ export function boostPrerequisitesBuilder( page ) { connected: undefined, jetpackDeactivated: undefined, mockSpeedScore: undefined, + enqueuedAssets: undefined, appendImage: undefined, }; @@ -36,6 +37,10 @@ export function boostPrerequisitesBuilder( page ) { state.mockSpeedScore = shouldMockSpeedScore; return this; }, + withEnqueuedAssets( shouldEnqueueAssets ) { + state.enqueuedAssets = shouldEnqueueAssets; + return this; + }, withAppendedImage( shouldAppendImage ) { state.appendImage = shouldAppendImage; return this; @@ -57,6 +62,7 @@ async function buildPrerequisites( state, page ) { testPostTitles: () => ensureTestPosts( state.testPostTitles ), clean: () => ensureCleanState( state.clean ), mockSpeedScore: () => ensureMockSpeedScoreState( state.mockSpeedScore ), + enqueuedAssets: () => ensureEnqueuedAssets( state.enqueuedAssets ), appendImage: () => ensureAppendedImage( state.appendImage ), }; @@ -99,6 +105,16 @@ export async function ensureMockSpeedScoreState( mockSpeedScore ) { } } +export async function ensureEnqueuedAssets( enqueue ) { + if ( enqueue ) { + logger.prerequisites( 'Enqueuing assets' ); + await execWpCommand( 'plugin activate e2e-concatenate-enqueue/e2e-concatenate-enqueue.php' ); + } else { + logger.prerequisites( 'Deactivating assets' ); + await execWpCommand( 'plugin deactivate e2e-concatenate-enqueue/e2e-concatenate-enqueue.php' ); + } +} + export async function ensureAppendedImage( append ) { if ( append ) { logger.prerequisites( 'Appending image' ); diff --git a/projects/plugins/boost/tests/e2e/lib/pages/wp-admin/JetpackBoostPage.js b/projects/plugins/boost/tests/e2e/lib/pages/wp-admin/JetpackBoostPage.js index a2f1b8a8c27bc..21925f1653f70 100644 --- a/projects/plugins/boost/tests/e2e/lib/pages/wp-admin/JetpackBoostPage.js +++ b/projects/plugins/boost/tests/e2e/lib/pages/wp-admin/JetpackBoostPage.js @@ -126,6 +126,16 @@ export default class JetpackBoostPage extends WpPage { return this.waitForElementToBeVisible( selector ); } + async isConcatenateJsMetaVisible() { + const selector = '[data-testid="meta-minify_js_excludes"]'; + return this.page.isVisible( selector ); + } + + async isConcatenateCssMetaVisible() { + const selector = '[data-testid="meta-minify_css_excludes"]'; + return this.page.isVisible( selector ); + } + async isImageCdnUpgradeSectionVisible() { const selector = '[data-testid="module-image_cdn"] >> text=For more control over image quality'; return this.page.isVisible( selector ); diff --git a/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/assets/e2e-script-one.js b/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/assets/e2e-script-one.js new file mode 100644 index 0000000000000..ddd845e598aba --- /dev/null +++ b/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/assets/e2e-script-one.js @@ -0,0 +1 @@ +console.log( 'e2e-script-one.js' ); diff --git a/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/assets/e2e-script-two.js b/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/assets/e2e-script-two.js new file mode 100644 index 0000000000000..9ce372f348a94 --- /dev/null +++ b/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/assets/e2e-script-two.js @@ -0,0 +1 @@ +console.log( 'e2e-script-two.js' ); diff --git a/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/assets/e2e-style-one.css b/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/assets/e2e-style-one.css new file mode 100644 index 0000000000000..7b521065fcd92 --- /dev/null +++ b/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/assets/e2e-style-one.css @@ -0,0 +1 @@ +.nonexistentselector { color: inherit; } diff --git a/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/assets/e2e-style-two.css b/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/assets/e2e-style-two.css new file mode 100644 index 0000000000000..2ae819307cf72 --- /dev/null +++ b/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/assets/e2e-style-two.css @@ -0,0 +1 @@ +.nonexistentselector2 { color: green; } diff --git a/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/e2e-concatenate-enqueue.php b/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/e2e-concatenate-enqueue.php new file mode 100644 index 0000000000000..c28f5af746ae8 --- /dev/null +++ b/projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/e2e-concatenate-enqueue.php @@ -0,0 +1,22 @@ + { + let page; + + test.beforeAll( async ( { browser } ) => { + page = await browser.newPage( playwrightConfig.use ); + await boostPrerequisitesBuilder( page ).withCleanEnv( true ).withConnection( true ).build(); + } ); + + test.afterAll( async () => {} ); + + test( 'No Concatenate meta information should show on the admin when the modules are inactive', async () => { + await boostPrerequisitesBuilder( page ) + .withInactiveModules( [ 'minify_js', 'minify_css' ] ) + .build(); + const jetpackBoostPage = await JetpackBoostPage.visit( page ); + + expect( + await jetpackBoostPage.isConcatenateJsMetaVisible(), + 'Concatenate JS meta information should not be visible' + ).toBeFalsy(); + expect( + await jetpackBoostPage.isConcatenateCssMetaVisible(), + 'Concatenate CSS meta information should not be visible' + ).toBeFalsy(); + } ); + + test( 'Concatenation shouldn`t occur when the modules are inactive', async () => { + await boostPrerequisitesBuilder( page ) + .withInactiveModules( [ 'minify_js', 'minify_css' ] ) + .withEnqueuedAssets( true ) + .build(); + const postFrontPage = await PostFrontendPage.visit( page ); + + expect( + // This script is enqueued via a helper plugin. + ( await postFrontPage.page.locator( '[id="e2e-script-one-js"]' ).count() ) > 0, + 'JS concatenation shouldn`t occur when the module is inactive' + ).toBeTruthy(); + expect( + // This style is enqueued via a helper plugin. + ( await postFrontPage.page.locator( '[id="e2e-style-one-css"]' ).count() ) > 0, + 'CSS concatenation shouldn`t occur when the module is inactive' + ).toBeTruthy(); + } ); + + test( 'Meta information should be visible when the modules are active', async () => { + await boostPrerequisitesBuilder( page ) + .withActiveModules( [ 'minify_js', 'minify_css' ] ) + .build(); + const jetpackBoostPage = await JetpackBoostPage.visit( page ); + + expect( + await jetpackBoostPage.isConcatenateJsMetaVisible(), + 'Concatenate JS meta information should be visible' + ).toBeTruthy(); + expect( + await jetpackBoostPage.isConcatenateCssMetaVisible(), + 'Concatenate CSS meta information should be visible' + ).toBeTruthy(); + } ); + + test( 'Concatenation occurs when modules are active', async () => { + await boostPrerequisitesBuilder( page ) + .withActiveModules( [ 'minify_js', 'minify_css' ] ) + .withEnqueuedAssets( true ) + .build(); + const postFrontPage = await PostFrontendPage.visit( page ); + + expect( + // e2e-script-one and e2e-script-two are enqueued by a helper plugin. When concatenation is enabled, + // they should be concatenated into a single script. + ( await postFrontPage.page + .locator( '[data-handles*="e2e-script-one"][data-handles*="e2e-script-two"]' ) + .count() ) > 0, + 'JS Concatenation occurs when module is active' + ).toBeTruthy(); + expect( + // e2e-style-one and e2e-style-two are enqueued by a helper plugin. When concatenation is enabled, + // they should be concatenated into a single style. + ( await postFrontPage.page + .locator( '[data-handles*="e2e-style-one"][data-handles*="e2e-style-two"]' ) + .count() ) > 0, + 'CSS Concatenation occurs when module is active' + ).toBeTruthy(); + } ); + + test( 'Assets that are excluded by default shouldn`t be concatenated', async () => { + await boostPrerequisitesBuilder( page ) + .withActiveModules( [ 'minify_js', 'minify_css' ] ) + .withEnqueuedAssets( true ) + .build(); + const postFrontPage = await PostFrontendPage.visit( page ); + + expect( + // jQuery is enqueued by a helper plugin. + ( await postFrontPage.page.locator( '[id="jquery-core-js"]' ).count() ) > 0, + 'jQuery should not be concatenated' + ).toBeTruthy(); + expect( + // Admin bar stylesheet is enqueued by default when logged-in. + ( await postFrontPage.page.locator( '[id="admin-bar-css"]' ).count() ) > 0, + 'Admin bar stylesheet should not be concatenated' + ).toBeTruthy(); + } ); +} ); diff --git a/tools/docker/jetpack-docker-config-default.yml b/tools/docker/jetpack-docker-config-default.yml index 723e425b689e2..b8592a6b13b72 100644 --- a/tools/docker/jetpack-docker-config-default.yml +++ b/tools/docker/jetpack-docker-config-default.yml @@ -61,6 +61,7 @@ e2e: tools/e2e-commons/plugins/e2e-plugin-updater.php: /var/www/html/wp-content/plugins/e2e-plugin-updater.php tools/e2e-commons/plugins/e2e-plan-data-interceptor.php: /var/www/html/wp-content/plugins/e2e-plan-data-interceptor.php tools/e2e-commons/plugins/e2e-waf-data-interceptor.php: /var/www/html/wp-content/plugins/e2e-waf-data-interceptor.php + projects/plugins/boost/tests/e2e/plugins/e2e-concatenate-enqueue/: /var/www/html/wp-content/plugins/e2e-concatenate-enqueue/ projects/plugins/boost/tests/e2e/plugins/e2e-appended-image/: /var/www/html/wp-content/plugins/e2e-appended-image/ projects/plugins/boost/tests/e2e/plugins/e2e-mock-speed-score-api.php: /var/www/html/wp-content/plugins/e2e-mock-speed-score-api.php tools/e2e-commons/plugins/e2e-search-test-helper.php: /var/www/html/wp-content/plugins/e2e-search-test-helper.php