@wordpress/e2e-tests 9.10.0 → 9.10.1-next.v.202605131006.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/package.json +4 -4
- package/plugins/connectors-capability-restriction.php +46 -0
- package/plugins/image-format-conversion-jpeg-to-webp.php +20 -0
- package/plugins/image-format-conversion-png-to-jpeg.php +20 -0
- package/plugins/interactive-blocks/directive-bind/render.php +7 -0
- package/plugins/rtc-websocket-provider/src/index.js +115 -0
- package/plugins/rtc-websocket-provider/src/yjs-external.js +15 -0
- package/plugins/rtc-websocket-provider.php +59 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/e2e-tests",
|
|
3
|
-
"version": "9.10.0",
|
|
3
|
+
"version": "9.10.1-next.v.202605131006.0+2a3d07cab",
|
|
4
4
|
"description": "Test plugins and mu-plugins for E2E tests in WordPress.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"npm": ">=8.19.2"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@wordpress/interactivity": "^6.45.0",
|
|
28
|
-
"@wordpress/interactivity-router": "^2.45.0"
|
|
27
|
+
"@wordpress/interactivity": "^6.45.1-next.v.202605131006.0+2a3d07cab",
|
|
28
|
+
"@wordpress/interactivity-router": "^2.45.1-next.v.202605131006.0+2a3d07cab"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"jest": ">=29",
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
"publishConfig": {
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "8804fa29bc78a1d98e5a4d40c3e180ddd907016c"
|
|
40
40
|
}
|
|
@@ -22,6 +22,13 @@ add_action(
|
|
|
22
22
|
}
|
|
23
23
|
);
|
|
24
24
|
|
|
25
|
+
register_activation_hook(
|
|
26
|
+
__FILE__,
|
|
27
|
+
static function () {
|
|
28
|
+
delete_option( 'gutenberg_test_cap_restriction' );
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
25
32
|
register_deactivation_hook(
|
|
26
33
|
__FILE__,
|
|
27
34
|
static function () {
|
|
@@ -29,6 +36,45 @@ register_deactivation_hook(
|
|
|
29
36
|
}
|
|
30
37
|
);
|
|
31
38
|
|
|
39
|
+
add_action(
|
|
40
|
+
'wp_connectors_init',
|
|
41
|
+
static function ( WP_Connector_Registry $registry ) {
|
|
42
|
+
$registry->register(
|
|
43
|
+
'test_install_required_connector',
|
|
44
|
+
array(
|
|
45
|
+
'name' => 'Test Install Required Connector',
|
|
46
|
+
'description' => 'A connector backed by a plugin that is not installed.',
|
|
47
|
+
'type' => 'ai_provider',
|
|
48
|
+
'plugin' => array(
|
|
49
|
+
'file' => 'gutenberg-test-connectors-never-installed/plugin.php',
|
|
50
|
+
'is_active' => '__return_false',
|
|
51
|
+
),
|
|
52
|
+
'authentication' => array(
|
|
53
|
+
'method' => 'api_key',
|
|
54
|
+
'setting_name' => 'gutenberg_test_install_required_connector_api_key',
|
|
55
|
+
),
|
|
56
|
+
)
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
$registry->register(
|
|
60
|
+
'test_activate_required_connector',
|
|
61
|
+
array(
|
|
62
|
+
'name' => 'Test Activate Required Connector',
|
|
63
|
+
'description' => 'A connector backed by an installed inactive plugin.',
|
|
64
|
+
'type' => 'ai_provider',
|
|
65
|
+
'plugin' => array(
|
|
66
|
+
'file' => 'hello/hello.php',
|
|
67
|
+
'is_active' => '__return_false',
|
|
68
|
+
),
|
|
69
|
+
'authentication' => array(
|
|
70
|
+
'method' => 'api_key',
|
|
71
|
+
'setting_name' => 'gutenberg_test_activate_required_connector_api_key',
|
|
72
|
+
),
|
|
73
|
+
)
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
|
|
32
78
|
add_filter(
|
|
33
79
|
'map_meta_cap',
|
|
34
80
|
static function ( $caps, $cap ) {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/**
|
|
3
|
+
* Plugin Name: Gutenberg Test Plugin: Image Format Conversion JPEG to WebP
|
|
4
|
+
* Plugin URI: https://github.com/WordPress/gutenberg
|
|
5
|
+
* Author: Gutenberg Team
|
|
6
|
+
*
|
|
7
|
+
* @package gutenberg-test-image-format-conversion-jpeg-to-webp
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
add_filter(
|
|
11
|
+
'image_editor_output_format',
|
|
12
|
+
static function ( $formats, $filename, $mime_type ) {
|
|
13
|
+
if ( 'image/jpeg' === $mime_type ) {
|
|
14
|
+
$formats['image/jpeg'] = 'image/webp';
|
|
15
|
+
}
|
|
16
|
+
return $formats;
|
|
17
|
+
},
|
|
18
|
+
10,
|
|
19
|
+
3
|
|
20
|
+
);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/**
|
|
3
|
+
* Plugin Name: Gutenberg Test Plugin: Image Format Conversion PNG to JPEG
|
|
4
|
+
* Plugin URI: https://github.com/WordPress/gutenberg
|
|
5
|
+
* Author: Gutenberg Team
|
|
6
|
+
*
|
|
7
|
+
* @package gutenberg-test-image-format-conversion-png-to-jpeg
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
add_filter(
|
|
11
|
+
'image_editor_output_format',
|
|
12
|
+
static function ( $formats, $filename, $mime_type ) {
|
|
13
|
+
if ( 'image/png' === $mime_type ) {
|
|
14
|
+
$formats['image/png'] = 'image/jpeg';
|
|
15
|
+
}
|
|
16
|
+
return $formats;
|
|
17
|
+
},
|
|
18
|
+
10,
|
|
19
|
+
3
|
|
20
|
+
);
|
|
@@ -66,6 +66,9 @@
|
|
|
66
66
|
'emptyString' => '{ "value": "" }',
|
|
67
67
|
'anyString' => '{ "value": "any" }',
|
|
68
68
|
'number' => '{ "value": 10 }',
|
|
69
|
+
'auto' => '{ "value": "auto" }',
|
|
70
|
+
'manual' => '{ "value": "manual" }',
|
|
71
|
+
'hint' => '{ "value": "hint" }',
|
|
69
72
|
);
|
|
70
73
|
?>
|
|
71
74
|
|
|
@@ -90,6 +93,10 @@
|
|
|
90
93
|
data-wp-bind--disabled="context.value"
|
|
91
94
|
data-wp-bind--aria-disabled="context.value"
|
|
92
95
|
>
|
|
96
|
+
<div
|
|
97
|
+
data-testid="popover"
|
|
98
|
+
data-wp-bind--popover="context.value"
|
|
99
|
+
></div>
|
|
93
100
|
<button
|
|
94
101
|
data-testid="toggle value"
|
|
95
102
|
data-wp-on--click="actions.toggleValue"
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test-only WebSocket sync provider for Gutenberg RTC e2e tests.
|
|
3
|
+
*
|
|
4
|
+
* Speaks the y-websocket binary protocol against test/e2e/bin/rtc-test-ws-sync-server.mjs
|
|
5
|
+
* (which is built on @y/websocket-server) so the test harness exercises the same
|
|
6
|
+
* wire format as production deployments. Exposes a small debug surface on
|
|
7
|
+
* window.__gutenbergTestWebSocketSync.rooms that the Playwright fixtures poll.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// eslint-disable-next-line import/no-extraneous-dependencies -- declared in test/e2e/package.json, only loaded by the WS e2e harness.
|
|
11
|
+
import { WebsocketProvider } from 'y-websocket';
|
|
12
|
+
|
|
13
|
+
const TEST_PROVIDER_NAMESPACE = 'gutenberg-test/rtc-websocket-provider';
|
|
14
|
+
const DEFAULT_URL = 'ws://127.0.0.1:18991';
|
|
15
|
+
|
|
16
|
+
const settings = window.gutenbergTestWebSocketSync || {};
|
|
17
|
+
const globalState = ( window.__gutenbergTestWebSocketSync = {
|
|
18
|
+
rooms: {},
|
|
19
|
+
tick: 0,
|
|
20
|
+
url: settings.url || DEFAULT_URL,
|
|
21
|
+
} );
|
|
22
|
+
|
|
23
|
+
function ensureRoomDebugState( room ) {
|
|
24
|
+
if ( ! globalState.rooms[ room ] ) {
|
|
25
|
+
globalState.rooms[ room ] = {
|
|
26
|
+
awarenessCount: 0,
|
|
27
|
+
clientId: null,
|
|
28
|
+
status: 'disconnected',
|
|
29
|
+
synced: false,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return globalState.rooms[ room ];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function updateDebugState( room, patch ) {
|
|
36
|
+
Object.assign( ensureRoomDebugState( room ), patch );
|
|
37
|
+
globalState.tick += 1;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function createWebSocketProvider() {
|
|
41
|
+
return async ( { awareness, objectType, objectId, ydoc } ) => {
|
|
42
|
+
const room = objectId ? `${ objectType }:${ objectId }` : objectType;
|
|
43
|
+
|
|
44
|
+
updateDebugState( room, {
|
|
45
|
+
clientId: ydoc.clientID,
|
|
46
|
+
status: 'connecting',
|
|
47
|
+
synced: false,
|
|
48
|
+
} );
|
|
49
|
+
|
|
50
|
+
const provider = new WebsocketProvider( globalState.url, room, ydoc, {
|
|
51
|
+
awareness,
|
|
52
|
+
// Disable BroadcastChannel so cross-tab sync always goes through
|
|
53
|
+
// the WebSocket. Tests need to exercise the wire transport.
|
|
54
|
+
disableBc: true,
|
|
55
|
+
} );
|
|
56
|
+
|
|
57
|
+
const statusListeners = new Set();
|
|
58
|
+
|
|
59
|
+
const onStatus = ( event ) => {
|
|
60
|
+
// A fresh socket means the previous sync handshake (if any) is
|
|
61
|
+
// no longer current. y-websocket re-fires 'sync' once sync step 2
|
|
62
|
+
// completes on the new connection.
|
|
63
|
+
const patch = { status: event.status };
|
|
64
|
+
if ( event.status !== 'connected' ) {
|
|
65
|
+
patch.synced = false;
|
|
66
|
+
}
|
|
67
|
+
updateDebugState( room, patch );
|
|
68
|
+
for ( const callback of statusListeners ) {
|
|
69
|
+
callback( { status: event.status } );
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
provider.on( 'status', onStatus );
|
|
73
|
+
|
|
74
|
+
// y-websocket distinguishes socket connection from sync completion.
|
|
75
|
+
// 'connected' means the WS is open; 'sync' fires once sync step 2 has
|
|
76
|
+
// landed and the doc reflects the server state. Tests that need real
|
|
77
|
+
// convergence should wait on `synced`, not just `status`.
|
|
78
|
+
const onSync = ( isSynced ) => {
|
|
79
|
+
updateDebugState( room, { synced: !! isSynced } );
|
|
80
|
+
};
|
|
81
|
+
provider.on( 'sync', onSync );
|
|
82
|
+
|
|
83
|
+
const onAwarenessChange = () => {
|
|
84
|
+
updateDebugState( room, {
|
|
85
|
+
awarenessCount: ( awareness || provider.awareness ).getStates()
|
|
86
|
+
.size,
|
|
87
|
+
} );
|
|
88
|
+
};
|
|
89
|
+
const awarenessInstance = awareness || provider.awareness;
|
|
90
|
+
awarenessInstance.on( 'change', onAwarenessChange );
|
|
91
|
+
onAwarenessChange();
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
destroy: () => {
|
|
95
|
+
awarenessInstance.off( 'change', onAwarenessChange );
|
|
96
|
+
provider.off( 'status', onStatus );
|
|
97
|
+
provider.off( 'sync', onSync );
|
|
98
|
+
provider.destroy();
|
|
99
|
+
updateDebugState( room, {
|
|
100
|
+
status: 'disconnected',
|
|
101
|
+
synced: false,
|
|
102
|
+
} );
|
|
103
|
+
},
|
|
104
|
+
on: ( event, callback ) => {
|
|
105
|
+
if ( event === 'status' ) {
|
|
106
|
+
statusListeners.add( callback );
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
window.wp.hooks.addFilter( 'sync.providers', TEST_PROVIDER_NAMESPACE, () => [
|
|
114
|
+
createWebSocketProvider(),
|
|
115
|
+
] );
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-export Yjs symbols from wp.sync.Y so the bundled y-websocket and
|
|
3
|
+
* y-protocols modules share the same Yjs instance as @wordpress/sync.
|
|
4
|
+
* Two Yjs instances on the same page cause silent data corruption:
|
|
5
|
+
* https://github.com/yjs/yjs/issues/438
|
|
6
|
+
*
|
|
7
|
+
* Only the symbols actually referenced by y-websocket and y-protocols
|
|
8
|
+
* need to be re-exported here.
|
|
9
|
+
*/
|
|
10
|
+
const Y = window.wp.sync.Y;
|
|
11
|
+
|
|
12
|
+
export const Doc = Y.Doc;
|
|
13
|
+
export const applyUpdate = Y.applyUpdate;
|
|
14
|
+
export const encodeStateAsUpdate = Y.encodeStateAsUpdate;
|
|
15
|
+
export const encodeStateVector = Y.encodeStateVector;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/**
|
|
3
|
+
* Plugin Name: Gutenberg Test Plugin, RTC WebSocket Provider
|
|
4
|
+
* Plugin URI: https://github.com/WordPress/gutenberg
|
|
5
|
+
* Author: Gutenberg Team
|
|
6
|
+
*
|
|
7
|
+
* @package gutenberg-test-rtc-websocket-provider
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Enqueues a test-only WebSocket sync provider for RTC e2e tests.
|
|
12
|
+
*/
|
|
13
|
+
function gutenberg_test_rtc_websocket_provider_enqueue() {
|
|
14
|
+
$script_path = plugin_dir_path( __FILE__ ) . 'rtc-websocket-provider/build/index.js';
|
|
15
|
+
$ws_url = '';
|
|
16
|
+
|
|
17
|
+
// The Playwright globalSetup writes the resolved WS URL here so the PHP
|
|
18
|
+
// plugin can find it. wp-env does not forward host env vars into the
|
|
19
|
+
// container, so getenv() alone would always miss any port override.
|
|
20
|
+
$config_path = plugin_dir_path( __FILE__ ) . 'rtc-websocket-provider/build/runtime-config.json';
|
|
21
|
+
if ( file_exists( $config_path ) ) {
|
|
22
|
+
$config = json_decode( file_get_contents( $config_path ), true );
|
|
23
|
+
if ( is_array( $config ) && ! empty( $config['url'] ) ) {
|
|
24
|
+
$ws_url = $config['url'];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if ( ! $ws_url ) {
|
|
29
|
+
$ws_url = getenv( 'GUTENBERG_RTC_TEST_WS_URL' );
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if ( ! $ws_url ) {
|
|
33
|
+
$ws_port = getenv( 'GUTENBERG_RTC_TEST_WS_PORT' );
|
|
34
|
+
if ( ! $ws_port ) {
|
|
35
|
+
$ws_port = '18991';
|
|
36
|
+
}
|
|
37
|
+
$ws_url = 'ws://127.0.0.1:' . $ws_port;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
wp_enqueue_script(
|
|
41
|
+
'gutenberg-test-rtc-websocket-provider',
|
|
42
|
+
plugins_url( 'rtc-websocket-provider/build/index.js', __FILE__ ),
|
|
43
|
+
array( 'wp-hooks', 'wp-sync' ),
|
|
44
|
+
filemtime( $script_path ),
|
|
45
|
+
true
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
wp_add_inline_script(
|
|
49
|
+
'gutenberg-test-rtc-websocket-provider',
|
|
50
|
+
'window.gutenbergTestWebSocketSync = ' . wp_json_encode(
|
|
51
|
+
array(
|
|
52
|
+
'url' => $ws_url,
|
|
53
|
+
)
|
|
54
|
+
) . ';',
|
|
55
|
+
'before'
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
add_action( 'enqueue_block_editor_assets', 'gutenberg_test_rtc_websocket_provider_enqueue' );
|