@wordpress/e2e-tests 7.9.0 → 7.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/jest.config.js +1 -4
  3. package/package.json +7 -7
  4. package/plugins/iframed-enqueue-block-editor-settings.php +19 -0
  5. package/plugins/interactive-blocks/{directive-show → directive-body}/block.json +3 -3
  6. package/plugins/interactive-blocks/directive-body/render.php +22 -0
  7. package/plugins/interactive-blocks/directive-body/view.js +11 -0
  8. package/plugins/interactive-blocks/directive-class/render.php +11 -0
  9. package/plugins/interactive-blocks/directive-effect/render.php +13 -1
  10. package/plugins/interactive-blocks/directive-effect/view.js +14 -16
  11. package/plugins/interactive-blocks/directive-init/block.json +14 -0
  12. package/plugins/interactive-blocks/directive-init/render.php +42 -0
  13. package/plugins/interactive-blocks/directive-init/view.js +64 -0
  14. package/plugins/interactive-blocks/directive-on/block.json +14 -0
  15. package/plugins/interactive-blocks/directive-on/render.php +52 -0
  16. package/plugins/interactive-blocks/directive-on/view.js +27 -0
  17. package/plugins/interactive-blocks/directive-priorities/render.php +4 -0
  18. package/plugins/interactive-blocks/store-afterload/block.json +14 -0
  19. package/plugins/interactive-blocks/store-afterload/render.php +41 -0
  20. package/plugins/interactive-blocks/store-afterload/view.js +60 -0
  21. package/plugins/interactive-blocks/tovdom-islands/render.php +5 -5
  22. package/plugins/interactive-blocks/tovdom-islands/view.js +18 -1
  23. package/specs/editor/plugins/iframed-enqueue-block-editor-settings.test.js +108 -0
  24. package/specs/editor/various/__snapshots__/inserting-blocks.test.js.snap +2 -2
  25. package/specs/editor/various/__snapshots__/rich-text.test.js.snap +15 -1
  26. package/specs/editor/various/block-editor-keyboard-shortcuts.test.js +3 -3
  27. package/specs/editor/various/reusable-blocks.test.js +10 -7
  28. package/specs/editor/various/rich-text.test.js +11 -0
  29. package/specs/experiments/blocks/post-comments-form.test.js +2 -2
  30. package/specs/site-editor/settings-sidebar.test.js +1 -1
  31. package/assets/large-post.html +0 -5553
  32. package/assets/small-post-with-containers.html +0 -77
  33. package/config/performance-reporter.js +0 -177
  34. package/config/setup-performance-test.js +0 -51
  35. package/jest.performance.config.js +0 -16
  36. package/plugins/interactive-blocks/directive-show/render.php +0 -53
  37. package/plugins/interactive-blocks/directive-show/view.js +0 -24
  38. package/specs/editor/plugins/allowed-blocks.test.js +0 -59
  39. package/specs/editor/plugins/block-variations.test.js +0 -191
  40. package/specs/editor/plugins/iframed-equeue-block-assets.test.js +0 -51
  41. package/specs/performance/front-end-block-theme.test.js +0 -77
  42. package/specs/performance/front-end-classic-theme.test.js +0 -77
  43. package/specs/performance/post-editor.test.js +0 -369
  44. package/specs/performance/site-editor.test.js +0 -188
  45. package/specs/performance/utils.js +0 -146
@@ -1,51 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import {
5
- activatePlugin,
6
- createNewPost,
7
- deactivatePlugin,
8
- canvas,
9
- activateTheme,
10
- } from '@wordpress/e2e-test-utils';
11
-
12
- async function getComputedStyle( context, selector, property ) {
13
- return await context.evaluate(
14
- ( sel, prop ) =>
15
- window.getComputedStyle( document.querySelector( sel ) )[ prop ],
16
- selector,
17
- property
18
- );
19
- }
20
-
21
- describe( 'iframed inline styles', () => {
22
- beforeEach( async () => {
23
- // Activate the empty theme (block based theme), which is iframed.
24
- await activateTheme( 'emptytheme' );
25
- await activatePlugin( 'gutenberg-test-iframed-enqueue_block_assets' );
26
- await createNewPost();
27
- } );
28
-
29
- afterEach( async () => {
30
- await deactivatePlugin( 'gutenberg-test-iframed-enqueue_block_assets' );
31
- await activateTheme( 'twentytwentyone' );
32
- } );
33
-
34
- it( 'should load styles added through enqueue_block_assets', async () => {
35
- await page.waitForSelector( 'iframe[name="editor-canvas"]' );
36
- // Check stylesheet.
37
- expect(
38
- await getComputedStyle( canvas(), 'body', 'background-color' )
39
- ).toBe( 'rgb(33, 117, 155)' );
40
- // Check inline style.
41
- expect( await getComputedStyle( canvas(), 'body', 'padding' ) ).toBe(
42
- '20px'
43
- );
44
-
45
- expect(
46
- await canvas().evaluate( () => ( { ...document.body.dataset } ) )
47
- ).toEqual( {
48
- iframedEnqueueBlockAssetsL10n: 'Iframed Enqueue Block Assets!',
49
- } );
50
- } );
51
- } );
@@ -1,77 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { activateTheme, createURL, logout } from '@wordpress/e2e-test-utils';
5
-
6
- /**
7
- * Internal dependencies
8
- */
9
- import { saveResultsFile } from './utils';
10
-
11
- describe( 'Front End Performance', () => {
12
- const results = {
13
- timeToFirstByte: [],
14
- largestContentfulPaint: [],
15
- lcpMinusTtfb: [],
16
- };
17
-
18
- beforeAll( async () => {
19
- await activateTheme( 'gutenberg-test-themes/twentytwentythree' );
20
- await logout();
21
- } );
22
-
23
- afterAll( async () => {
24
- saveResultsFile( __filename, results );
25
- } );
26
-
27
- it( 'Report TTFB, LCP, and LCP-TTFB', async () => {
28
- // Based on https://addyosmani.com/blog/puppeteer-recipes/#performance-observer-lcp
29
- function calcLCP() {
30
- // By using -1 we know when it didn't record any event.
31
- window.largestContentfulPaint = -1;
32
-
33
- const observer = new PerformanceObserver( ( entryList ) => {
34
- const entries = entryList.getEntries();
35
- const lastEntry = entries[ entries.length - 1 ];
36
- // According to the spec, we can use startTime
37
- // as it'll report renderTime || loadTime:
38
- // https://www.w3.org/TR/largest-contentful-paint/#largestcontentfulpaint
39
- window.largestContentfulPaint = lastEntry.startTime;
40
- } );
41
-
42
- observer.observe( {
43
- type: 'largest-contentful-paint',
44
- buffered: true,
45
- } );
46
-
47
- document.addEventListener( 'visibilitychange', () => {
48
- if ( document.visibilityState === 'hidden' ) {
49
- observer.takeRecords();
50
- observer.disconnect();
51
- }
52
- } );
53
- }
54
-
55
- let i = 16;
56
- while ( i-- ) {
57
- await page.evaluateOnNewDocument( calcLCP );
58
- // By waiting for networkidle we make sure navigation won't be considered finished on load,
59
- // hence, it'll paint the page and largest-contentful-paint events will be dispatched.
60
- // https://pptr.dev/api/puppeteer.page.goto#remarks
61
- await page.goto( createURL( '/' ), { waitUntil: 'networkidle0' } );
62
-
63
- const { lcp, ttfb } = await page.evaluate( () => {
64
- const [ { responseStart, startTime } ] =
65
- performance.getEntriesByType( 'navigation' );
66
- return {
67
- lcp: window.largestContentfulPaint,
68
- ttfb: responseStart - startTime,
69
- };
70
- } );
71
-
72
- results.largestContentfulPaint.push( lcp );
73
- results.timeToFirstByte.push( ttfb );
74
- results.lcpMinusTtfb.push( lcp - ttfb );
75
- }
76
- } );
77
- } );
@@ -1,77 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import { activateTheme, createURL, logout } from '@wordpress/e2e-test-utils';
5
-
6
- /**
7
- * Internal dependencies
8
- */
9
- import { saveResultsFile } from './utils';
10
-
11
- describe( 'Front End Performance', () => {
12
- const results = {
13
- timeToFirstByte: [],
14
- largestContentfulPaint: [],
15
- lcpMinusTtfb: [],
16
- };
17
-
18
- beforeAll( async () => {
19
- await activateTheme( 'gutenberg-test-themes/twentytwentyone' );
20
- await logout();
21
- } );
22
-
23
- afterAll( async () => {
24
- saveResultsFile( __filename, results );
25
- } );
26
-
27
- it( 'Report TTFB, LCP, and LCP-TTFB', async () => {
28
- // Based on https://addyosmani.com/blog/puppeteer-recipes/#performance-observer-lcp
29
- function calcLCP() {
30
- // By using -1 we know when it didn't record any event.
31
- window.largestContentfulPaint = -1;
32
-
33
- const observer = new PerformanceObserver( ( entryList ) => {
34
- const entries = entryList.getEntries();
35
- const lastEntry = entries[ entries.length - 1 ];
36
- // According to the spec, we can use startTime
37
- // as it'll report renderTime || loadTime:
38
- // https://www.w3.org/TR/largest-contentful-paint/#largestcontentfulpaint
39
- window.largestContentfulPaint = lastEntry.startTime;
40
- } );
41
-
42
- observer.observe( {
43
- type: 'largest-contentful-paint',
44
- buffered: true,
45
- } );
46
-
47
- document.addEventListener( 'visibilitychange', () => {
48
- if ( document.visibilityState === 'hidden' ) {
49
- observer.takeRecords();
50
- observer.disconnect();
51
- }
52
- } );
53
- }
54
-
55
- let i = 16;
56
- while ( i-- ) {
57
- await page.evaluateOnNewDocument( calcLCP );
58
- // By waiting for networkidle we make sure navigation won't be considered finished on load,
59
- // hence, it'll paint the page and largest-contentful-paint events will be dispatched.
60
- // https://pptr.dev/api/puppeteer.page.goto#remarks
61
- await page.goto( createURL( '/' ), { waitUntil: 'networkidle0' } );
62
-
63
- const { lcp, ttfb } = await page.evaluate( () => {
64
- const [ { responseStart, startTime } ] =
65
- performance.getEntriesByType( 'navigation' );
66
- return {
67
- lcp: window.largestContentfulPaint,
68
- ttfb: responseStart - startTime,
69
- };
70
- } );
71
-
72
- results.largestContentfulPaint.push( lcp );
73
- results.timeToFirstByte.push( ttfb );
74
- results.lcpMinusTtfb.push( lcp - ttfb );
75
- }
76
- } );
77
- } );
@@ -1,369 +0,0 @@
1
- /**
2
- * External dependencies
3
- */
4
- import path from 'path';
5
-
6
- /**
7
- * WordPress dependencies
8
- */
9
- import {
10
- activateTheme,
11
- createNewPost,
12
- saveDraft,
13
- insertBlock,
14
- openGlobalBlockInserter,
15
- closeGlobalBlockInserter,
16
- openListView,
17
- closeListView,
18
- canvas,
19
- } from '@wordpress/e2e-test-utils';
20
-
21
- /**
22
- * Internal dependencies
23
- */
24
- import {
25
- readFile,
26
- deleteFile,
27
- saveResultsFile,
28
- getTraceFilePath,
29
- getTypingEventDurations,
30
- getClickEventDurations,
31
- getHoverEventDurations,
32
- getSelectionEventDurations,
33
- getLoadingDurations,
34
- sum,
35
- } from './utils';
36
-
37
- jest.setTimeout( 1000000 );
38
-
39
- async function loadHtmlIntoTheBlockEditor( html ) {
40
- await page.evaluate( ( _html ) => {
41
- const { parse } = window.wp.blocks;
42
- const { dispatch } = window.wp.data;
43
- const blocks = parse( _html );
44
-
45
- blocks.forEach( ( block ) => {
46
- if ( block.name === 'core/image' ) {
47
- delete block.attributes.id;
48
- delete block.attributes.url;
49
- }
50
- } );
51
-
52
- dispatch( 'core/block-editor' ).resetBlocks( blocks );
53
- }, html );
54
- }
55
-
56
- async function load1000Paragraphs() {
57
- await page.evaluate( () => {
58
- const { createBlock } = window.wp.blocks;
59
- const { dispatch } = window.wp.data;
60
- const blocks = Array.from( { length: 1000 } ).map( () =>
61
- createBlock( 'core/paragraph' )
62
- );
63
- dispatch( 'core/block-editor' ).resetBlocks( blocks );
64
- } );
65
- }
66
-
67
- describe( 'Post Editor Performance', () => {
68
- const results = {
69
- serverResponse: [],
70
- firstPaint: [],
71
- domContentLoaded: [],
72
- loaded: [],
73
- firstContentfulPaint: [],
74
- firstBlock: [],
75
- type: [],
76
- typeContainer: [],
77
- focus: [],
78
- listViewOpen: [],
79
- inserterOpen: [],
80
- inserterHover: [],
81
- inserterSearch: [],
82
- };
83
- const traceFilePath = getTraceFilePath();
84
-
85
- let traceResults;
86
-
87
- beforeAll( async () => {
88
- // See https://github.com/WordPress/gutenberg/pull/50905/files#r1209014677;
89
- await activateTheme( 'gutenberg-test-themes/twentytwentyone' );
90
- } );
91
-
92
- afterAll( async () => {
93
- saveResultsFile( __filename, results );
94
- deleteFile( traceFilePath );
95
- } );
96
-
97
- beforeEach( async () => {
98
- await createNewPost();
99
- // Disable auto-save to avoid impacting the metrics.
100
- await page.evaluate( () => {
101
- window.wp.data.dispatch( 'core/editor' ).updateEditorSettings( {
102
- autosaveInterval: 100000000000,
103
- localAutosaveInterval: 100000000000,
104
- } );
105
- } );
106
- } );
107
-
108
- it( 'Loading', async () => {
109
- await loadHtmlIntoTheBlockEditor(
110
- readFile( path.join( __dirname, '../../assets/large-post.html' ) )
111
- );
112
- await saveDraft();
113
- const draftURL = await page.url();
114
-
115
- // Number of sample measurements to take.
116
- const samples = 5;
117
- // Number of throwaway measurements to perform before recording samples.
118
- // Having at least one helps ensure that caching quirks don't manifest in
119
- // the results.
120
- const throwaway = 1;
121
-
122
- let i = throwaway + samples;
123
- while ( i-- ) {
124
- await page.close();
125
- page = await browser.newPage();
126
-
127
- await page.goto( draftURL );
128
- await page.waitForSelector( '.edit-post-layout', {
129
- timeout: 120000,
130
- } );
131
- await canvas().waitForSelector( '.wp-block', { timeout: 120000 } );
132
-
133
- if ( i < samples ) {
134
- const {
135
- serverResponse,
136
- firstPaint,
137
- domContentLoaded,
138
- loaded,
139
- firstContentfulPaint,
140
- firstBlock,
141
- } = await getLoadingDurations();
142
-
143
- results.serverResponse.push( serverResponse );
144
- results.firstPaint.push( firstPaint );
145
- results.domContentLoaded.push( domContentLoaded );
146
- results.loaded.push( loaded );
147
- results.firstContentfulPaint.push( firstContentfulPaint );
148
- results.firstBlock.push( firstBlock );
149
- }
150
- }
151
- } );
152
-
153
- it( 'Typing', async () => {
154
- await loadHtmlIntoTheBlockEditor(
155
- readFile( path.join( __dirname, '../../assets/large-post.html' ) )
156
- );
157
- await insertBlock( 'Paragraph' );
158
- let i = 20;
159
- await page.tracing.start( {
160
- path: traceFilePath,
161
- screenshots: false,
162
- categories: [ 'devtools.timeline' ],
163
- } );
164
- while ( i-- ) {
165
- // Wait for the browser to be idle before starting the monitoring.
166
- // The timeout should be big enough to allow all async tasks tor run.
167
- // And also to allow Rich Text to mark the change as persistent.
168
- // eslint-disable-next-line no-restricted-syntax
169
- await page.waitForTimeout( 2000 );
170
- await page.keyboard.type( 'x' );
171
- }
172
- await page.tracing.stop();
173
- traceResults = JSON.parse( readFile( traceFilePath ) );
174
- const [ keyDownEvents, keyPressEvents, keyUpEvents ] =
175
- getTypingEventDurations( traceResults );
176
- if (
177
- keyDownEvents.length === keyPressEvents.length &&
178
- keyPressEvents.length === keyUpEvents.length
179
- ) {
180
- // The first character typed triggers a longer time (isTyping change)
181
- // It can impact the stability of the metric, so we exclude it.
182
- for ( let j = 1; j < keyDownEvents.length; j++ ) {
183
- results.type.push(
184
- keyDownEvents[ j ] + keyPressEvents[ j ] + keyUpEvents[ j ]
185
- );
186
- }
187
- }
188
- } );
189
-
190
- it( 'Typing within containers', async () => {
191
- await loadHtmlIntoTheBlockEditor(
192
- readFile(
193
- path.join(
194
- __dirname,
195
- '../../assets/small-post-with-containers.html'
196
- )
197
- )
198
- );
199
- // Select the block where we type in
200
- await canvas().waitForSelector( 'p[aria-label="Paragraph block"]' );
201
- await canvas().click( 'p[aria-label="Paragraph block"]' );
202
- // Ignore firsted typed character because it's different
203
- // It probably deserves a dedicated metric.
204
- // (isTyping triggers so it's slower)
205
- await page.keyboard.type( 'x' );
206
-
207
- let i = 10;
208
- await page.tracing.start( {
209
- path: traceFilePath,
210
- screenshots: false,
211
- categories: [ 'devtools.timeline' ],
212
- } );
213
-
214
- while ( i-- ) {
215
- // Wait for the browser to be idle before starting the monitoring.
216
- // eslint-disable-next-line no-restricted-syntax
217
- await page.waitForTimeout( 500 );
218
- await page.keyboard.type( 'x' );
219
- }
220
- // eslint-disable-next-line no-restricted-syntax
221
- await page.waitForTimeout( 500 );
222
- await page.tracing.stop();
223
- traceResults = JSON.parse( readFile( traceFilePath ) );
224
- const [ keyDownEvents, keyPressEvents, keyUpEvents ] =
225
- getTypingEventDurations( traceResults );
226
- if (
227
- keyDownEvents.length === keyPressEvents.length &&
228
- keyPressEvents.length === keyUpEvents.length
229
- ) {
230
- // The first character typed triggers a longer time (isTyping change)
231
- // It can impact the stability of the metric, so we exclude it.
232
- for ( let j = 1; j < keyDownEvents.length; j++ ) {
233
- results.typeContainer.push(
234
- keyDownEvents[ j ] + keyPressEvents[ j ] + keyUpEvents[ j ]
235
- );
236
- }
237
- }
238
- } );
239
-
240
- it( 'Selecting blocks', async () => {
241
- await load1000Paragraphs();
242
- const paragraphs = await canvas().$$( '.wp-block' );
243
- await paragraphs[ 0 ].click();
244
- for ( let j = 1; j <= 10; j++ ) {
245
- // Wait for the browser to be idle before starting the monitoring.
246
- // eslint-disable-next-line no-restricted-syntax
247
- await page.waitForTimeout( 1000 );
248
- await page.tracing.start( {
249
- path: traceFilePath,
250
- screenshots: false,
251
- categories: [ 'devtools.timeline' ],
252
- } );
253
- await paragraphs[ j ].click();
254
- await page.tracing.stop();
255
- traceResults = JSON.parse( readFile( traceFilePath ) );
256
- const allDurations = getSelectionEventDurations( traceResults );
257
- results.focus.push(
258
- allDurations.reduce( ( acc, eventDurations ) => {
259
- return acc + sum( eventDurations );
260
- }, 0 )
261
- );
262
- }
263
- } );
264
-
265
- it( 'Opening persistent list view', async () => {
266
- await load1000Paragraphs();
267
- for ( let j = 0; j < 10; j++ ) {
268
- await page.tracing.start( {
269
- path: traceFilePath,
270
- screenshots: false,
271
- categories: [ 'devtools.timeline' ],
272
- } );
273
- await openListView();
274
- await page.tracing.stop();
275
- traceResults = JSON.parse( readFile( traceFilePath ) );
276
- const [ mouseClickEvents ] = getClickEventDurations( traceResults );
277
- for ( let k = 0; k < mouseClickEvents.length; k++ ) {
278
- results.listViewOpen.push( mouseClickEvents[ k ] );
279
- }
280
- await closeListView();
281
- }
282
- } );
283
-
284
- it( 'Opening the inserter', async () => {
285
- await load1000Paragraphs();
286
- for ( let j = 0; j < 10; j++ ) {
287
- await page.tracing.start( {
288
- path: traceFilePath,
289
- screenshots: false,
290
- categories: [ 'devtools.timeline' ],
291
- } );
292
- await openGlobalBlockInserter();
293
- await page.tracing.stop();
294
- traceResults = JSON.parse( readFile( traceFilePath ) );
295
- const [ mouseClickEvents ] = getClickEventDurations( traceResults );
296
- for ( let k = 0; k < mouseClickEvents.length; k++ ) {
297
- results.inserterOpen.push( mouseClickEvents[ k ] );
298
- }
299
- await closeGlobalBlockInserter();
300
- }
301
- } );
302
-
303
- it( 'Searching the inserter', async () => {
304
- await load1000Paragraphs();
305
- await openGlobalBlockInserter();
306
- for ( let j = 0; j < 10; j++ ) {
307
- // Wait for the browser to be idle before starting the monitoring.
308
- // eslint-disable-next-line no-restricted-syntax
309
- await page.waitForTimeout( 500 );
310
- await page.tracing.start( {
311
- path: traceFilePath,
312
- screenshots: false,
313
- categories: [ 'devtools.timeline' ],
314
- } );
315
- await page.keyboard.type( 'p' );
316
- await page.tracing.stop();
317
- traceResults = JSON.parse( readFile( traceFilePath ) );
318
- const [ keyDownEvents, keyPressEvents, keyUpEvents ] =
319
- getTypingEventDurations( traceResults );
320
- if (
321
- keyDownEvents.length === keyPressEvents.length &&
322
- keyPressEvents.length === keyUpEvents.length
323
- ) {
324
- results.inserterSearch.push(
325
- sum( keyDownEvents ) +
326
- sum( keyPressEvents ) +
327
- sum( keyUpEvents )
328
- );
329
- }
330
- await page.keyboard.press( 'Backspace' );
331
- }
332
- await closeGlobalBlockInserter();
333
- } );
334
-
335
- it( 'Hovering Inserter Items', async () => {
336
- await load1000Paragraphs();
337
- const paragraphBlockItem =
338
- '.block-editor-inserter__menu .editor-block-list-item-paragraph';
339
- const headingBlockItem =
340
- '.block-editor-inserter__menu .editor-block-list-item-heading';
341
- await openGlobalBlockInserter();
342
- await page.waitForSelector( paragraphBlockItem );
343
- await page.hover( paragraphBlockItem );
344
- await page.hover( headingBlockItem );
345
- for ( let j = 0; j < 10; j++ ) {
346
- // Wait for the browser to be idle before starting the monitoring.
347
- // eslint-disable-next-line no-restricted-syntax
348
- await page.waitForTimeout( 200 );
349
- await page.tracing.start( {
350
- path: traceFilePath,
351
- screenshots: false,
352
- categories: [ 'devtools.timeline' ],
353
- } );
354
- await page.hover( paragraphBlockItem );
355
- await page.hover( headingBlockItem );
356
- await page.tracing.stop();
357
-
358
- traceResults = JSON.parse( readFile( traceFilePath ) );
359
- const [ mouseOverEvents, mouseOutEvents ] =
360
- getHoverEventDurations( traceResults );
361
- for ( let k = 0; k < mouseOverEvents.length; k++ ) {
362
- results.inserterHover.push(
363
- mouseOverEvents[ k ] + mouseOutEvents[ k ]
364
- );
365
- }
366
- }
367
- await closeGlobalBlockInserter();
368
- } );
369
- } );