@wordpress/e2e-tests 6.3.2 → 6.4.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 6.4.0 (2023-02-15)
6
+
5
7
  ## 6.3.0 (2023-02-01)
6
8
 
7
9
  ## 6.2.0 (2023-01-11)
@@ -19,9 +19,11 @@ const PUPPETEER_TIMEOUT = process.env.PUPPETEER_TIMEOUT;
19
19
  // The Jest timeout is increased because these tests are a bit slow.
20
20
  jest.setTimeout( PUPPETEER_TIMEOUT || 100000 );
21
21
 
22
- async function setupBrowser() {
23
- await clearLocalStorage();
22
+ async function setupPage() {
24
23
  await setBrowserViewport( 'large' );
24
+ await page.emulateMediaFeatures( [
25
+ { name: 'prefers-reduced-motion', value: 'reduce' },
26
+ ] );
25
27
  }
26
28
 
27
29
  // Before every test suite run, delete all content created by the test. This ensures
@@ -32,13 +34,18 @@ beforeAll( async () => {
32
34
 
33
35
  await trashAllPosts();
34
36
  await trashAllPosts( 'wp_block' );
35
- await setupBrowser();
37
+ await clearLocalStorage();
38
+ await setupPage();
36
39
  await activatePlugin( 'gutenberg-test-plugin-disables-the-css-animations' );
37
- await page.emulateMediaFeatures( [
38
- { name: 'prefers-reduced-motion', value: 'reduce' },
39
- ] );
40
40
  } );
41
41
 
42
42
  afterEach( async () => {
43
- await setupBrowser();
43
+ // Clear localStorage between tests so that the next test starts clean.
44
+ await clearLocalStorage();
45
+ // Close the previous page entirely and create a new page, so that the next test
46
+ // isn't affected by page unload work.
47
+ await page.close();
48
+ page = await browser.newPage();
49
+ // Set up testing config on new page.
50
+ await setupPage();
44
51
  } );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/e2e-tests",
3
- "version": "6.3.2",
3
+ "version": "6.4.0",
4
4
  "description": "End-To-End (E2E) tests for WordPress.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -23,11 +23,11 @@
23
23
  "node": ">=14"
24
24
  },
25
25
  "dependencies": {
26
- "@wordpress/e2e-test-utils": "^9.3.1",
27
- "@wordpress/jest-console": "^6.9.1",
28
- "@wordpress/jest-puppeteer-axe": "^5.9.1",
29
- "@wordpress/scripts": "^25.3.2",
30
- "@wordpress/url": "^3.27.1",
26
+ "@wordpress/e2e-test-utils": "^9.4.0",
27
+ "@wordpress/jest-console": "^6.10.0",
28
+ "@wordpress/jest-puppeteer-axe": "^5.10.0",
29
+ "@wordpress/scripts": "^25.4.0",
30
+ "@wordpress/url": "^3.28.0",
31
31
  "chalk": "^4.0.0",
32
32
  "expect-puppeteer": "^4.4.0",
33
33
  "filenamify": "^4.2.0",
@@ -46,5 +46,5 @@
46
46
  "publishConfig": {
47
47
  "access": "public"
48
48
  },
49
- "gitHead": "3eb2c536278d5a17f698b9c378fe3db746a89622"
49
+ "gitHead": "c25ff895413bad4354c55c0c2d732552618b0d56"
50
50
  }
@@ -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,6 +120,10 @@ describe( 'Links', () => {
119
120
  // Type a URL.
120
121
  await page.keyboard.type( 'https://wordpress.org/gutenberg' );
121
122
 
123
+ // Open settings.
124
+ await page.keyboard.press( 'Tab' );
125
+ await page.keyboard.press( 'Space' );
126
+
122
127
  // Navigate to and toggle the "Open in new tab" checkbox.
123
128
  await page.keyboard.press( 'Tab' );
124
129
  await page.keyboard.press( 'Space' );
@@ -524,6 +529,10 @@ describe( 'Links', () => {
524
529
  await waitForURLFieldAutoFocus();
525
530
  await page.keyboard.type( 'w.org' );
526
531
 
532
+ // Toggle link settings open
533
+ await page.keyboard.press( 'Tab' );
534
+ await page.keyboard.press( 'Space' );
535
+
527
536
  // Navigate to and toggle the "Open in new tab" checkbox.
528
537
  await page.keyboard.press( 'Tab' );
529
538
  await page.keyboard.press( 'Space' );
@@ -532,10 +541,9 @@ describe( 'Links', () => {
532
541
  // a changing value of the setting.
533
542
  await page.waitForSelector( ':focus.components-form-toggle__input' );
534
543
 
535
- // 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
536
545
  // immediately.
537
-
538
- await pressKeyWithModifier( 'shift', 'Tab' );
546
+ await page.keyboard.press( 'Tab' );
539
547
  await page.keyboard.press( 'Enter' );
540
548
 
541
549
  // Wait for Gutenberg to finish the job.
@@ -596,8 +604,10 @@ describe( 'Links', () => {
596
604
  // Press Cmd+K to insert a link.
597
605
  await pressKeyWithModifier( 'primary', 'K' );
598
606
 
599
- // Wait for the URL field to auto-focus.
600
- await waitForURLFieldAutoFocus();
607
+ const [ settingsToggle ] = await page.$x(
608
+ '//button[contains(@aria-label, "Toggle link settings")]'
609
+ );
610
+ await settingsToggle.click();
601
611
 
602
612
  const textInput = await page
603
613
  .waitForXPath(
@@ -624,11 +634,17 @@ describe( 'Links', () => {
624
634
  '//button[contains(@aria-label, "Edit")]'
625
635
  );
626
636
  await editButton.click();
637
+
627
638
  await waitForURLFieldAutoFocus();
628
639
 
629
- await pressKeyWithModifier( 'shift', 'Tab' );
640
+ const [ settingsToggle ] = await page.$x(
641
+ '//button[contains(@aria-label, "Toggle link settings")]'
642
+ );
643
+ await settingsToggle.click();
630
644
 
631
- // 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.
632
648
  const { isTextInput, textValue } = await page.evaluate( () => {
633
649
  const el = document.activeElement;
634
650
 
@@ -685,7 +701,12 @@ describe( 'Links', () => {
685
701
 
686
702
  await waitForURLFieldAutoFocus();
687
703
 
688
- await pressKeyWithModifier( 'shift', 'Tab' );
704
+ const [ settingsToggle ] = await page.$x(
705
+ '//button[contains(@aria-label, "Toggle link settings")]'
706
+ );
707
+ await settingsToggle.click();
708
+
709
+ await page.keyboard.press( 'Tab' );
689
710
 
690
711
  // Tabbing back should land us in the text input.
691
712
  const textInputValue = await page.evaluate(
@@ -715,9 +736,14 @@ describe( 'Links', () => {
715
736
  await editButton.click();
716
737
  await waitForURLFieldAutoFocus();
717
738
 
718
- await pressKeyWithModifier( 'shift', 'Tab' );
739
+ const [ settingsToggle ] = await page.$x(
740
+ '//button[contains(@aria-label, "Toggle link settings")]'
741
+ );
742
+ await settingsToggle.click();
719
743
 
720
- // 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.
721
747
  const textInputValue = await page.evaluate(
722
748
  () => document.activeElement.value
723
749
  );
@@ -761,11 +787,13 @@ describe( 'Links', () => {
761
787
  await editButton.click();
762
788
  await waitForURLFieldAutoFocus();
763
789
 
790
+ const [ settingsToggle ] = await page.$x(
791
+ '//button[contains(@aria-label, "Toggle link settings")]'
792
+ );
793
+ await settingsToggle.click();
794
+
764
795
  // Move focus back to RichText for the underlying link.
765
- await page.keyboard.press( 'Tab' );
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
+ // Toggle 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' );
@@ -5,6 +5,7 @@ import {
5
5
  createNewPost,
6
6
  insertBlock,
7
7
  getEditedPostContent,
8
+ isListViewOpen,
8
9
  openListView,
9
10
  pressKeyWithModifier,
10
11
  pressKeyTimes,
@@ -327,4 +328,87 @@ describe( 'List view', () => {
327
328
  );
328
329
  await expect( listViewGroupBlockRight ).toHaveFocus();
329
330
  } );
331
+
332
+ async function getActiveElementLabel() {
333
+ return page.evaluate(
334
+ () =>
335
+ document.activeElement.getAttribute( 'aria-label' ) ||
336
+ document.activeElement.textContent
337
+ );
338
+ }
339
+
340
+ // If list view sidebar is open and focus is not inside the sidebar, move focus to the sidebar when using the shortcut. If focus is inside the sidebar, shortcut should close the sidebar.
341
+ it( 'ensures the list view global shortcut works properly', async () => {
342
+ // Insert some blocks of different types.
343
+ await insertBlock( 'Image' );
344
+ await insertBlock( 'Paragraph' );
345
+ await page.keyboard.type( 'Paragraph text.' );
346
+
347
+ // Open list view sidebar.
348
+ await pressKeyWithModifier( 'access', 'o' );
349
+
350
+ // Navigate to the image block.
351
+ await page.keyboard.press( 'ArrowUp' );
352
+ // Check if image block link in the list view has focus by XPath selector.
353
+ const listViewImageBlock = await page.waitForXPath(
354
+ '//a[contains(., "Image")]'
355
+ );
356
+ await expect( listViewImageBlock ).toHaveFocus();
357
+ // Select the image block in the list view to move focus to it in the canvas.
358
+ await page.keyboard.press( 'Enter' );
359
+
360
+ // Check if image block upload button has focus by XPath selector.
361
+ const imageBlockUploadButton = await page.waitForXPath(
362
+ '//button[contains(text(), "Upload")]'
363
+ );
364
+ await expect( imageBlockUploadButton ).toHaveFocus();
365
+
366
+ // Since focus is now at the image block upload button in the canvas, pressing the list view shortcut should bring focus back to the image block in the list view.
367
+ await pressKeyWithModifier( 'access', 'o' );
368
+ await expect( listViewImageBlock ).toHaveFocus();
369
+
370
+ // Since focus is now inside the list view, the shortcut should close the sidebar.
371
+ await pressKeyWithModifier( 'access', 'o' );
372
+ // Focus should now be on the paragraph block since that is where we opened the list view sidebar. This is not a perfect solution, but current functionality prevents a better way at the moment. Get the current block aria-label and compare.
373
+ await expect( await getActiveElementLabel() ).toEqual(
374
+ 'Paragraph block'
375
+ );
376
+ // List view sidebar should be closed.
377
+ await expect( await isListViewOpen() ).toBeFalsy();
378
+
379
+ // Open list view sidebar.
380
+ await pressKeyWithModifier( 'access', 'o' );
381
+
382
+ // Focus the list view close button and make sure the shortcut will close the list view. This is to catch a bug where elements could be out of range of the sidebar region. Must shift+tab 3 times to reach cclose button before tabs.
383
+ await pressKeyWithModifier( 'shift', 'Tab' );
384
+ await pressKeyWithModifier( 'shift', 'Tab' );
385
+ await pressKeyWithModifier( 'shift', 'Tab' );
386
+ await expect( await getActiveElementLabel() ).toEqual(
387
+ 'Close Document Overview Sidebar'
388
+ );
389
+
390
+ // Close the list view sidebar.
391
+ await pressKeyWithModifier( 'access', 'o' );
392
+ // List view sidebar should be closed.
393
+ await expect( await isListViewOpen() ).toBeFalsy();
394
+
395
+ // Open list view sidebar.
396
+ await pressKeyWithModifier( 'access', 'o' );
397
+
398
+ // Focus the outline tab and select it. This test ensures the outline tab receives similar focus events based on the shortcut.
399
+ await pressKeyWithModifier( 'shift', 'Tab' );
400
+ await expect( await getActiveElementLabel() ).toEqual( 'Outline' );
401
+ await page.keyboard.press( 'Enter' );
402
+
403
+ // From here, tab in to the editor so focus can be checked on return to the outline tab in the sidebar.
404
+ await pressKeyTimes( 'Tab', 2 );
405
+ // Focus should be placed on the outline tab button since there is nothing to focus inside the tab itself.
406
+ await pressKeyWithModifier( 'access', 'o' );
407
+ await expect( await getActiveElementLabel() ).toEqual( 'Outline' );
408
+
409
+ // Close the list view sidebar.
410
+ await pressKeyWithModifier( 'access', 'o' );
411
+ // List view sidebar should be closed.
412
+ await expect( await isListViewOpen() ).toBeFalsy();
413
+ } );
330
414
  } );
@@ -12,6 +12,7 @@ import { activateTheme, createURL, logout } from '@wordpress/e2e-test-utils';
12
12
  describe( 'Front End Performance', () => {
13
13
  const results = {
14
14
  timeToFirstByte: [],
15
+ largestContentfulPaint: [],
15
16
  };
16
17
 
17
18
  beforeAll( async () => {
@@ -44,4 +45,50 @@ describe( 'Front End Performance', () => {
44
45
  );
45
46
  }
46
47
  } );
48
+
49
+ it( 'Largest Contentful Paint (LCP)', async () => {
50
+ // Based on https://addyosmani.com/blog/puppeteer-recipes/#performance-observer-lcp
51
+ function calcLCP() {
52
+ // By using -1 we know when it didn't record any event.
53
+ window.largestContentfulPaint = -1;
54
+
55
+ const observer = new PerformanceObserver( ( entryList ) => {
56
+ const entries = entryList.getEntries();
57
+ const lastEntry = entries[ entries.length - 1 ];
58
+ // According to the spec, we can use startTime
59
+ // as it'll report renderTime || loadTime:
60
+ // https://www.w3.org/TR/largest-contentful-paint/#largestcontentfulpaint
61
+ window.largestContentfulPaint = lastEntry.startTime;
62
+ } );
63
+
64
+ observer.observe( {
65
+ type: 'largest-contentful-paint',
66
+ buffered: true,
67
+ } );
68
+
69
+ document.addEventListener( 'visibilitychange', () => {
70
+ if ( document.visibilityState === 'hidden' ) {
71
+ observer.takeRecords();
72
+ observer.disconnect();
73
+ }
74
+ } );
75
+ }
76
+
77
+ // We derive the 75th percentile of the TTFB based on these results.
78
+ // By running it 16 times, the percentile value would be (75/100)*16=12,
79
+ // meaning that we discard the worst 4 values.
80
+ let i = 16;
81
+ while ( i-- ) {
82
+ await page.evaluateOnNewDocument( calcLCP );
83
+ // By waiting for networkidle we make sure navigation won't be considered finished on load,
84
+ // hence, it'll paint the page and largest-contentful-paint events will be dispatched.
85
+ // https://pptr.dev/api/puppeteer.page.goto#remarks
86
+ await page.goto( createURL( '/' ), { waitUntil: 'networkidle0' } );
87
+
88
+ const lcp = await page.evaluate(
89
+ () => window.largestContentfulPaint
90
+ );
91
+ results.largestContentfulPaint.push( lcp );
92
+ }
93
+ } );
47
94
  } );
@@ -7,14 +7,16 @@ 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: [],
15
16
  };
16
17
 
17
18
  beforeAll( async () => {
19
+ await activateTheme( 'twentytwentyone' );
18
20
  await logout();
19
21
  } );
20
22
 
@@ -42,4 +44,50 @@ describe( 'Front End Performance', () => {
42
44
  );
43
45
  }
44
46
  } );
47
+
48
+ it( 'Largest Contentful Paint (LCP)', async () => {
49
+ // Based on https://addyosmani.com/blog/puppeteer-recipes/#performance-observer-lcp
50
+ function calcLCP() {
51
+ // By using -1 we know when it didn't record any event.
52
+ window.largestContentfulPaint = -1;
53
+
54
+ const observer = new PerformanceObserver( ( entryList ) => {
55
+ const entries = entryList.getEntries();
56
+ const lastEntry = entries[ entries.length - 1 ];
57
+ // According to the spec, we can use startTime
58
+ // as it'll report renderTime || loadTime:
59
+ // https://www.w3.org/TR/largest-contentful-paint/#largestcontentfulpaint
60
+ window.largestContentfulPaint = lastEntry.startTime;
61
+ } );
62
+
63
+ observer.observe( {
64
+ type: 'largest-contentful-paint',
65
+ buffered: true,
66
+ } );
67
+
68
+ document.addEventListener( 'visibilitychange', () => {
69
+ if ( document.visibilityState === 'hidden' ) {
70
+ observer.takeRecords();
71
+ observer.disconnect();
72
+ }
73
+ } );
74
+ }
75
+
76
+ // We derive the 75th percentile of the TTFB based on these results.
77
+ // By running it 16 times, the percentile value would be (75/100)*16=12,
78
+ // meaning that we discard the worst 4 values.
79
+ let i = 16;
80
+ while ( i-- ) {
81
+ await page.evaluateOnNewDocument( calcLCP );
82
+ // By waiting for networkidle we make sure navigation won't be considered finished on load,
83
+ // hence, it'll paint the page and largest-contentful-paint events will be dispatched.
84
+ // https://pptr.dev/api/puppeteer.page.goto#remarks
85
+ await page.goto( createURL( '/' ), { waitUntil: 'networkidle0' } );
86
+
87
+ const lcp = await page.evaluate(
88
+ () => window.largestContentfulPaint
89
+ );
90
+ results.largestContentfulPaint.push( lcp );
91
+ }
92
+ } );
45
93
  } );
@@ -105,28 +105,43 @@ describe( 'Post Editor Performance', () => {
105
105
  readFile( join( __dirname, '../../assets/large-post.html' ) )
106
106
  );
107
107
  await saveDraft();
108
- let i = 5;
108
+ const draftURL = await page.url();
109
+
110
+ // Number of sample measurements to take.
111
+ const samples = 5;
112
+ // Number of throwaway measurements to perform before recording samples.
113
+ // Having at least one helps ensure that caching quirks don't manifest in
114
+ // the results.
115
+ const throwaway = 1;
116
+
117
+ let i = throwaway + samples;
109
118
  while ( i-- ) {
110
- await page.reload();
119
+ await page.close();
120
+ page = await browser.newPage();
121
+
122
+ await page.goto( draftURL );
111
123
  await page.waitForSelector( '.edit-post-layout', {
112
124
  timeout: 120000,
113
125
  } );
114
126
  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
127
 
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 );
128
+ if ( i < samples ) {
129
+ const {
130
+ serverResponse,
131
+ firstPaint,
132
+ domContentLoaded,
133
+ loaded,
134
+ firstContentfulPaint,
135
+ firstBlock,
136
+ } = await getLoadingDurations();
137
+
138
+ results.serverResponse.push( serverResponse );
139
+ results.firstPaint.push( firstPaint );
140
+ results.domContentLoaded.push( domContentLoaded );
141
+ results.loaded.push( loaded );
142
+ results.firstContentfulPaint.push( firstContentfulPaint );
143
+ results.firstBlock.push( firstBlock );
144
+ }
130
145
  }
131
146
  } );
132
147
 
@@ -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,37 +75,73 @@ 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
+ } );
82
+
83
+ afterAll( async () => {
84
+ await deleteAllTemplates( 'wp_template' );
85
+ await deleteAllTemplates( 'wp_template_part' );
86
+ await activateTheme( 'twentytwentyone' );
87
+ } );
86
88
 
87
- await visitSiteEditor( { postId: id, postType: 'page' } );
89
+ beforeEach( async () => {
90
+ await visitSiteEditor( {
91
+ postId: id,
92
+ postType: 'page',
93
+ path: '/navigation/single',
94
+ } );
95
+ } );
96
+
97
+ it( 'Loading', async () => {
98
+ const editorURL = await page.url();
88
99
 
89
- let i = 3;
100
+ // Number of sample measurements to take.
101
+ const samples = 3;
102
+ // Number of throwaway measurements to perform before recording samples.
103
+ // Having at least one helps ensure that caching quirks don't manifest in
104
+ // the results.
105
+ const throwaway = 1;
106
+
107
+ let i = throwaway + samples;
90
108
 
91
109
  // Measuring loading time.
92
110
  while ( i-- ) {
93
- await page.reload();
111
+ await page.close();
112
+ page = await browser.newPage();
113
+
114
+ await page.goto( editorURL );
94
115
  await page.waitForSelector( '.edit-site-visual-editor', {
95
116
  timeout: 120000,
96
117
  } );
97
118
  await canvas().waitForSelector( '.wp-block', { timeout: 120000 } );
98
- const {
99
- serverResponse,
100
- firstPaint,
101
- domContentLoaded,
102
- loaded,
103
- firstContentfulPaint,
104
- firstBlock,
105
- } = await getLoadingDurations();
106
-
107
- results.serverResponse.push( serverResponse );
108
- results.firstPaint.push( firstPaint );
109
- results.domContentLoaded.push( domContentLoaded );
110
- results.loaded.push( loaded );
111
- results.firstContentfulPaint.push( firstContentfulPaint );
112
- results.firstBlock.push( firstBlock );
119
+
120
+ if ( i < samples ) {
121
+ const {
122
+ serverResponse,
123
+ firstPaint,
124
+ domContentLoaded,
125
+ loaded,
126
+ firstContentfulPaint,
127
+ firstBlock,
128
+ } = await getLoadingDurations();
129
+
130
+ results.serverResponse.push( serverResponse );
131
+ results.firstPaint.push( firstPaint );
132
+ results.domContentLoaded.push( domContentLoaded );
133
+ results.loaded.push( loaded );
134
+ results.firstContentfulPaint.push( firstContentfulPaint );
135
+ results.firstBlock.push( firstBlock );
136
+ }
113
137
  }
138
+ } );
139
+
140
+ it( 'Typing', async () => {
141
+ await page.waitForSelector( '.edit-site-visual-editor', {
142
+ timeout: 120000,
143
+ } );
144
+ await canvas().waitForSelector( '.wp-block', { timeout: 120000 } );
114
145
 
115
146
  // Measuring typing performance inside the post content.
116
147
  await canvas().waitForSelector(
@@ -121,7 +152,7 @@ describe( 'Site Editor Performance', () => {
121
152
  '[data-type="core/post-content"] [data-type="core/paragraph"]'
122
153
  );
123
154
  await insertBlock( 'Paragraph' );
124
- i = 200;
155
+ let i = 200;
125
156
  const traceFile = __dirname + '/trace.json';
126
157
  await page.tracing.start( {
127
158
  path: traceFile,
@@ -265,6 +265,7 @@ describe( 'Multi-entity save flow', () => {
265
265
  await visitSiteEditor( {
266
266
  postId: 'emptytheme//index',
267
267
  postType: 'wp_template',
268
+ path: '/templates/single',
268
269
  } );
269
270
 
270
271
  await enterEditMode();
@@ -304,6 +305,7 @@ describe( 'Multi-entity save flow', () => {
304
305
  await visitSiteEditor( {
305
306
  postId: 'emptytheme//index',
306
307
  postType: 'wp_template',
308
+ path: '/templates/single',
307
309
  } );
308
310
 
309
311
  await enterEditMode();
@@ -69,6 +69,7 @@ describe( 'Settings sidebar', () => {
69
69
  await visitSiteEditor( {
70
70
  postId: 'emptytheme//singular',
71
71
  postType: 'wp_template',
72
+ path: '/templates/single',
72
73
  } );
73
74
  await enterEditMode();
74
75
  const templateCardAfterNavigation = await getTemplateCard();
@@ -1,51 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`Heading can be created by prefixing existing content with number signs and a space 1`] = `
4
- "<!-- wp:heading {\\"level\\":4} -->
5
- <h4 class=\\"wp-block-heading\\">4</h4>
6
- <!-- /wp:heading -->"
7
- `;
8
-
9
- exports[`Heading can be created by prefixing number sign and a space 1`] = `
10
- "<!-- wp:heading {\\"level\\":3} -->
11
- <h3 class=\\"wp-block-heading\\">3</h3>
12
- <!-- /wp:heading -->"
13
- `;
14
-
15
- exports[`Heading should correctly apply named colors 1`] = `
16
- "<!-- wp:heading {\\"textColor\\":\\"luminous-vivid-orange\\"} -->
17
- <h2 class=\\"wp-block-heading has-luminous-vivid-orange-color has-text-color\\">Heading</h2>
18
- <!-- /wp:heading -->"
19
- `;
20
-
21
- exports[`Heading should create a paragraph block above when pressing enter at the start 1`] = `
22
- "<!-- wp:paragraph -->
23
- <p></p>
24
- <!-- /wp:paragraph -->
25
-
26
- <!-- wp:heading -->
27
- <h2 class=\\"wp-block-heading\\">a</h2>
28
- <!-- /wp:heading -->"
29
- `;
30
-
31
- exports[`Heading should create a paragraph block below when pressing enter at the end 1`] = `
32
- "<!-- wp:heading -->
33
- <h2 class=\\"wp-block-heading\\">a</h2>
34
- <!-- /wp:heading -->
35
-
36
- <!-- wp:paragraph -->
37
- <p></p>
38
- <!-- /wp:paragraph -->"
39
- `;
40
-
41
- exports[`Heading should not work with the list input rule 1`] = `
42
- "<!-- wp:heading -->
43
- <h2 class=\\"wp-block-heading\\">1. H</h2>
44
- <!-- /wp:heading -->"
45
- `;
46
-
47
- exports[`Heading should work with the format input rules 1`] = `
48
- "<!-- wp:heading -->
49
- <h2 class=\\"wp-block-heading\\"><code>code</code></h2>
50
- <!-- /wp:heading -->"
51
- `;
@@ -1,113 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import {
5
- clickBlockAppender,
6
- createNewPost,
7
- getEditedPostContent,
8
- pressKeyWithModifier,
9
- } from '@wordpress/e2e-test-utils';
10
-
11
- describe( 'Heading', () => {
12
- const COLOR_ITEM_SELECTOR =
13
- '.block-editor-panel-color-gradient-settings__dropdown';
14
- const CUSTOM_COLOR_BUTTON_X_SELECTOR = `.components-color-palette__custom-color`;
15
- const COLOR_INPUT_FIELD_SELECTOR =
16
- '.components-color-picker .components-input-control__input';
17
-
18
- beforeEach( async () => {
19
- await createNewPost();
20
- } );
21
-
22
- it( 'can be created by prefixing number sign and a space', async () => {
23
- await clickBlockAppender();
24
- await page.keyboard.type( '### 3' );
25
-
26
- expect( await getEditedPostContent() ).toMatchSnapshot();
27
- } );
28
-
29
- it( 'can be created by prefixing existing content with number signs and a space', async () => {
30
- await clickBlockAppender();
31
- await page.keyboard.type( '4' );
32
- await page.keyboard.press( 'ArrowLeft' );
33
- await page.keyboard.type( '#### ' );
34
-
35
- expect( await getEditedPostContent() ).toMatchSnapshot();
36
- } );
37
-
38
- it( 'should not work with the list input rule', async () => {
39
- await clickBlockAppender();
40
- await page.keyboard.type( '## 1. H' );
41
-
42
- expect( await getEditedPostContent() ).toMatchSnapshot();
43
- } );
44
-
45
- it( 'should work with the format input rules', async () => {
46
- await clickBlockAppender();
47
- await page.keyboard.type( '## `code`' );
48
-
49
- expect( await getEditedPostContent() ).toMatchSnapshot();
50
- } );
51
-
52
- it( 'should create a paragraph block above when pressing enter at the start', async () => {
53
- await page.keyboard.press( 'Enter' );
54
- await page.keyboard.type( '## a' );
55
- await page.keyboard.press( 'ArrowLeft' );
56
- await page.keyboard.press( 'Enter' );
57
-
58
- expect( await getEditedPostContent() ).toMatchSnapshot();
59
- } );
60
-
61
- it( 'should create a paragraph block below when pressing enter at the end', async () => {
62
- await page.keyboard.press( 'Enter' );
63
- await page.keyboard.type( '## a' );
64
- await page.keyboard.press( 'Enter' );
65
-
66
- expect( await getEditedPostContent() ).toMatchSnapshot();
67
- } );
68
-
69
- it( 'should correctly apply custom colors', async () => {
70
- await clickBlockAppender();
71
- await page.keyboard.type( '### Heading' );
72
-
73
- const textColorButton = await page.waitForSelector(
74
- COLOR_ITEM_SELECTOR
75
- );
76
- await textColorButton.click();
77
-
78
- const customTextColorButton = await page.waitForSelector(
79
- CUSTOM_COLOR_BUTTON_X_SELECTOR
80
- );
81
-
82
- await customTextColorButton.click();
83
- await page.waitForSelector( COLOR_INPUT_FIELD_SELECTOR );
84
- await page.click( COLOR_INPUT_FIELD_SELECTOR );
85
- await pressKeyWithModifier( 'primary', 'A' );
86
- await page.keyboard.type( '4b7f4d' );
87
- await page.keyboard.press( 'Enter' );
88
- expect( await getEditedPostContent() ).toMatchInlineSnapshot( `
89
- "<!-- wp:heading {\\"level\\":3,\\"style\\":{\\"color\\":{\\"text\\":\\"#4b7f4d\\"}}} -->
90
- <h3 class=\\"wp-block-heading has-text-color\\" style=\\"color:#4b7f4d\\">Heading</h3>
91
- <!-- /wp:heading -->"
92
- ` );
93
- } );
94
-
95
- it( 'should correctly apply named colors', async () => {
96
- await clickBlockAppender();
97
- await page.keyboard.type( '## Heading' );
98
-
99
- const textColorButton = await page.waitForSelector(
100
- COLOR_ITEM_SELECTOR
101
- );
102
- await textColorButton.click();
103
-
104
- const colorButtonSelector = `//button[@aria-label='Color: Luminous vivid orange']`;
105
- const [ colorButton ] = await page.$x( colorButtonSelector );
106
- await colorButton.click();
107
- await page.waitForXPath(
108
- `${ colorButtonSelector }[@aria-pressed='true']`
109
- );
110
- await page.click( 'h2[data-type="core/heading"]' );
111
- expect( await getEditedPostContent() ).toMatchSnapshot();
112
- } );
113
- } );
@@ -1,66 +0,0 @@
1
- /**
2
- * WordPress dependencies
3
- */
4
- import {
5
- activatePlugin,
6
- deactivatePlugin,
7
- createNewPost,
8
- insertBlock,
9
- publishPost,
10
- trashAllPosts,
11
- } from '@wordpress/e2e-test-utils';
12
-
13
- const createDemoPosts = async () => {
14
- await createNewPost( { postType: 'post', title: `Post 1` } );
15
- await publishPost();
16
- };
17
-
18
- describe( 'Query block', () => {
19
- beforeAll( async () => {
20
- await activatePlugin( 'gutenberg-test-query-block' );
21
- await createDemoPosts();
22
- } );
23
- afterAll( async () => {
24
- await trashAllPosts();
25
- await deactivatePlugin( 'gutenberg-test-query-block' );
26
- } );
27
- beforeEach( async () => {
28
- await createNewPost( { postType: 'page', title: `Query Page` } );
29
- } );
30
- afterEach( async () => {
31
- await trashAllPosts( 'page' );
32
- } );
33
- describe( 'Query block insertion', () => {
34
- it( 'List', async () => {
35
- await insertBlock( 'Query' );
36
- // Wait for the choose pattern button
37
- const choosePatternButton = await page.waitForSelector(
38
- 'div[data-type="core/query"] button.is-primary'
39
- );
40
- await choosePatternButton.click();
41
- // Wait for pattern blocks to be loaded.
42
- await page.waitForSelector(
43
- '.block-library-query-pattern__selection-content iframe[title="Editor canvas"]'
44
- );
45
- // Choose the standard pattern.
46
- const chosenPattern = await page.waitForSelector(
47
- '.block-editor-block-patterns-list__item[aria-label="Standard"]'
48
- );
49
- chosenPattern.click();
50
- // Wait for pattern setup to go away.
51
- await page.waitForSelector(
52
- '.block-library-query-pattern__selection-content',
53
- {
54
- hidden: true,
55
- }
56
- );
57
- /**
58
- * We can't use `getEditedPostContent` easily for now because
59
- * `query` makes used of `instanceId` so it's not very reliable.
60
- * This should be revisited.
61
- */
62
- await page.waitForSelector( '.wp-block-post-date' );
63
- await page.waitForSelector( '.wp-block-post-title' );
64
- } );
65
- } );
66
- } );