@wordpress/e2e-test-utils-playwright 1.48.0 → 1.48.1
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/build/admin/create-new-post.js +31 -0
- package/build/admin/create-new-post.js.map +1 -0
- package/build/admin/edit-post.js +20 -0
- package/build/admin/edit-post.js.map +1 -0
- package/{src/admin/get-page-error.ts → build/admin/get-page-error.js} +9 -12
- package/build/admin/get-page-error.js.map +1 -0
- package/build/admin/index.js +40 -0
- package/build/admin/index.js.map +1 -0
- package/build/admin/visit-admin-page.js +32 -0
- package/build/admin/visit-admin-page.js.map +1 -0
- package/build/admin/visit-site-editor.js +45 -0
- package/build/admin/visit-site-editor.js.map +1 -0
- package/build/admin/wait-for-site-editor.js +41 -0
- package/build/admin/wait-for-site-editor.js.map +1 -0
- package/build/config.js +13 -0
- package/build/config.js.map +1 -0
- package/build/editor/click-block-options-menu-item.js +17 -0
- package/build/editor/click-block-options-menu-item.js.map +1 -0
- package/build/editor/click-block-toolbar-button.js +16 -0
- package/build/editor/click-block-toolbar-button.js.map +1 -0
- package/build/editor/get-blocks.js +45 -0
- package/build/editor/get-blocks.js.map +1 -0
- package/build/editor/get-edited-post-content.js +15 -0
- package/build/editor/get-edited-post-content.js.map +1 -0
- package/build/editor/index.js +75 -0
- package/build/editor/index.js.map +1 -0
- package/build/editor/insert-block.js +23 -0
- package/build/editor/insert-block.js.map +1 -0
- package/build/editor/open-document-settings-sidebar.js +27 -0
- package/build/editor/open-document-settings-sidebar.js.map +1 -0
- package/build/editor/preview.js +21 -0
- package/build/editor/preview.js.map +1 -0
- package/build/editor/publish-post.js +45 -0
- package/build/editor/publish-post.js.map +1 -0
- package/build/editor/save-draft.js +18 -0
- package/build/editor/save-draft.js.map +1 -0
- package/build/editor/select-blocks.js +28 -0
- package/build/editor/select-blocks.js.map +1 -0
- package/build/editor/set-content.js +17 -0
- package/build/editor/set-content.js.map +1 -0
- package/build/editor/set-is-fixed-toolbar.js +18 -0
- package/build/editor/set-is-fixed-toolbar.js.map +1 -0
- package/build/editor/set-preferences.js +21 -0
- package/build/editor/set-preferences.js.map +1 -0
- package/build/editor/show-block-toolbar.js +19 -0
- package/build/editor/show-block-toolbar.js.map +1 -0
- package/build/editor/site-editor.js +44 -0
- package/build/editor/site-editor.js.map +1 -0
- package/build/editor/switch-editor-tool.js +33 -0
- package/build/editor/switch-editor-tool.js.map +1 -0
- package/build/editor/switch-to-legacy-canvas.js +18 -0
- package/build/editor/switch-to-legacy-canvas.js.map +1 -0
- package/build/editor/transform-block-to.js +24 -0
- package/build/editor/transform-block-to.js.map +1 -0
- package/build/index.js +19 -0
- package/build/index.js.map +1 -0
- package/build/lighthouse/index.js +61 -0
- package/build/lighthouse/index.js.map +1 -0
- package/build/metrics/index.js +314 -0
- package/build/metrics/index.js.map +1 -0
- package/build/page-utils/drag-files.js +119 -0
- package/build/page-utils/drag-files.js.map +1 -0
- package/build/page-utils/emulate-network-conditions.js +71 -0
- package/build/page-utils/emulate-network-conditions.js.map +1 -0
- package/build/page-utils/index.js +37 -0
- package/build/page-utils/index.js.map +1 -0
- package/build/page-utils/is-current-url.js +21 -0
- package/build/page-utils/is-current-url.js.map +1 -0
- package/build/page-utils/keycodes.js +41 -0
- package/build/page-utils/keycodes.js.map +1 -0
- package/build/page-utils/press-keys.js +141 -0
- package/build/page-utils/press-keys.js.map +1 -0
- package/{src → build}/page-utils/set-browser-viewport.js +12 -14
- package/build/page-utils/set-browser-viewport.js.map +1 -0
- package/build/request-utils/blocks.js +40 -0
- package/build/request-utils/blocks.js.map +1 -0
- package/build/request-utils/comments.js +52 -0
- package/build/request-utils/comments.js.map +1 -0
- package/build/request-utils/gutenberg-experiments.js +47 -0
- package/build/request-utils/gutenberg-experiments.js.map +1 -0
- package/build/request-utils/index.js +196 -0
- package/build/request-utils/index.js.map +1 -0
- package/build/request-utils/login.js +21 -0
- package/build/request-utils/login.js.map +1 -0
- package/build/request-utils/media.js +106 -0
- package/build/request-utils/media.js.map +1 -0
- package/build/request-utils/menus.js +116 -0
- package/build/request-utils/menus.js.map +1 -0
- package/build/request-utils/pages.js +53 -0
- package/build/request-utils/pages.js.map +1 -0
- package/build/request-utils/patterns.js +27 -0
- package/build/request-utils/patterns.js.map +1 -0
- package/build/request-utils/plugins.js +85 -0
- package/build/request-utils/plugins.js.map +1 -0
- package/build/request-utils/posts.js +42 -0
- package/build/request-utils/posts.js.map +1 -0
- package/build/request-utils/preferences.js +54 -0
- package/build/request-utils/preferences.js.map +1 -0
- package/{src/request-utils/records.ts → build/request-utils/records.js} +10 -15
- package/build/request-utils/records.js.map +1 -0
- package/build/request-utils/rest.js +181 -0
- package/build/request-utils/rest.js.map +1 -0
- package/build/request-utils/site-settings.js +33 -0
- package/build/request-utils/site-settings.js.map +1 -0
- package/build/request-utils/templates.js +54 -0
- package/build/request-utils/templates.js.map +1 -0
- package/build/request-utils/themes.js +69 -0
- package/build/request-utils/themes.js.map +1 -0
- package/build/request-utils/users.js +81 -0
- package/build/request-utils/users.js.map +1 -0
- package/build/request-utils/widgets.js +61 -0
- package/build/request-utils/widgets.js.map +1 -0
- package/build/test.js +189 -0
- package/build/test.js.map +1 -0
- package/build/types.js +3 -0
- package/build/types.js.map +1 -0
- package/build-types/admin/index.d.ts.map +1 -1
- package/build-types/config.d.ts.map +1 -1
- package/build-types/editor/index.d.ts.map +1 -1
- package/build-types/lighthouse/index.d.ts.map +1 -1
- package/build-types/metrics/index.d.ts.map +1 -1
- package/build-types/page-utils/index.d.ts.map +1 -1
- package/build-types/page-utils/press-keys.d.ts +1 -1
- package/build-types/page-utils/set-browser-viewport.d.ts +22 -12
- package/build-types/page-utils/set-browser-viewport.d.ts.map +1 -1
- package/build-types/request-utils/index.d.ts +2 -2
- package/build-types/request-utils/index.d.ts.map +1 -1
- package/build-types/request-utils/pages.d.ts +1 -1
- package/build-types/request-utils/pages.d.ts.map +1 -1
- package/build-types/request-utils/widgets.d.ts +2 -2
- package/build-types/request-utils/widgets.d.ts.map +1 -1
- package/build-types/types.d.ts.map +1 -1
- package/package.json +8 -5
- package/src/admin/create-new-post.ts +0 -47
- package/src/admin/edit-post.ts +0 -24
- package/src/admin/index.ts +0 -52
- package/src/admin/visit-admin-page.ts +0 -43
- package/src/admin/visit-site-editor.ts +0 -62
- package/src/admin/wait-for-site-editor.ts +0 -52
- package/src/config.ts +0 -12
- package/src/editor/click-block-options-menu-item.ts +0 -18
- package/src/editor/click-block-toolbar-button.ts +0 -21
- package/src/editor/get-blocks.ts +0 -75
- package/src/editor/get-edited-post-content.ts +0 -19
- package/src/editor/index.ts +0 -95
- package/src/editor/insert-block.ts +0 -54
- package/src/editor/open-document-settings-sidebar.ts +0 -31
- package/src/editor/preview.ts +0 -32
- package/src/editor/publish-post.ts +0 -51
- package/src/editor/save-draft.ts +0 -20
- package/src/editor/select-blocks.ts +0 -48
- package/src/editor/set-content.ts +0 -24
- package/src/editor/set-is-fixed-toolbar.ts +0 -20
- package/src/editor/set-preferences.ts +0 -37
- package/src/editor/show-block-toolbar.ts +0 -20
- package/src/editor/site-editor.ts +0 -55
- package/src/editor/switch-editor-tool.ts +0 -34
- package/src/editor/switch-to-legacy-canvas.ts +0 -20
- package/src/editor/transform-block-to.ts +0 -34
- package/src/index.ts +0 -8
- package/src/lighthouse/index.ts +0 -75
- package/src/metrics/index.ts +0 -441
- package/src/page-utils/drag-files.ts +0 -173
- package/src/page-utils/emulate-network-conditions.ts +0 -101
- package/src/page-utils/index.ts +0 -54
- package/src/page-utils/is-current-url.ts +0 -20
- package/src/page-utils/keycodes.ts +0 -48
- package/src/page-utils/press-keys.ts +0 -195
- package/src/request-utils/blocks.ts +0 -58
- package/src/request-utils/comments.ts +0 -80
- package/src/request-utils/gutenberg-experiments.ts +0 -62
- package/src/request-utils/index.ts +0 -222
- package/src/request-utils/login.ts +0 -34
- package/src/request-utils/media.ts +0 -102
- package/src/request-utils/menus.ts +0 -145
- package/src/request-utils/pages.ts +0 -75
- package/src/request-utils/patterns.ts +0 -31
- package/src/request-utils/plugins.ts +0 -103
- package/src/request-utils/posts.ts +0 -69
- package/src/request-utils/preferences.ts +0 -63
- package/src/request-utils/rest.ts +0 -222
- package/src/request-utils/site-settings.ts +0 -58
- package/src/request-utils/templates.ts +0 -83
- package/src/request-utils/themes.ts +0 -110
- package/src/request-utils/users.ts +0 -125
- package/src/request-utils/widgets.js +0 -68
- package/src/test.ts +0 -204
- package/src/types.ts +0 -13
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* External dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { readFile } from 'fs/promises';
|
|
5
|
-
import { basename } from 'path';
|
|
6
|
-
import { getType } from 'mime';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Internal dependencies
|
|
10
|
-
*/
|
|
11
|
-
import type { PageUtils } from './index';
|
|
12
|
-
import type { Locator } from '@playwright/test';
|
|
13
|
-
|
|
14
|
-
type FileObject = {
|
|
15
|
-
name: string;
|
|
16
|
-
mimeType?: string;
|
|
17
|
-
buffer: Buffer;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
type Options = {
|
|
21
|
-
position?: { x: number; y: number };
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Simulate dragging files from outside the current page.
|
|
26
|
-
*
|
|
27
|
-
* @param this
|
|
28
|
-
* @param files The files to be dragged.
|
|
29
|
-
* @return The methods of the drag operation.
|
|
30
|
-
*/
|
|
31
|
-
async function dragFiles(
|
|
32
|
-
this: PageUtils,
|
|
33
|
-
files: string | string[] | FileObject | FileObject[]
|
|
34
|
-
) {
|
|
35
|
-
const filesList = Array.isArray( files ) ? files : [ files ];
|
|
36
|
-
const fileObjects = await Promise.all(
|
|
37
|
-
filesList.map( async ( filePathOrObject ) => {
|
|
38
|
-
if ( typeof filePathOrObject !== 'string' ) {
|
|
39
|
-
return {
|
|
40
|
-
name: filePathOrObject.name,
|
|
41
|
-
mimeType:
|
|
42
|
-
filePathOrObject.mimeType ||
|
|
43
|
-
getType( filePathOrObject.name ),
|
|
44
|
-
base64: filePathOrObject.buffer.toString( 'base64' ),
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
const base64 = await readFile( filePathOrObject, 'base64' );
|
|
48
|
-
const name = basename( filePathOrObject );
|
|
49
|
-
return {
|
|
50
|
-
name,
|
|
51
|
-
mimeType: getType( filePathOrObject ),
|
|
52
|
-
base64,
|
|
53
|
-
};
|
|
54
|
-
} )
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
// CDP doesn't actually support dragging files, this is only a _good enough_
|
|
58
|
-
// dummy data so that it will correctly send the relevant events.
|
|
59
|
-
const dragData = {
|
|
60
|
-
items: fileObjects.map( ( fileObject ) => ( {
|
|
61
|
-
mimeType: fileObject.mimeType ?? 'File',
|
|
62
|
-
data: fileObject.base64,
|
|
63
|
-
} ) ),
|
|
64
|
-
files: fileObjects.map( ( fileObject ) => fileObject.name ),
|
|
65
|
-
// Copy = 1, Link = 2, Move = 16.
|
|
66
|
-
dragOperationsMask: 1,
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const cdpSession = await this.context.newCDPSession( this.page );
|
|
70
|
-
|
|
71
|
-
const position = {
|
|
72
|
-
x: 0,
|
|
73
|
-
y: 0,
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
return {
|
|
77
|
-
/**
|
|
78
|
-
* Drag the files over an element (fires `dragenter` and `dragover` events).
|
|
79
|
-
*
|
|
80
|
-
* @param selectorOrLocator A selector or a locator to search for an element.
|
|
81
|
-
* @param options The optional options.
|
|
82
|
-
* @param options.position A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the element.
|
|
83
|
-
*/
|
|
84
|
-
dragOver: async (
|
|
85
|
-
selectorOrLocator: string | Locator,
|
|
86
|
-
options: Options = {}
|
|
87
|
-
) => {
|
|
88
|
-
const locator =
|
|
89
|
-
typeof selectorOrLocator === 'string'
|
|
90
|
-
? this.page.locator( selectorOrLocator )
|
|
91
|
-
: selectorOrLocator;
|
|
92
|
-
const boundingBox = await locator.boundingBox();
|
|
93
|
-
|
|
94
|
-
if ( ! boundingBox ) {
|
|
95
|
-
throw new Error(
|
|
96
|
-
'Cannot find the element or the element is not visible on the viewport.'
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
position.x =
|
|
101
|
-
boundingBox.x +
|
|
102
|
-
( options.position?.x ?? boundingBox.width / 2 );
|
|
103
|
-
position.y =
|
|
104
|
-
boundingBox.y +
|
|
105
|
-
( options.position?.y ?? boundingBox.height / 2 );
|
|
106
|
-
|
|
107
|
-
await cdpSession.send( 'Input.dispatchDragEvent', {
|
|
108
|
-
type: 'dragEnter',
|
|
109
|
-
...position,
|
|
110
|
-
data: dragData,
|
|
111
|
-
} );
|
|
112
|
-
await cdpSession.send( 'Input.dispatchDragEvent', {
|
|
113
|
-
type: 'dragOver',
|
|
114
|
-
...position,
|
|
115
|
-
data: dragData,
|
|
116
|
-
} );
|
|
117
|
-
},
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Drop the files at the current position.
|
|
121
|
-
*/
|
|
122
|
-
drop: async () => {
|
|
123
|
-
const topMostElement = await this.page.evaluateHandle(
|
|
124
|
-
( { x, y } ) => {
|
|
125
|
-
const element = document.elementFromPoint( x, y );
|
|
126
|
-
if ( element instanceof HTMLIFrameElement ) {
|
|
127
|
-
const offsetBox = element.getBoundingClientRect();
|
|
128
|
-
return element.contentDocument!.elementFromPoint(
|
|
129
|
-
x - offsetBox.x,
|
|
130
|
-
y - offsetBox.y
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
return element;
|
|
134
|
-
},
|
|
135
|
-
position
|
|
136
|
-
);
|
|
137
|
-
const elementHandle = topMostElement.asElement();
|
|
138
|
-
|
|
139
|
-
if ( ! elementHandle ) {
|
|
140
|
-
throw new Error( 'Element not found.' );
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const dataTransfer = await elementHandle.evaluateHandle(
|
|
144
|
-
async ( _node, _fileObjects ) => {
|
|
145
|
-
const dt = new DataTransfer();
|
|
146
|
-
const fileInstances = await Promise.all(
|
|
147
|
-
_fileObjects.map( async ( fileObject: any ) => {
|
|
148
|
-
const blob = await fetch(
|
|
149
|
-
`data:${ fileObject.mimeType };base64,${ fileObject.base64 }`
|
|
150
|
-
).then( ( res ) => res.blob() );
|
|
151
|
-
return new File( [ blob ], fileObject.name, {
|
|
152
|
-
type: fileObject.mimeType ?? undefined,
|
|
153
|
-
} );
|
|
154
|
-
} )
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
fileInstances.forEach( ( file ) => {
|
|
158
|
-
dt.items.add( file );
|
|
159
|
-
} );
|
|
160
|
-
|
|
161
|
-
return dt;
|
|
162
|
-
},
|
|
163
|
-
fileObjects
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
await elementHandle.dispatchEvent( 'drop', { dataTransfer } );
|
|
167
|
-
|
|
168
|
-
await cdpSession.detach();
|
|
169
|
-
},
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
export { dragFiles };
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Internal dependencies
|
|
3
|
-
*/
|
|
4
|
-
import type { PageUtils } from './';
|
|
5
|
-
|
|
6
|
-
interface NetworkConditions {
|
|
7
|
-
/**
|
|
8
|
-
* True to emulate internet disconnection.
|
|
9
|
-
*/
|
|
10
|
-
offline: boolean;
|
|
11
|
-
/**
|
|
12
|
-
* Minimum latency from request sent to response headers received (ms).
|
|
13
|
-
*/
|
|
14
|
-
latency: number;
|
|
15
|
-
/**
|
|
16
|
-
* Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.
|
|
17
|
-
*/
|
|
18
|
-
downloadThroughput: number;
|
|
19
|
-
/**
|
|
20
|
-
* Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.
|
|
21
|
-
*/
|
|
22
|
-
uploadThroughput: number;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Defaults from https://github.com/puppeteer/puppeteer/blob/401355610874beac23a51dcb75739a4bb4191a2b/packages/puppeteer-core/src/cdp/PredefinedNetworkConditions.ts.
|
|
26
|
-
const PredefinedNetworkConditions: Record< string, NetworkConditions > = {
|
|
27
|
-
// Generally aligned with DevTools
|
|
28
|
-
// https://source.chromium.org/chromium/chromium/src/+/main:third_party/devtools-frontend/src/front_end/core/sdk/NetworkManager.ts;l=398;drc=225e1240f522ca684473f541ae6dae6cd766dd33.
|
|
29
|
-
'Slow 3G': {
|
|
30
|
-
offline: false,
|
|
31
|
-
// ~500Kbps down
|
|
32
|
-
downloadThroughput: ( ( 500 * 1000 ) / 8 ) * 0.8,
|
|
33
|
-
// ~500Kbps up
|
|
34
|
-
uploadThroughput: ( ( 500 * 1000 ) / 8 ) * 0.8,
|
|
35
|
-
// 400ms RTT
|
|
36
|
-
latency: 400 * 5,
|
|
37
|
-
},
|
|
38
|
-
'Fast 3G': {
|
|
39
|
-
offline: false,
|
|
40
|
-
// ~1.6 Mbps down
|
|
41
|
-
downloadThroughput: ( ( 1.6 * 1000 * 1000 ) / 8 ) * 0.9,
|
|
42
|
-
// ~0.75 Mbps up
|
|
43
|
-
uploadThroughput: ( ( 750 * 1000 ) / 8 ) * 0.9,
|
|
44
|
-
// 150ms RTT
|
|
45
|
-
latency: 150 * 3.75,
|
|
46
|
-
},
|
|
47
|
-
// alias to Fast 3G to align with Lighthouse (crbug.com/342406608)
|
|
48
|
-
// and DevTools (crbug.com/342406608),
|
|
49
|
-
'Slow 4G': {
|
|
50
|
-
offline: false,
|
|
51
|
-
// ~1.6 Mbps down
|
|
52
|
-
downloadThroughput: ( ( 1.6 * 1000 * 1000 ) / 8 ) * 0.9,
|
|
53
|
-
// ~0.75 Mbps up
|
|
54
|
-
uploadThroughput: ( ( 750 * 1000 ) / 8 ) * 0.9,
|
|
55
|
-
// 150ms RTT
|
|
56
|
-
latency: 150 * 3.75,
|
|
57
|
-
},
|
|
58
|
-
'Fast 4G': {
|
|
59
|
-
offline: false,
|
|
60
|
-
// 9 Mbps down
|
|
61
|
-
downloadThroughput: ( ( 9 * 1000 * 1000 ) / 8 ) * 0.9,
|
|
62
|
-
// 1.5 Mbps up
|
|
63
|
-
uploadThroughput: ( ( 1.5 * 1000 * 1000 ) / 8 ) * 0.9,
|
|
64
|
-
// 60ms RTT
|
|
65
|
-
latency: 60 * 2.75,
|
|
66
|
-
},
|
|
67
|
-
/**
|
|
68
|
-
* Network conditions used for desktop in Lighthouse/PSI.
|
|
69
|
-
*
|
|
70
|
-
* 10,240 kb/s throughput with 40 ms TCP RTT.
|
|
71
|
-
*
|
|
72
|
-
* @see https://github.com/paulirish/lighthouse/blob/f0855904aaffaecf3089169449646960782d7e92/core/config/constants.js#L40-L49
|
|
73
|
-
* @see https://docs.google.com/document/d/1-p4HSp42REEA5-jCBVB6PqQcVhI1nQIblBCNKhPJUXg/edit?tab=t.0#heading=h.jsap7yf4phk6
|
|
74
|
-
*/
|
|
75
|
-
Broadband: {
|
|
76
|
-
offline: false,
|
|
77
|
-
downloadThroughput: ( 10240 * 1000 ) / 8,
|
|
78
|
-
uploadThroughput: ( 10240 * 1000 ) / 8,
|
|
79
|
-
latency: 40,
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
export async function emulateNetworkConditions(
|
|
84
|
-
this: PageUtils,
|
|
85
|
-
condition: keyof typeof PredefinedNetworkConditions | NetworkConditions
|
|
86
|
-
) {
|
|
87
|
-
if ( 'chromium' !== this.browserName ) {
|
|
88
|
-
throw new Error(
|
|
89
|
-
'CDP sessions are only supported on Chromium-based browsers'
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const session = await this.page.context().newCDPSession( this.page );
|
|
94
|
-
await session.send(
|
|
95
|
-
'Network.emulateNetworkConditions',
|
|
96
|
-
'string' === typeof condition
|
|
97
|
-
? PredefinedNetworkConditions[ condition ]
|
|
98
|
-
: condition
|
|
99
|
-
);
|
|
100
|
-
await session.detach();
|
|
101
|
-
}
|
package/src/page-utils/index.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* External dependencies
|
|
3
|
-
*/
|
|
4
|
-
import type {
|
|
5
|
-
Browser,
|
|
6
|
-
Page,
|
|
7
|
-
BrowserContext,
|
|
8
|
-
PlaywrightWorkerOptions,
|
|
9
|
-
} from '@playwright/test';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Internal dependencies
|
|
13
|
-
*/
|
|
14
|
-
import { dragFiles } from './drag-files';
|
|
15
|
-
import { isCurrentURL } from './is-current-url';
|
|
16
|
-
import { setClipboardData, pressKeys } from './press-keys';
|
|
17
|
-
import { setBrowserViewport } from './set-browser-viewport';
|
|
18
|
-
import { emulateNetworkConditions } from './emulate-network-conditions';
|
|
19
|
-
|
|
20
|
-
type PageUtilConstructorParams = {
|
|
21
|
-
page: Page;
|
|
22
|
-
browserName: PlaywrightWorkerOptions[ 'browserName' ];
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
class PageUtils {
|
|
26
|
-
browser: Browser;
|
|
27
|
-
page: Page;
|
|
28
|
-
context: BrowserContext;
|
|
29
|
-
browserName: PlaywrightWorkerOptions[ 'browserName' ];
|
|
30
|
-
|
|
31
|
-
constructor( { page, browserName }: PageUtilConstructorParams ) {
|
|
32
|
-
this.page = page;
|
|
33
|
-
this.context = page.context();
|
|
34
|
-
this.browser = this.context.browser()!;
|
|
35
|
-
this.browserName = browserName;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** @borrows dragFiles as this.dragFiles */
|
|
39
|
-
dragFiles: typeof dragFiles = dragFiles.bind( this );
|
|
40
|
-
/** @borrows isCurrentURL as this.isCurrentURL */
|
|
41
|
-
isCurrentURL: typeof isCurrentURL = isCurrentURL.bind( this );
|
|
42
|
-
/** @borrows pressKeys as this.pressKeys */
|
|
43
|
-
pressKeys: typeof pressKeys = pressKeys.bind( this );
|
|
44
|
-
/** @borrows setBrowserViewport as this.setBrowserViewport */
|
|
45
|
-
setBrowserViewport: typeof setBrowserViewport =
|
|
46
|
-
setBrowserViewport.bind( this );
|
|
47
|
-
/** @borrows setClipboardData as this.setClipboardData */
|
|
48
|
-
setClipboardData: typeof setClipboardData = setClipboardData.bind( this );
|
|
49
|
-
/** @borrows emulateNetworkConditions as this.emulateNetworkConditions */
|
|
50
|
-
emulateNetworkConditions: typeof emulateNetworkConditions =
|
|
51
|
-
emulateNetworkConditions.bind( this );
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export { PageUtils };
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Internal dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { WP_BASE_URL } from '../config';
|
|
5
|
-
import type { PageUtils } from './';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Checks if current path of the URL matches the provided path.
|
|
9
|
-
*
|
|
10
|
-
* @param this
|
|
11
|
-
* @param path String to be serialized as pathname.
|
|
12
|
-
*
|
|
13
|
-
* @return Boolean represents whether current URL is or not a WordPress path.
|
|
14
|
-
*/
|
|
15
|
-
export function isCurrentURL( this: PageUtils, path: string ) {
|
|
16
|
-
const currentURL = new URL( this.page.url() );
|
|
17
|
-
const expectedURL = new URL( path, WP_BASE_URL );
|
|
18
|
-
|
|
19
|
-
return expectedURL.pathname === currentURL.pathname;
|
|
20
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This filed is partially copied from @wordpress/keycodes to keep the package
|
|
3
|
-
* (internal-)dependencies free.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Keycode for ALT key.
|
|
8
|
-
*/
|
|
9
|
-
export const ALT = 'alt';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Keycode for CTRL key.
|
|
13
|
-
*/
|
|
14
|
-
export const CTRL = 'ctrl';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Keycode for COMMAND key.
|
|
18
|
-
*/
|
|
19
|
-
export const COMMAND = 'meta';
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Keycode for SHIFT key.
|
|
23
|
-
*/
|
|
24
|
-
export const SHIFT = 'shift';
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Object that contains functions that return the available modifier
|
|
28
|
-
* depending on platform.
|
|
29
|
-
*/
|
|
30
|
-
export const modifiers: Record<
|
|
31
|
-
string,
|
|
32
|
-
( _isApple: () => boolean ) => string[]
|
|
33
|
-
> = {
|
|
34
|
-
primary: ( _isApple ) => ( _isApple() ? [ COMMAND ] : [ CTRL ] ),
|
|
35
|
-
primaryShift: ( _isApple ) =>
|
|
36
|
-
_isApple() ? [ SHIFT, COMMAND ] : [ CTRL, SHIFT ],
|
|
37
|
-
primaryAlt: ( _isApple ) =>
|
|
38
|
-
_isApple() ? [ ALT, COMMAND ] : [ CTRL, ALT ],
|
|
39
|
-
secondary: ( _isApple ) =>
|
|
40
|
-
_isApple() ? [ SHIFT, ALT, COMMAND ] : [ CTRL, SHIFT, ALT ],
|
|
41
|
-
access: ( _isApple ) => ( _isApple() ? [ CTRL, ALT ] : [ SHIFT, ALT ] ),
|
|
42
|
-
ctrl: () => [ CTRL ],
|
|
43
|
-
alt: () => [ ALT ],
|
|
44
|
-
ctrlShift: () => [ CTRL, SHIFT ],
|
|
45
|
-
shift: () => [ SHIFT ],
|
|
46
|
-
shiftAlt: () => [ SHIFT, ALT ],
|
|
47
|
-
undefined: () => [],
|
|
48
|
-
};
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* External dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { capitalCase } from 'change-case';
|
|
5
|
-
import type { Page } from '@playwright/test';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Internal dependencies
|
|
9
|
-
*/
|
|
10
|
-
import type { PageUtils } from './';
|
|
11
|
-
import { modifiers as baseModifiers, SHIFT, ALT, CTRL } from './keycodes';
|
|
12
|
-
|
|
13
|
-
let clipboardDataHolder: {
|
|
14
|
-
'text/plain': string;
|
|
15
|
-
'text/html': string;
|
|
16
|
-
'rich-text': string;
|
|
17
|
-
} = {
|
|
18
|
-
'text/plain': '',
|
|
19
|
-
'text/html': '',
|
|
20
|
-
'rich-text': '',
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Sets the clipboard data that can be pasted with
|
|
25
|
-
* `pressKeys( 'primary+v' )`.
|
|
26
|
-
*
|
|
27
|
-
* @param clipboardData
|
|
28
|
-
* @param clipboardData.plainText
|
|
29
|
-
* @param clipboardData.html
|
|
30
|
-
*/
|
|
31
|
-
export function setClipboardData(
|
|
32
|
-
this: PageUtils,
|
|
33
|
-
{ plainText = '', html = '' }
|
|
34
|
-
) {
|
|
35
|
-
clipboardDataHolder = {
|
|
36
|
-
'text/plain': plainText,
|
|
37
|
-
'text/html': html,
|
|
38
|
-
'rich-text': '',
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async function emulateClipboard( page: Page, type: 'copy' | 'cut' | 'paste' ) {
|
|
43
|
-
const output = await page.evaluate(
|
|
44
|
-
( [ _type, _clipboardData ] ) => {
|
|
45
|
-
const canvasDoc =
|
|
46
|
-
// @ts-ignore
|
|
47
|
-
document.activeElement?.contentDocument ?? document;
|
|
48
|
-
const event = new ClipboardEvent( _type, {
|
|
49
|
-
bubbles: true,
|
|
50
|
-
cancelable: true,
|
|
51
|
-
clipboardData: new DataTransfer(),
|
|
52
|
-
} );
|
|
53
|
-
|
|
54
|
-
if ( ! event.clipboardData ) {
|
|
55
|
-
throw new Error( 'ClipboardEvent.clipboardData is null' );
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if ( _type === 'paste' ) {
|
|
59
|
-
event.clipboardData.setData(
|
|
60
|
-
'text/plain',
|
|
61
|
-
_clipboardData[ 'text/plain' ]
|
|
62
|
-
);
|
|
63
|
-
event.clipboardData.setData(
|
|
64
|
-
'text/html',
|
|
65
|
-
_clipboardData[ 'text/html' ]
|
|
66
|
-
);
|
|
67
|
-
event.clipboardData.setData(
|
|
68
|
-
'rich-text',
|
|
69
|
-
_clipboardData[ 'rich-text' ]
|
|
70
|
-
);
|
|
71
|
-
} else {
|
|
72
|
-
const selection = canvasDoc.defaultView.getSelection()!;
|
|
73
|
-
const plainText = selection.toString();
|
|
74
|
-
let html = plainText;
|
|
75
|
-
if ( selection.rangeCount ) {
|
|
76
|
-
const range = selection.getRangeAt( 0 );
|
|
77
|
-
const fragment = range.cloneContents();
|
|
78
|
-
html = Array.from( fragment.childNodes )
|
|
79
|
-
.map(
|
|
80
|
-
( node ) =>
|
|
81
|
-
( node as Element ).outerHTML ??
|
|
82
|
-
( node as Element ).nodeValue
|
|
83
|
-
)
|
|
84
|
-
.join( '' );
|
|
85
|
-
}
|
|
86
|
-
event.clipboardData.setData( 'text/plain', plainText );
|
|
87
|
-
event.clipboardData.setData( 'text/html', html );
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
canvasDoc.activeElement.dispatchEvent( event );
|
|
91
|
-
|
|
92
|
-
if ( _type === 'paste' ) {
|
|
93
|
-
return event.defaultPrevented;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return {
|
|
97
|
-
'text/plain': event.clipboardData.getData( 'text/plain' ),
|
|
98
|
-
'text/html': event.clipboardData.getData( 'text/html' ),
|
|
99
|
-
'rich-text': event.clipboardData.getData( 'rich-text' ),
|
|
100
|
-
};
|
|
101
|
-
},
|
|
102
|
-
[ type, clipboardDataHolder ] as const
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
if ( typeof output === 'object' ) {
|
|
106
|
-
clipboardDataHolder = output;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if ( output === false ) {
|
|
110
|
-
// Emulate paste by typing the clipboard content, which works across all
|
|
111
|
-
// elements and documents (keyboard.type does uses the nested active
|
|
112
|
-
// element automatically).
|
|
113
|
-
await page.keyboard.type( clipboardDataHolder[ 'text/plain' ] );
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const isAppleOS = () => process.platform === 'darwin';
|
|
118
|
-
|
|
119
|
-
const isWebkit = ( page: Page ) =>
|
|
120
|
-
page.context().browser()!.browserType().name() === 'webkit';
|
|
121
|
-
|
|
122
|
-
const browserCache = new WeakMap();
|
|
123
|
-
const getHasNaturalTabNavigation = async ( page: Page ) => {
|
|
124
|
-
if ( ! isAppleOS() || ! isWebkit( page ) ) {
|
|
125
|
-
return true;
|
|
126
|
-
}
|
|
127
|
-
if ( browserCache.has( page.context().browser()! ) ) {
|
|
128
|
-
return browserCache.get( page.context().browser()! );
|
|
129
|
-
}
|
|
130
|
-
const testPage = await page.context().newPage();
|
|
131
|
-
await testPage.setContent( `<button>1</button><button>2</button>` );
|
|
132
|
-
await testPage.getByText( '1' ).focus();
|
|
133
|
-
await testPage.keyboard.press( 'Tab' );
|
|
134
|
-
const featureDetected = await testPage
|
|
135
|
-
.getByText( '2' )
|
|
136
|
-
.evaluate( ( node ) => node === document.activeElement );
|
|
137
|
-
browserCache.set( page.context().browser()!, featureDetected );
|
|
138
|
-
await testPage.close();
|
|
139
|
-
return featureDetected;
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
type Options = {
|
|
143
|
-
times?: number;
|
|
144
|
-
delay?: number;
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
const modifiers = {
|
|
148
|
-
...baseModifiers,
|
|
149
|
-
shiftAlt: ( _isApple: () => boolean ) =>
|
|
150
|
-
_isApple() ? [ SHIFT, ALT ] : [ SHIFT, CTRL ],
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
export async function pressKeys(
|
|
154
|
-
this: PageUtils,
|
|
155
|
-
key: string,
|
|
156
|
-
{ times, ...pressOptions }: Options = {}
|
|
157
|
-
) {
|
|
158
|
-
const hasNaturalTabNavigation = await getHasNaturalTabNavigation(
|
|
159
|
-
this.page
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
let command: () => Promise< void >;
|
|
163
|
-
|
|
164
|
-
if ( key.toLowerCase() === 'primary+c' ) {
|
|
165
|
-
command = () => emulateClipboard( this.page, 'copy' );
|
|
166
|
-
} else if ( key.toLowerCase() === 'primary+x' ) {
|
|
167
|
-
command = () => emulateClipboard( this.page, 'cut' );
|
|
168
|
-
} else if ( key.toLowerCase() === 'primary+v' ) {
|
|
169
|
-
command = () => emulateClipboard( this.page, 'paste' );
|
|
170
|
-
} else {
|
|
171
|
-
const keys = key.split( '+' ).flatMap( ( keyCode ) => {
|
|
172
|
-
if ( Object.prototype.hasOwnProperty.call( modifiers, keyCode ) ) {
|
|
173
|
-
return modifiers[ keyCode as keyof typeof modifiers ](
|
|
174
|
-
isAppleOS
|
|
175
|
-
).map( ( modifier ) =>
|
|
176
|
-
modifier === CTRL ? 'Control' : capitalCase( modifier )
|
|
177
|
-
);
|
|
178
|
-
} else if ( keyCode === 'Tab' && ! hasNaturalTabNavigation ) {
|
|
179
|
-
return [ 'Alt', 'Tab' ];
|
|
180
|
-
}
|
|
181
|
-
return keyCode;
|
|
182
|
-
} );
|
|
183
|
-
const normalizedKeys = keys.join( '+' );
|
|
184
|
-
command = () => this.page.keyboard.press( normalizedKeys );
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
times = times ?? 1;
|
|
188
|
-
for ( let i = 0; i < times; i += 1 ) {
|
|
189
|
-
await command();
|
|
190
|
-
|
|
191
|
-
if ( times > 1 && pressOptions.delay ) {
|
|
192
|
-
await this.page.waitForTimeout( pressOptions.delay );
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Internal dependencies
|
|
3
|
-
*/
|
|
4
|
-
import type { RequestUtils } from './index';
|
|
5
|
-
|
|
6
|
-
type CreateBlockPayload = {
|
|
7
|
-
date?: string;
|
|
8
|
-
date_gmt?: string;
|
|
9
|
-
slug?: string;
|
|
10
|
-
title: string;
|
|
11
|
-
status: 'publish' | 'future' | 'draft' | 'pending' | 'private';
|
|
12
|
-
content?: string;
|
|
13
|
-
meta?: unknown;
|
|
14
|
-
wp_pattern_category?: number[];
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Delete all blocks using REST API.
|
|
19
|
-
*
|
|
20
|
-
* @see https://developer.wordpress.org/rest-api/reference/blocks/#list-editor-blocks
|
|
21
|
-
* @param this
|
|
22
|
-
*/
|
|
23
|
-
export async function deleteAllBlocks( this: RequestUtils ) {
|
|
24
|
-
// List all blocks.
|
|
25
|
-
// https://developer.wordpress.org/rest-api/reference/blocks/#list-editor-blocks
|
|
26
|
-
const blocks = await this.rest( {
|
|
27
|
-
path: '/wp/v2/blocks',
|
|
28
|
-
params: {
|
|
29
|
-
per_page: 100,
|
|
30
|
-
// All possible statuses.
|
|
31
|
-
status: 'publish,future,draft,pending,private,trash',
|
|
32
|
-
},
|
|
33
|
-
} );
|
|
34
|
-
|
|
35
|
-
// Delete blocks.
|
|
36
|
-
// https://developer.wordpress.org/rest-api/reference/blocks/#delete-a-editor-block
|
|
37
|
-
// "/wp/v2/posts" not yet supports batch requests.
|
|
38
|
-
await this.batchRest(
|
|
39
|
-
blocks.map( ( block: { id: number } ) => ( {
|
|
40
|
-
method: 'DELETE',
|
|
41
|
-
path: `/wp/v2/blocks/${ block.id }?force=true`,
|
|
42
|
-
} ) )
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Creates a new block using the REST API.
|
|
48
|
-
*
|
|
49
|
-
* @see https://developer.wordpress.org/rest-api/reference/blocks/#create-a-editor-block.
|
|
50
|
-
* @param this
|
|
51
|
-
* @param payload Block payload.
|
|
52
|
-
*/
|
|
53
|
-
export async function createBlock(
|
|
54
|
-
this: RequestUtils,
|
|
55
|
-
payload: CreateBlockPayload
|
|
56
|
-
) {
|
|
57
|
-
return this.createRecord( 'blocks', { ...payload } );
|
|
58
|
-
}
|