@wordpress/e2e-tests 6.3.3 → 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 +2 -0
- package/config/setup-performance-test.js +14 -7
- package/package.json +7 -7
- package/specs/editor/various/links.test.js +50 -16
- package/specs/editor/various/list-view.test.js +84 -0
- package/specs/performance/front-end-block-theme.test.js +47 -0
- package/specs/performance/front-end-classic-theme.test.js +49 -1
- package/specs/performance/post-editor.test.js +31 -16
- package/specs/performance/site-editor.test.js +69 -42
- package/specs/editor/blocks/__snapshots__/heading.test.js.snap +0 -51
- package/specs/editor/blocks/heading.test.js +0 -113
- package/specs/editor/blocks/query.test.js +0 -66
package/CHANGELOG.md
CHANGED
@@ -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
|
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
|
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
|
-
|
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
|
+
"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.
|
27
|
-
"@wordpress/jest-console": "^6.
|
28
|
-
"@wordpress/jest-puppeteer-axe": "^5.
|
29
|
-
"@wordpress/scripts": "^25.
|
30
|
-
"@wordpress/url": "^3.
|
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": "
|
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
|
-
//
|
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
|
-
|
600
|
-
|
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
|
-
|
640
|
+
const [ settingsToggle ] = await page.$x(
|
641
|
+
'//button[contains(@aria-label, "Toggle link settings")]'
|
642
|
+
);
|
643
|
+
await settingsToggle.click();
|
630
644
|
|
631
|
-
|
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
|
-
|
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
|
-
|
739
|
+
const [ settingsToggle ] = await page.$x(
|
740
|
+
'//button[contains(@aria-label, "Toggle link settings")]'
|
741
|
+
);
|
742
|
+
await settingsToggle.click();
|
719
743
|
|
720
|
-
|
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
|
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
|
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
|
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
|
-
|
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.
|
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
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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,41 +75,73 @@ describe( 'Site Editor Performance', () => {
|
|
80
75
|
}, html );
|
81
76
|
await saveDraft();
|
82
77
|
|
83
|
-
|
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
|
path: '/navigation/single',
|
91
94
|
} );
|
95
|
+
} );
|
96
|
+
|
97
|
+
it( 'Loading', async () => {
|
98
|
+
const editorURL = await page.url();
|
92
99
|
|
93
|
-
|
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;
|
94
108
|
|
95
109
|
// Measuring loading time.
|
96
110
|
while ( i-- ) {
|
97
|
-
await page.
|
111
|
+
await page.close();
|
112
|
+
page = await browser.newPage();
|
113
|
+
|
114
|
+
await page.goto( editorURL );
|
98
115
|
await page.waitForSelector( '.edit-site-visual-editor', {
|
99
116
|
timeout: 120000,
|
100
117
|
} );
|
101
118
|
await canvas().waitForSelector( '.wp-block', { timeout: 120000 } );
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
+
}
|
117
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 } );
|
118
145
|
|
119
146
|
// Measuring typing performance inside the post content.
|
120
147
|
await canvas().waitForSelector(
|
@@ -125,7 +152,7 @@ describe( 'Site Editor Performance', () => {
|
|
125
152
|
'[data-type="core/post-content"] [data-type="core/paragraph"]'
|
126
153
|
);
|
127
154
|
await insertBlock( 'Paragraph' );
|
128
|
-
i = 200;
|
155
|
+
let i = 200;
|
129
156
|
const traceFile = __dirname + '/trace.json';
|
130
157
|
await page.tracing.start( {
|
131
158
|
path: traceFile,
|
@@ -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
|
-
} );
|