@wordpress/e2e-tests 6.3.5 → 6.5.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 (41) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/config/setup-performance-test.js +14 -7
  3. package/jest.config.js +4 -0
  4. package/package.json +7 -7
  5. package/specs/editor/blocks/pullquote.test.js +3 -3
  6. package/specs/editor/plugins/__snapshots__/align-hook.test.js.snap +11 -11
  7. package/specs/editor/plugins/__snapshots__/container-blocks.test.js.snap +14 -14
  8. package/specs/editor/plugins/__snapshots__/cpt-locking.test.js.snap +29 -29
  9. package/specs/editor/plugins/__snapshots__/iframed-inline-styles.test.js.snap +1 -1
  10. package/specs/editor/plugins/__snapshots__/iframed-masonry-block.test.js.snap +1 -1
  11. package/specs/editor/plugins/__snapshots__/inner-blocks-render-appender.test.js.snap +5 -5
  12. package/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap +2 -2
  13. package/specs/editor/various/__snapshots__/adding-patterns.test.js.snap +4 -4
  14. package/specs/editor/various/__snapshots__/block-grouping.test.js.snap +21 -21
  15. package/specs/editor/various/__snapshots__/block-hierarchy-navigation.test.js.snap +12 -12
  16. package/specs/editor/various/__snapshots__/embedding.test.js.snap +19 -19
  17. package/specs/editor/various/__snapshots__/inserting-blocks.test.js.snap +8 -8
  18. package/specs/editor/various/__snapshots__/keep-styles-on-block-transforms.test.js.snap +11 -11
  19. package/specs/editor/various/__snapshots__/links.test.js.snap +9 -9
  20. package/specs/editor/various/__snapshots__/multi-block-selection.test.js.snap +17 -17
  21. package/specs/editor/various/__snapshots__/rich-text.test.js.snap +5 -5
  22. package/specs/editor/various/block-grouping.test.js +3 -3
  23. package/specs/editor/various/format-library/__snapshots__/text-color.test.js.snap +1 -1
  24. package/specs/editor/various/links.test.js +50 -16
  25. package/specs/editor/various/multi-block-selection.test.js +2 -2
  26. package/specs/performance/front-end-block-theme.test.js +48 -12
  27. package/specs/performance/front-end-classic-theme.test.js +50 -13
  28. package/specs/performance/post-editor.test.js +45 -28
  29. package/specs/performance/site-editor.test.js +69 -42
  30. package/specs/performance/utils.js +12 -1
  31. package/specs/widgets/editing-widgets.test.js +20 -15
  32. package/specs/editor/blocks/__snapshots__/heading.test.js.snap +0 -51
  33. package/specs/editor/blocks/__snapshots__/navigation.test.js.snap +0 -47
  34. package/specs/editor/blocks/heading.test.js +0 -113
  35. package/specs/editor/blocks/navigation.test.js +0 -1723
  36. package/specs/editor/blocks/query.test.js +0 -66
  37. package/specs/editor/various/__snapshots__/block-deletion.test.js.snap +0 -111
  38. package/specs/editor/various/__snapshots__/list-view.test.js.snap +0 -15
  39. package/specs/editor/various/block-deletion.test.js +0 -209
  40. package/specs/editor/various/list-view.test.js +0 -330
  41. package/specs/editor/various/switch-to-draft.test.js +0 -254
@@ -8,6 +8,7 @@ import {
8
8
  createNewPost,
9
9
  pressKeyWithModifier,
10
10
  showBlockToolbar,
11
+ pressKeyTimes,
11
12
  } from '@wordpress/e2e-test-utils';
12
13
 
13
14
  describe( 'Links', () => {
@@ -119,8 +120,11 @@ describe( 'Links', () => {
119
120
  // Type a URL.
120
121
  await page.keyboard.type( 'https://wordpress.org/gutenberg' );
121
122
 
122
- // Navigate to and toggle the "Open in new tab" checkbox.
123
+ // Open settings.
123
124
  await page.keyboard.press( 'Tab' );
125
+ await page.keyboard.press( 'Space' );
126
+
127
+ // Navigate to and toggle the "Open in new tab" checkbox.
124
128
  await page.keyboard.press( 'Tab' );
125
129
  await page.keyboard.press( 'Space' );
126
130
 
@@ -134,7 +138,7 @@ describe( 'Links', () => {
134
138
  expect( await getEditedPostContent() ).toMatchSnapshot();
135
139
 
136
140
  // Tab back to the Submit and apply the link.
137
- await pressKeyWithModifier( 'shift', 'Tab' );
141
+ await page.keyboard.press( 'Tab' );
138
142
  await page.keyboard.press( 'Enter' );
139
143
 
140
144
  // The link should have been inserted.
@@ -525,8 +529,11 @@ describe( 'Links', () => {
525
529
  await waitForURLFieldAutoFocus();
526
530
  await page.keyboard.type( 'w.org' );
527
531
 
528
- // Navigate to and toggle the "Open in new tab" checkbox.
532
+ // Link settings open
529
533
  await page.keyboard.press( 'Tab' );
534
+ await page.keyboard.press( 'Space' );
535
+
536
+ // Navigate to and toggle the "Open in new tab" checkbox.
530
537
  await page.keyboard.press( 'Tab' );
531
538
  await page.keyboard.press( 'Space' );
532
539
 
@@ -534,7 +541,7 @@ describe( 'Links', () => {
534
541
  // a changing value of the setting.
535
542
  await page.waitForSelector( ':focus.components-form-toggle__input' );
536
543
 
537
- // Close dialog. Expect that "Open in new tab" would have been applied
544
+ // Submit link. Expect that "Open in new tab" would have been applied
538
545
  // immediately.
539
546
  await page.keyboard.press( 'Tab' );
540
547
  await page.keyboard.press( 'Enter' );
@@ -597,8 +604,10 @@ describe( 'Links', () => {
597
604
  // Press Cmd+K to insert a link.
598
605
  await pressKeyWithModifier( 'primary', 'K' );
599
606
 
600
- // Wait for the URL field to auto-focus.
601
- await waitForURLFieldAutoFocus();
607
+ const [ settingsToggle ] = await page.$x(
608
+ '//button[contains(@aria-label, "Link Settings")]'
609
+ );
610
+ await settingsToggle.click();
602
611
 
603
612
  const textInput = await page
604
613
  .waitForXPath(
@@ -625,11 +634,17 @@ describe( 'Links', () => {
625
634
  '//button[contains(@aria-label, "Edit")]'
626
635
  );
627
636
  await editButton.click();
637
+
628
638
  await waitForURLFieldAutoFocus();
629
639
 
630
- await pressKeyWithModifier( 'shift', 'Tab' );
640
+ const [ settingsToggle ] = await page.$x(
641
+ '//button[contains(@aria-label, "Link Settings")]'
642
+ );
643
+ await settingsToggle.click();
631
644
 
632
- // Tabbing back should land us in the text input.
645
+ await page.keyboard.press( 'Tab' );
646
+
647
+ // Tabbing should land us in the text input.
633
648
  const { isTextInput, textValue } = await page.evaluate( () => {
634
649
  const el = document.activeElement;
635
650
 
@@ -686,7 +701,12 @@ describe( 'Links', () => {
686
701
 
687
702
  await waitForURLFieldAutoFocus();
688
703
 
689
- await pressKeyWithModifier( 'shift', 'Tab' );
704
+ const [ settingsToggle ] = await page.$x(
705
+ '//button[contains(@aria-label, "Link Settings")]'
706
+ );
707
+ await settingsToggle.click();
708
+
709
+ await page.keyboard.press( 'Tab' );
690
710
 
691
711
  // Tabbing back should land us in the text input.
692
712
  const textInputValue = await page.evaluate(
@@ -716,9 +736,14 @@ describe( 'Links', () => {
716
736
  await editButton.click();
717
737
  await waitForURLFieldAutoFocus();
718
738
 
719
- await pressKeyWithModifier( 'shift', 'Tab' );
739
+ const [ settingsToggle ] = await page.$x(
740
+ '//button[contains(@aria-label, "Link Settings")]'
741
+ );
742
+ await settingsToggle.click();
720
743
 
721
- // Tabbing back should land us in the text input.
744
+ await page.keyboard.press( 'Tab' );
745
+
746
+ // Tabbing should land us in the text input.
722
747
  const textInputValue = await page.evaluate(
723
748
  () => document.activeElement.value
724
749
  );
@@ -762,10 +787,13 @@ describe( 'Links', () => {
762
787
  await editButton.click();
763
788
  await waitForURLFieldAutoFocus();
764
789
 
790
+ const [ settingsToggle ] = await page.$x(
791
+ '//button[contains(@aria-label, "Link Settings")]'
792
+ );
793
+ await settingsToggle.click();
794
+
765
795
  // Move focus back to RichText for the underlying link.
766
- await page.keyboard.press( 'Tab' );
767
- await page.keyboard.press( 'Tab' );
768
- await page.keyboard.press( 'Tab' );
796
+ await pressKeyTimes( 'Tab', 5 );
769
797
 
770
798
  // Make a selection within the RichText.
771
799
  await pressKeyWithModifier( 'shift', 'ArrowRight' );
@@ -773,7 +801,7 @@ describe( 'Links', () => {
773
801
  await pressKeyWithModifier( 'shift', 'ArrowRight' );
774
802
 
775
803
  // Move back to the text input.
776
- await page.keyboard.press( 'Tab' );
804
+ await pressKeyTimes( 'Tab', 3 );
777
805
 
778
806
  // Tabbing back should land us in the text input.
779
807
  const textInputValue = await page.evaluate(
@@ -971,8 +999,14 @@ describe( 'Links', () => {
971
999
  await page.keyboard.press( 'Tab' );
972
1000
  await page.keyboard.press( 'Enter' );
973
1001
 
1002
+ await waitForURLFieldAutoFocus();
1003
+
1004
+ // Link settings open
1005
+ await page.keyboard.press( 'Tab' );
1006
+ await page.keyboard.press( 'Space' );
1007
+
974
1008
  // Move to Link Text field.
975
- await pressKeyWithModifier( 'shift', 'Tab' );
1009
+ await page.keyboard.press( 'Tab' );
976
1010
 
977
1011
  // Change text to "z"
978
1012
  await page.keyboard.type( 'z' );
@@ -359,8 +359,8 @@ describe( 'Multi-block selection', () => {
359
359
  await page.mouse.up();
360
360
  await page.keyboard.type( 'hi' );
361
361
  expect( await getEditedPostContent() ).toMatchInlineSnapshot( `
362
- "<!-- wp:group {\\"layout\\":{\\"type\\":\\"constrained\\"}} -->
363
- <div class=\\"wp-block-group\\"><!-- wp:paragraph -->
362
+ "<!-- wp:group {"layout":{"type":"constrained"}} -->
363
+ <div class="wp-block-group"><!-- wp:paragraph -->
364
364
  <p>hih text in group</p>
365
365
  <!-- /wp:paragraph --></div>
366
366
  <!-- /wp:group -->"
@@ -12,6 +12,8 @@ import { activateTheme, createURL, logout } from '@wordpress/e2e-test-utils';
12
12
  describe( 'Front End Performance', () => {
13
13
  const results = {
14
14
  timeToFirstByte: [],
15
+ largestContentfulPaint: [],
16
+ lcpMinusTtfb: [],
15
17
  };
16
18
 
17
19
  beforeAll( async () => {
@@ -28,20 +30,54 @@ describe( 'Front End Performance', () => {
28
30
  );
29
31
  } );
30
32
 
31
- it( 'Time To First Byte (TTFB)', async () => {
32
- // We derive the 75th percentile of the TTFB based on these results.
33
- // By running it 16 times, the percentile value would be (75/100)*16=12,
34
- // meaning that we discard the worst 4 values.
33
+ it( 'Report TTFB, LCP, and LCP-TTFB', async () => {
34
+ // Based on https://addyosmani.com/blog/puppeteer-recipes/#performance-observer-lcp
35
+ function calcLCP() {
36
+ // By using -1 we know when it didn't record any event.
37
+ window.largestContentfulPaint = -1;
38
+
39
+ const observer = new PerformanceObserver( ( entryList ) => {
40
+ const entries = entryList.getEntries();
41
+ const lastEntry = entries[ entries.length - 1 ];
42
+ // According to the spec, we can use startTime
43
+ // as it'll report renderTime || loadTime:
44
+ // https://www.w3.org/TR/largest-contentful-paint/#largestcontentfulpaint
45
+ window.largestContentfulPaint = lastEntry.startTime;
46
+ } );
47
+
48
+ observer.observe( {
49
+ type: 'largest-contentful-paint',
50
+ buffered: true,
51
+ } );
52
+
53
+ document.addEventListener( 'visibilitychange', () => {
54
+ if ( document.visibilityState === 'hidden' ) {
55
+ observer.takeRecords();
56
+ observer.disconnect();
57
+ }
58
+ } );
59
+ }
60
+
35
61
  let i = 16;
36
62
  while ( i-- ) {
37
- await page.goto( createURL( '/' ) );
38
- const navigationTimingJson = await page.evaluate( () =>
39
- JSON.stringify( performance.getEntriesByType( 'navigation' ) )
40
- );
41
- const [ navigationTiming ] = JSON.parse( navigationTimingJson );
42
- results.timeToFirstByte.push(
43
- navigationTiming.responseStart - navigationTiming.startTime
44
- );
63
+ await page.evaluateOnNewDocument( calcLCP );
64
+ // By waiting for networkidle we make sure navigation won't be considered finished on load,
65
+ // hence, it'll paint the page and largest-contentful-paint events will be dispatched.
66
+ // https://pptr.dev/api/puppeteer.page.goto#remarks
67
+ await page.goto( createURL( '/' ), { waitUntil: 'networkidle0' } );
68
+
69
+ const { lcp, ttfb } = await page.evaluate( () => {
70
+ const [ { responseStart, startTime } ] =
71
+ performance.getEntriesByType( 'navigation' );
72
+ return {
73
+ lcp: window.largestContentfulPaint,
74
+ ttfb: responseStart - startTime,
75
+ };
76
+ } );
77
+
78
+ results.largestContentfulPaint.push( lcp );
79
+ results.timeToFirstByte.push( ttfb );
80
+ results.lcpMinusTtfb.push( lcp - ttfb );
45
81
  }
46
82
  } );
47
83
  } );
@@ -7,14 +7,17 @@ import { writeFileSync } from 'fs';
7
7
  /**
8
8
  * WordPress dependencies
9
9
  */
10
- import { createURL, logout } from '@wordpress/e2e-test-utils';
10
+ import { activateTheme, createURL, logout } from '@wordpress/e2e-test-utils';
11
11
 
12
12
  describe( 'Front End Performance', () => {
13
13
  const results = {
14
14
  timeToFirstByte: [],
15
+ largestContentfulPaint: [],
16
+ lcpMinusTtfb: [],
15
17
  };
16
18
 
17
19
  beforeAll( async () => {
20
+ await activateTheme( 'twentytwentyone' );
18
21
  await logout();
19
22
  } );
20
23
 
@@ -26,20 +29,54 @@ describe( 'Front End Performance', () => {
26
29
  );
27
30
  } );
28
31
 
29
- it( 'Time To First Byte (TTFB)', async () => {
30
- // We derive the 75th percentile of the TTFB based on these results.
31
- // By running it 16 times, the percentile value would be (75/100)*16=12,
32
- // meaning that we discard the worst 4 values.
32
+ it( 'Report TTFB, LCP, and LCP-TTFB', async () => {
33
+ // Based on https://addyosmani.com/blog/puppeteer-recipes/#performance-observer-lcp
34
+ function calcLCP() {
35
+ // By using -1 we know when it didn't record any event.
36
+ window.largestContentfulPaint = -1;
37
+
38
+ const observer = new PerformanceObserver( ( entryList ) => {
39
+ const entries = entryList.getEntries();
40
+ const lastEntry = entries[ entries.length - 1 ];
41
+ // According to the spec, we can use startTime
42
+ // as it'll report renderTime || loadTime:
43
+ // https://www.w3.org/TR/largest-contentful-paint/#largestcontentfulpaint
44
+ window.largestContentfulPaint = lastEntry.startTime;
45
+ } );
46
+
47
+ observer.observe( {
48
+ type: 'largest-contentful-paint',
49
+ buffered: true,
50
+ } );
51
+
52
+ document.addEventListener( 'visibilitychange', () => {
53
+ if ( document.visibilityState === 'hidden' ) {
54
+ observer.takeRecords();
55
+ observer.disconnect();
56
+ }
57
+ } );
58
+ }
59
+
33
60
  let i = 16;
34
61
  while ( i-- ) {
35
- await page.goto( createURL( '/' ) );
36
- const navigationTimingJson = await page.evaluate( () =>
37
- JSON.stringify( performance.getEntriesByType( 'navigation' ) )
38
- );
39
- const [ navigationTiming ] = JSON.parse( navigationTimingJson );
40
- results.timeToFirstByte.push(
41
- navigationTiming.responseStart - navigationTiming.startTime
42
- );
62
+ await page.evaluateOnNewDocument( calcLCP );
63
+ // By waiting for networkidle we make sure navigation won't be considered finished on load,
64
+ // hence, it'll paint the page and largest-contentful-paint events will be dispatched.
65
+ // https://pptr.dev/api/puppeteer.page.goto#remarks
66
+ await page.goto( createURL( '/' ), { waitUntil: 'networkidle0' } );
67
+
68
+ const { lcp, ttfb } = await page.evaluate( () => {
69
+ const [ { responseStart, startTime } ] =
70
+ performance.getEntriesByType( 'navigation' );
71
+ return {
72
+ lcp: window.largestContentfulPaint,
73
+ ttfb: responseStart - startTime,
74
+ };
75
+ } );
76
+
77
+ results.largestContentfulPaint.push( lcp );
78
+ results.timeToFirstByte.push( ttfb );
79
+ results.lcpMinusTtfb.push( lcp - ttfb );
43
80
  }
44
81
  } );
45
82
  } );
@@ -29,6 +29,7 @@ import {
29
29
  getHoverEventDurations,
30
30
  getSelectionEventDurations,
31
31
  getLoadingDurations,
32
+ sum,
32
33
  } from './utils';
33
34
 
34
35
  jest.setTimeout( 1000000 );
@@ -105,28 +106,43 @@ describe( 'Post Editor Performance', () => {
105
106
  readFile( join( __dirname, '../../assets/large-post.html' ) )
106
107
  );
107
108
  await saveDraft();
108
- let i = 5;
109
+ const draftURL = await page.url();
110
+
111
+ // Number of sample measurements to take.
112
+ const samples = 5;
113
+ // Number of throwaway measurements to perform before recording samples.
114
+ // Having at least one helps ensure that caching quirks don't manifest in
115
+ // the results.
116
+ const throwaway = 1;
117
+
118
+ let i = throwaway + samples;
109
119
  while ( i-- ) {
110
- await page.reload();
120
+ await page.close();
121
+ page = await browser.newPage();
122
+
123
+ await page.goto( draftURL );
111
124
  await page.waitForSelector( '.edit-post-layout', {
112
125
  timeout: 120000,
113
126
  } );
114
127
  await canvas().waitForSelector( '.wp-block', { timeout: 120000 } );
115
- const {
116
- serverResponse,
117
- firstPaint,
118
- domContentLoaded,
119
- loaded,
120
- firstContentfulPaint,
121
- firstBlock,
122
- } = await getLoadingDurations();
123
128
 
124
- results.serverResponse.push( serverResponse );
125
- results.firstPaint.push( firstPaint );
126
- results.domContentLoaded.push( domContentLoaded );
127
- results.loaded.push( loaded );
128
- results.firstContentfulPaint.push( firstContentfulPaint );
129
- results.firstBlock.push( firstBlock );
129
+ if ( i < samples ) {
130
+ const {
131
+ serverResponse,
132
+ firstPaint,
133
+ domContentLoaded,
134
+ loaded,
135
+ firstContentfulPaint,
136
+ firstBlock,
137
+ } = await getLoadingDurations();
138
+
139
+ results.serverResponse.push( serverResponse );
140
+ results.firstPaint.push( firstPaint );
141
+ results.domContentLoaded.push( domContentLoaded );
142
+ results.loaded.push( loaded );
143
+ results.firstContentfulPaint.push( firstContentfulPaint );
144
+ results.firstBlock.push( firstBlock );
145
+ }
130
146
  }
131
147
  } );
132
148
 
@@ -220,22 +236,26 @@ describe( 'Post Editor Performance', () => {
220
236
  it( 'Selecting blocks', async () => {
221
237
  await load1000Paragraphs();
222
238
  const paragraphs = await canvas().$$( '.wp-block' );
223
- await page.tracing.start( {
224
- path: traceFile,
225
- screenshots: false,
226
- categories: [ 'devtools.timeline' ],
227
- } );
228
239
  await paragraphs[ 0 ].click();
229
240
  for ( let j = 1; j <= 10; j++ ) {
230
241
  // Wait for the browser to be idle before starting the monitoring.
231
242
  // eslint-disable-next-line no-restricted-syntax
232
243
  await page.waitForTimeout( 1000 );
244
+ await page.tracing.start( {
245
+ path: traceFile,
246
+ screenshots: false,
247
+ categories: [ 'devtools.timeline' ],
248
+ } );
233
249
  await paragraphs[ j ].click();
250
+ await page.tracing.stop();
251
+ traceResults = JSON.parse( readFile( traceFile ) );
252
+ const allDurations = getSelectionEventDurations( traceResults );
253
+ results.focus.push(
254
+ allDurations.reduce( ( acc, eventDurations ) => {
255
+ return acc + sum( eventDurations );
256
+ }, 0 )
257
+ );
234
258
  }
235
- await page.tracing.stop();
236
- traceResults = JSON.parse( readFile( traceFile ) );
237
- const [ focusEvents ] = getSelectionEventDurations( traceResults );
238
- results.focus = focusEvents;
239
259
  } );
240
260
 
241
261
  it( 'Opening persistent list view', async () => {
@@ -277,9 +297,6 @@ describe( 'Post Editor Performance', () => {
277
297
  } );
278
298
 
279
299
  it( 'Searching the inserter', async () => {
280
- function sum( arr ) {
281
- return arr.reduce( ( a, b ) => a + b, 0 );
282
- }
283
300
  await load1000Paragraphs();
284
301
  await openGlobalBlockInserter();
285
302
  for ( let j = 0; j < 10; j++ ) {
@@ -30,34 +30,29 @@ import {
30
30
 
31
31
  jest.setTimeout( 1000000 );
32
32
 
33
+ const results = {
34
+ serverResponse: [],
35
+ firstPaint: [],
36
+ domContentLoaded: [],
37
+ loaded: [],
38
+ firstContentfulPaint: [],
39
+ firstBlock: [],
40
+ type: [],
41
+ typeContainer: [],
42
+ focus: [],
43
+ inserterOpen: [],
44
+ inserterHover: [],
45
+ inserterSearch: [],
46
+ listViewOpen: [],
47
+ };
48
+
49
+ let id;
50
+
33
51
  describe( 'Site Editor Performance', () => {
34
52
  beforeAll( async () => {
35
53
  await activateTheme( 'emptytheme' );
36
54
  await deleteAllTemplates( 'wp_template' );
37
55
  await deleteAllTemplates( 'wp_template_part' );
38
- } );
39
- afterAll( async () => {
40
- await deleteAllTemplates( 'wp_template' );
41
- await deleteAllTemplates( 'wp_template_part' );
42
- await activateTheme( 'twentytwentyone' );
43
- } );
44
-
45
- it( 'Loading', async () => {
46
- const results = {
47
- serverResponse: [],
48
- firstPaint: [],
49
- domContentLoaded: [],
50
- loaded: [],
51
- firstContentfulPaint: [],
52
- firstBlock: [],
53
- type: [],
54
- typeContainer: [],
55
- focus: [],
56
- inserterOpen: [],
57
- inserterHover: [],
58
- inserterSearch: [],
59
- listViewOpen: [],
60
- };
61
56
 
62
57
  const html = readFile(
63
58
  join( __dirname, '../../assets/large-post.html' )
@@ -80,40 +75,72 @@ describe( 'Site Editor Performance', () => {
80
75
  }, html );
81
76
  await saveDraft();
82
77
 
83
- const id = await page.evaluate( () =>
78
+ id = await page.evaluate( () =>
84
79
  new URL( document.location ).searchParams.get( 'post' )
85
80
  );
81
+ } );
86
82
 
83
+ afterAll( async () => {
84
+ await deleteAllTemplates( 'wp_template' );
85
+ await deleteAllTemplates( 'wp_template_part' );
86
+ await activateTheme( 'twentytwentyone' );
87
+ } );
88
+
89
+ beforeEach( async () => {
87
90
  await visitSiteEditor( {
88
91
  postId: id,
89
92
  postType: 'page',
90
93
  } );
94
+ } );
95
+
96
+ it( 'Loading', async () => {
97
+ const editorURL = await page.url();
91
98
 
92
- let i = 3;
99
+ // Number of sample measurements to take.
100
+ const samples = 3;
101
+ // Number of throwaway measurements to perform before recording samples.
102
+ // Having at least one helps ensure that caching quirks don't manifest in
103
+ // the results.
104
+ const throwaway = 1;
105
+
106
+ let i = throwaway + samples;
93
107
 
94
108
  // Measuring loading time.
95
109
  while ( i-- ) {
96
- await page.reload();
110
+ await page.close();
111
+ page = await browser.newPage();
112
+
113
+ await page.goto( editorURL );
97
114
  await page.waitForSelector( '.edit-site-visual-editor', {
98
115
  timeout: 120000,
99
116
  } );
100
117
  await canvas().waitForSelector( '.wp-block', { timeout: 120000 } );
101
- const {
102
- serverResponse,
103
- firstPaint,
104
- domContentLoaded,
105
- loaded,
106
- firstContentfulPaint,
107
- firstBlock,
108
- } = await getLoadingDurations();
109
-
110
- results.serverResponse.push( serverResponse );
111
- results.firstPaint.push( firstPaint );
112
- results.domContentLoaded.push( domContentLoaded );
113
- results.loaded.push( loaded );
114
- results.firstContentfulPaint.push( firstContentfulPaint );
115
- results.firstBlock.push( firstBlock );
118
+
119
+ if ( i < samples ) {
120
+ const {
121
+ serverResponse,
122
+ firstPaint,
123
+ domContentLoaded,
124
+ loaded,
125
+ firstContentfulPaint,
126
+ firstBlock,
127
+ } = await getLoadingDurations();
128
+
129
+ results.serverResponse.push( serverResponse );
130
+ results.firstPaint.push( firstPaint );
131
+ results.domContentLoaded.push( domContentLoaded );
132
+ results.loaded.push( loaded );
133
+ results.firstContentfulPaint.push( firstContentfulPaint );
134
+ results.firstBlock.push( firstBlock );
135
+ }
116
136
  }
137
+ } );
138
+
139
+ it( 'Typing', async () => {
140
+ await page.waitForSelector( '.edit-site-visual-editor', {
141
+ timeout: 120000,
142
+ } );
143
+ await canvas().waitForSelector( '.wp-block', { timeout: 120000 } );
117
144
 
118
145
  // Measuring typing performance inside the post content.
119
146
  await canvas().waitForSelector(
@@ -124,7 +151,7 @@ describe( 'Site Editor Performance', () => {
124
151
  '[data-type="core/post-content"] [data-type="core/paragraph"]'
125
152
  );
126
153
  await insertBlock( 'Paragraph' );
127
- i = 200;
154
+ let i = 200;
128
155
  const traceFile = __dirname + '/trace.json';
129
156
  await page.tracing.start( {
130
157
  path: traceFile,
@@ -41,6 +41,10 @@ function isFocusEvent( item ) {
41
41
  return isEvent( item ) && item.args.data.type === 'focus';
42
42
  }
43
43
 
44
+ function isFocusInEvent( item ) {
45
+ return isEvent( item ) && item.args.data.type === 'focusin';
46
+ }
47
+
44
48
  function isClickEvent( item ) {
45
49
  return isEvent( item ) && item.args.data.type === 'click';
46
50
  }
@@ -68,7 +72,10 @@ export function getTypingEventDurations( trace ) {
68
72
  }
69
73
 
70
74
  export function getSelectionEventDurations( trace ) {
71
- return [ getEventDurationsForType( trace, isFocusEvent ) ];
75
+ return [
76
+ getEventDurationsForType( trace, isFocusEvent ),
77
+ getEventDurationsForType( trace, isFocusInEvent ),
78
+ ];
72
79
  }
73
80
 
74
81
  export function getClickEventDurations( trace ) {
@@ -113,3 +120,7 @@ export async function getLoadingDurations() {
113
120
  };
114
121
  } );
115
122
  }
123
+
124
+ export function sum( arr ) {
125
+ return arr.reduce( ( a, b ) => a + b, 0 );
126
+ }