1+ /**
2+ * @fileoverview
3+ * This module contains Query Monitor compatibility step definitions for WP Rocket activation.
4+ *
5+ * @requires {@link ../../common/custom-world }
6+ * @requires {@link @cucumber/cucumber }
7+ * @requires {@link @playwright/test }
8+ * @requires {@link ../../../utils/commands }
9+ */
10+ import { Given , Then } from '@cucumber/cucumber' ;
11+ import { ICustomWorld } from '../../common/custom-world' ;
12+ import {
13+ activatePlugin ,
14+ installRemotePlugin ,
15+ isPluginInstalled ,
16+ wpWithOutput ,
17+ } from '../../../utils/commands' ;
18+
19+ /**
20+ * Ensures WordPress core is on the latest version
21+ */
22+ Given ( 'WP is latest WP' , async function ( this : ICustomWorld ) {
23+ const result = await wpWithOutput ( 'core update' ) ;
24+ // Acceptable outcomes: already at latest, or successfully updated
25+ const success = ! result . failed
26+ || result . stdout . includes ( 'WordPress is up to date' )
27+ || result . stdout . includes ( 'Success' ) ;
28+ if ( ! success ) {
29+ throw new Error ( `Failed to update WordPress core: ${ result . stderr } ` ) ;
30+ }
31+ } ) ;
32+
33+ /**
34+ * Ensures Query Monitor plugin is installed and active
35+ */
36+ Given ( 'Query monitor is active' , async function ( this : ICustomWorld ) {
37+ const isInstalled = await isPluginInstalled ( 'query-monitor' ) ;
38+ if ( ! isInstalled ) {
39+ await installRemotePlugin ( 'https://downloads.wordpress.org/plugin/query-monitor.latest-stable.zip' ) ;
40+ }
41+ await activatePlugin ( 'query-monitor' ) ;
42+ } ) ;
43+
44+ /**
45+ * Opens Query Monitor toolbar panel in wp-admin
46+ *
47+ * @return {Promise<void> }
48+ */
49+ const openQueryMonitorToolbar = async function ( this : ICustomWorld ) : Promise < void > {
50+ await this . utils . gotoWpr ( ) ;
51+ await this . page . waitForLoadState ( 'load' , { timeout : 30000 } ) ;
52+
53+ const qmToolbar = this . page . locator ( '#wp-admin-bar-query-monitor' ) ;
54+ await qmToolbar . waitFor ( { state : 'visible' , timeout : 10000 } ) ;
55+
56+ await qmToolbar . locator ( 'a.ab-item' ) . first ( ) . click ( ) ;
57+
58+ // Wait for QM to render its panel container in the DOM (may remain visually hidden)
59+ const qmMain = this . page . locator ( '#query-monitor-main' ) ;
60+ await qmMain . waitFor ( { state : 'attached' , timeout : 10000 } ) ;
61+ } ;
62+
63+ /**
64+ * Verifies Query Monitor has no WP Rocket related entries in the PHP errors panel
65+ */
66+ Then ( 'no PHP error in query monitor about WPR' , async function ( this : ICustomWorld ) {
67+ await openQueryMonitorToolbar . call ( this ) ;
68+
69+ // QM renders a hidden panel; expand it to make it accessible to Playwright
70+ const qmPanel = this . page . locator ( '#qm-php_errors' ) ;
71+ const panelExists = await qmPanel . count ( ) > 0 ;
72+ if ( ! panelExists ) {
73+ return ; // No PHP errors panel = no errors
74+ }
75+
76+ const errorText = await qmPanel . textContent ( ) ;
77+ const wprRelated = errorText ?. includes ( '/plugins/wp-rocket/' )
78+ || errorText ?. includes ( 'WP_Rocket' ) ;
79+
80+ if ( wprRelated ) {
81+ throw new Error ( `PHP errors from WP Rocket found in Query Monitor:\n${ errorText } ` ) ;
82+ }
83+ } ) ;
84+
85+ /**
86+ * Verifies Query Monitor has no WP Rocket related entries in the doing_it_wrong panel
87+ */
88+ Then ( 'no doing it wrong for WPR' , async function ( this : ICustomWorld ) {
89+ await openQueryMonitorToolbar . call ( this ) ;
90+
91+ const qmPanel = this . page . locator ( '#qm-doing_it_wrong' ) ;
92+ const panelExists = await qmPanel . count ( ) > 0 ;
93+ if ( ! panelExists ) {
94+ return ; // No doing_it_wrong panel = no notices
95+ }
96+
97+ const noticeText = await qmPanel . textContent ( ) ;
98+ const wprRelated = noticeText ?. includes ( '/plugins/wp-rocket/' )
99+ || noticeText ?. includes ( 'WP_Rocket' ) ;
100+
101+ if ( wprRelated ) {
102+ throw new Error ( `doing_it_wrong notices from WP Rocket found in Query Monitor:\n${ noticeText } ` ) ;
103+ }
104+ } ) ;
0 commit comments