Skip to content

Commit 23cbf68

Browse files
committed
Update QM e2e test for both QM 3.x and 4.0+
Add separate test cases for QM 3.x (server-side HTML) and QM 4.0+ (Preact shadow DOM). Each test auto-skips when the other QM version is detected.
1 parent e27d533 commit 23cbf68

1 file changed

Lines changed: 102 additions & 5 deletions

File tree

tests/e2e/specs/query-monitor-plugin.test.js

Lines changed: 102 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,112 @@ test.describe( 'Query Monitor plugin', () => {
1212
expect( plugin.status ).toBe( 'inactive' );
1313
}
1414

15-
test.beforeEach( async ( { requestUtils }) => {
15+
test.beforeEach( async ( { requestUtils } ) => {
1616
await deactivateQueryMonitor( requestUtils );
1717
} );
1818

19-
test.afterEach( async ( { requestUtils }) => {
19+
test.afterEach( async ( { requestUtils } ) => {
2020
await deactivateQueryMonitor( requestUtils );
2121
} );
2222

23-
test( 'should activate', async ( { admin, page } ) => {
23+
test( 'should activate and show SQLite queries (QM 4.0+)', async ( { admin, page } ) => {
2424
// Activate the Query Monitor plugin on the plugins page.
2525
await admin.visitAdminPage( '/plugins.php' );
2626
await page.getByLabel( 'Activate Query Monitor', { exact: true } ).click();
2727
await page.getByText( 'Plugin activated.', { exact: true } ).waitFor();
2828

29+
// Skip this test if QM 4.0+ is not active (no shadow DOM container).
30+
const hasContainer = await page.locator( '#query-monitor-container' ).count();
31+
test.skip( hasContainer === 0, 'QM 4.0+ not detected' );
32+
33+
// Click on the Query Monitor admin bar item.
34+
// QM 4.0 re-renders the admin bar with Preact — use the ab-item class.
35+
await page.locator( '#wp-admin-bar-query-monitor > a.ab-item' ).click();
36+
37+
// Wait for the QM panel to render inside the shadow DOM.
38+
const container = page.locator( '#query-monitor-container' );
39+
await expect( async () => {
40+
const hasShadow = await container.evaluate(
41+
( el ) => el.shadowRoot !== null
42+
);
43+
expect( hasShadow ).toBe( true );
44+
} ).toPass();
45+
46+
// Click on the Database Queries tab inside the shadow DOM.
47+
// QM 4.0 renders nav items as <button role="tab">.
48+
await expect( async () => {
49+
await container.evaluate( ( el ) => {
50+
const shadow = el.shadowRoot;
51+
const tabs = shadow.querySelectorAll( 'button[role="tab"]' );
52+
for ( const tab of tabs ) {
53+
if ( tab.textContent.includes( 'Database Queries' ) ) {
54+
tab.click();
55+
return;
56+
}
57+
}
58+
throw new Error( 'Database Queries tab not found' );
59+
} );
60+
} ).toPass();
61+
62+
// Verify the first logged query is visible in the shadow DOM.
63+
await expect( async () => {
64+
const hasSqlQuery = await container.evaluate( ( el ) => {
65+
const shadow = el.shadowRoot;
66+
const codeCells = shadow.querySelectorAll( 'td code' );
67+
for ( const cell of codeCells ) {
68+
if ( cell.textContent.includes( 'SELECT option_name, option_value' ) ) {
69+
return true;
70+
}
71+
}
72+
return false;
73+
} );
74+
expect( hasSqlQuery ).toBe( true );
75+
} ).toPass();
76+
77+
// Click the SQLite <details> summary for the first query row.
78+
// The element is injected by a debounced MutationObserver, so retry.
79+
await expect( async () => {
80+
await container.evaluate( ( el ) => {
81+
const shadow = el.shadowRoot;
82+
const summary = shadow.querySelector( 'details.qm-sqlite summary' );
83+
if ( ! summary ) {
84+
throw new Error( 'SQLite details summary not found' );
85+
}
86+
summary.click();
87+
} );
88+
} ).toPass();
89+
90+
// Verify the SQLite query is displayed.
91+
await expect( async () => {
92+
const hasSqliteQuery = await container.evaluate( ( el ) => {
93+
const shadow = el.shadowRoot;
94+
const sqliteQueries = shadow.querySelectorAll( '.qm-sqlite-query' );
95+
for ( const query of sqliteQueries ) {
96+
if (
97+
query.textContent.includes( 'SELECT' ) &&
98+
query.textContent.includes( 'option_name' )
99+
) {
100+
return true;
101+
}
102+
}
103+
return false;
104+
} );
105+
expect( hasSqliteQuery ).toBe( true );
106+
} ).toPass();
107+
} );
108+
109+
test( 'should activate and show SQLite queries (QM 3.x)', async ( { admin, page } ) => {
110+
// Activate the Query Monitor plugin on the plugins page.
111+
await admin.visitAdminPage( '/plugins.php' );
112+
await page.getByLabel( 'Activate Query Monitor', { exact: true } ).click();
113+
await page.getByText( 'Plugin activated.', { exact: true } ).waitFor();
114+
115+
// Skip this test if QM 3.x is not active (has shadow DOM container = QM 4.0+).
116+
const hasContainer = await page.locator( '#query-monitor-container' ).count();
117+
test.skip( hasContainer > 0, 'QM 3.x not detected' );
118+
29119
// Click on the Query Monitor menu item in the WordPress admin bar.
30-
await page.locator('a[role="menuitem"][href="#qm-overview"][aria-expanded="false"]').click();
120+
await page.locator( '#wp-admin-bar-query-monitor > a' ).click();
31121

32122
// Wait for the Query Monitor panel to open.
33123
await page.locator( '#query-monitor-main' ).waitFor();
@@ -42,6 +132,13 @@ test.describe( 'Query Monitor plugin', () => {
42132

43133
// Check that the query is logged with SQLite information.
44134
await sqlCell.getByLabel( 'Toggle SQLite queries' ).click();
45-
expect( page.locator('.qm-sqlite-query', { hasText: 'SELECT `option_name` , `option_value` FROM `wp_options`' }).first() ).toBeVisible();
135+
await expect(
136+
page
137+
.locator( '.qm-sqlite-query', {
138+
hasText:
139+
'SELECT `option_name` , `option_value` FROM `wp_options`',
140+
} )
141+
.first()
142+
).toBeVisible();
46143
} );
47144
} );

0 commit comments

Comments
 (0)