@wordpress/e2e-tests 8.31.1-next.f56bd8138.0 → 8.32.1-next.47f435fc9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/package.json +9 -9
  3. package/plugins/block-bindings/index.js +96 -6
  4. package/plugins/block-bindings.php +12 -5
  5. package/plugins/interactive-blocks/deferred-store/block.json +1 -1
  6. package/plugins/interactive-blocks/directive-bind/block.json +1 -1
  7. package/plugins/interactive-blocks/directive-bind/render.php +11 -0
  8. package/plugins/interactive-blocks/directive-class/block.json +1 -1
  9. package/plugins/interactive-blocks/directive-class/render.php +3 -1
  10. package/plugins/interactive-blocks/directive-context/block.json +1 -1
  11. package/plugins/interactive-blocks/directive-context/render.php +28 -0
  12. package/plugins/interactive-blocks/directive-context/view.js +17 -1
  13. package/plugins/interactive-blocks/directive-each/block.json +1 -1
  14. package/plugins/interactive-blocks/directive-each/render.php +29 -0
  15. package/plugins/interactive-blocks/directive-init/block.json +1 -1
  16. package/plugins/interactive-blocks/directive-init/render.php +1 -1
  17. package/plugins/interactive-blocks/directive-key/block.json +1 -1
  18. package/plugins/interactive-blocks/directive-on/block.json +1 -1
  19. package/plugins/interactive-blocks/directive-on/render.php +1 -1
  20. package/plugins/interactive-blocks/directive-on-document/block.json +1 -1
  21. package/plugins/interactive-blocks/directive-on-document/render.php +6 -1
  22. package/plugins/interactive-blocks/directive-on-document/view.js +4 -0
  23. package/plugins/interactive-blocks/directive-on-window/block.json +1 -1
  24. package/plugins/interactive-blocks/directive-on-window/render.php +6 -1
  25. package/plugins/interactive-blocks/directive-on-window/view.js +4 -0
  26. package/plugins/interactive-blocks/directive-priorities/block.json +1 -1
  27. package/plugins/interactive-blocks/directive-run/block.json +1 -1
  28. package/plugins/interactive-blocks/directive-run/render.php +3 -3
  29. package/plugins/interactive-blocks/directive-style/block.json +1 -1
  30. package/plugins/interactive-blocks/directive-style/render.php +10 -0
  31. package/plugins/interactive-blocks/directive-text/block.json +1 -1
  32. package/plugins/interactive-blocks/directive-text/render.php +9 -0
  33. package/plugins/interactive-blocks/directive-watch/block.json +1 -1
  34. package/plugins/interactive-blocks/directive-watch/render.php +8 -0
  35. package/plugins/interactive-blocks/directive-watch/view.js +8 -0
  36. package/plugins/interactive-blocks/generator-scope/block.json +1 -1
  37. package/plugins/interactive-blocks/get-server-context/block.json +1 -1
  38. package/plugins/interactive-blocks/get-server-state/block.json +1 -1
  39. package/plugins/interactive-blocks/namespace/block.json +1 -1
  40. package/plugins/interactive-blocks/negation-operator/block.json +1 -1
  41. package/plugins/interactive-blocks/router-navigate/block.json +1 -1
  42. package/plugins/interactive-blocks/router-regions/block.json +1 -1
  43. package/plugins/interactive-blocks/router-regions/render.php +43 -7
  44. package/plugins/interactive-blocks/router-script-modules-alpha/block.json +1 -1
  45. package/plugins/interactive-blocks/router-script-modules-bravo/block.json +1 -1
  46. package/plugins/interactive-blocks/router-script-modules-charlie/block.json +1 -1
  47. package/plugins/interactive-blocks/router-script-modules-wrapper/block.json +1 -1
  48. package/plugins/interactive-blocks/router-styles-blue/block.json +1 -1
  49. package/plugins/interactive-blocks/router-styles-green/block.json +1 -1
  50. package/plugins/interactive-blocks/router-styles-red/block.json +1 -1
  51. package/plugins/interactive-blocks/router-styles-wrapper/block.json +1 -1
  52. package/plugins/interactive-blocks/store/block.json +1 -1
  53. package/plugins/interactive-blocks/store-tag/block.json +1 -1
  54. package/plugins/interactive-blocks/tovdom/block.json +1 -1
  55. package/plugins/interactive-blocks/tovdom-islands/block.json +1 -1
  56. package/plugins/interactive-blocks/with-scope/block.json +1 -1
  57. package/plugins/server-side-rendered-block.php +38 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 8.32.0 (2025-10-01)
6
+
5
7
  ## 8.31.0 (2025-09-17)
6
8
 
7
9
  ## 8.30.0 (2025-09-03)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/e2e-tests",
3
- "version": "8.31.1-next.f56bd8138.0",
3
+ "version": "8.32.1-next.47f435fc9.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",
@@ -24,13 +24,13 @@
24
24
  "npm": ">=8.19.2"
25
25
  },
26
26
  "dependencies": {
27
- "@wordpress/e2e-test-utils": "^11.31.1-next.f56bd8138.0",
28
- "@wordpress/interactivity": "^6.31.1-next.f56bd8138.0",
29
- "@wordpress/interactivity-router": "^2.31.1-next.f56bd8138.0",
30
- "@wordpress/jest-console": "^8.31.1-next.f56bd8138.0",
31
- "@wordpress/jest-puppeteer-axe": "^7.31.1-next.f56bd8138.0",
32
- "@wordpress/scripts": "^30.24.1-next.f56bd8138.0",
33
- "@wordpress/url": "^4.31.1-next.f56bd8138.0",
27
+ "@wordpress/e2e-test-utils": "^11.32.1-next.47f435fc9.0",
28
+ "@wordpress/interactivity": "^6.33.1-next.47f435fc9.0",
29
+ "@wordpress/interactivity-router": "^2.32.1-next.47f435fc9.0",
30
+ "@wordpress/jest-console": "^8.32.1-next.47f435fc9.0",
31
+ "@wordpress/jest-puppeteer-axe": "^7.32.1-next.47f435fc9.0",
32
+ "@wordpress/scripts": "^30.25.1-next.47f435fc9.0",
33
+ "@wordpress/url": "^4.32.1-next.47f435fc9.0",
34
34
  "chalk": "^4.0.0",
35
35
  "expect-puppeteer": "^4.4.0",
36
36
  "filenamify": "^4.2.0",
@@ -47,5 +47,5 @@
47
47
  "publishConfig": {
48
48
  "access": "public"
49
49
  },
50
- "gitHead": "ea4a281fd857f48338877590de8c8eb9b9a8cef4"
50
+ "gitHead": "9720f22c138771d2ed1a0522725c3cdf1c242953"
51
51
  }
@@ -13,13 +13,20 @@ const getValues = ( { bindings } ) => {
13
13
  }
14
14
  return newValues;
15
15
  };
16
- const setValues = ( { dispatch, bindings } ) => {
16
+ const setValues = ( { dispatch, context, bindings } ) => {
17
+ const newMeta = {};
17
18
  Object.values( bindings ).forEach( ( { args, newValue } ) => {
18
- // Example of what could be done.
19
- dispatch( 'core' ).editEntityRecord( 'postType', 'post', 1, {
20
- meta: { [ args?.key ]: newValue },
21
- } );
19
+ newMeta[ args.key ] = newValue;
22
20
  } );
21
+
22
+ dispatch( 'core' ).editEntityRecord(
23
+ 'postType',
24
+ context?.postType,
25
+ context?.postId,
26
+ {
27
+ meta: newMeta,
28
+ }
29
+ );
23
30
  };
24
31
 
25
32
  registerBlockBindingsSource( {
@@ -27,7 +34,90 @@ registerBlockBindingsSource( {
27
34
  getValues,
28
35
  setValues,
29
36
  canUserEditValue: () => true,
30
- getFieldsList: () => fieldsList,
37
+ editorUI() {
38
+ return {
39
+ mode: 'dropdown',
40
+ data: Object.entries( fieldsList || {} ).map(
41
+ ( [ key, field ] ) => ( {
42
+ label: field?.label || key,
43
+ type: field?.type || 'string',
44
+ args: {
45
+ key,
46
+ },
47
+ } )
48
+ ),
49
+ };
50
+ },
51
+ } );
52
+
53
+ const ModalButton = ( { fieldKey, fieldLabel, attribute, closeModal } ) => {
54
+ const { updateBlockBindings } = wp.blockEditor.useBlockBindingsUtils();
55
+
56
+ return el(
57
+ 'button',
58
+ {
59
+ onClick: () => {
60
+ updateBlockBindings( {
61
+ [ attribute ]: {
62
+ source: 'testing/modal-source',
63
+ args: { key: fieldKey },
64
+ },
65
+ } );
66
+ closeModal();
67
+ },
68
+ style: {
69
+ display: 'block',
70
+ margin: '5px 0',
71
+ padding: '10px',
72
+ width: '100%',
73
+ },
74
+ },
75
+ fieldLabel
76
+ );
77
+ };
78
+
79
+ registerBlockBindingsSource( {
80
+ name: 'testing/modal-source',
81
+ label: 'Modal Source',
82
+ getValues,
83
+ setValues,
84
+ canUserEditValue: () => true,
85
+ editorUI() {
86
+ return {
87
+ mode: 'modal',
88
+ data: Object.entries( fieldsList || {} ).map(
89
+ ( [ key, field ] ) => ( {
90
+ label: field?.label || key,
91
+ type: field?.type || 'string',
92
+ args: {
93
+ key,
94
+ },
95
+ } )
96
+ ),
97
+ renderModalContent( { attribute, closeModal } ) {
98
+ return el(
99
+ 'div',
100
+ { style: { padding: '20px' } },
101
+ el( 'h3', null, 'Select a field from the modal' ),
102
+ el(
103
+ 'p',
104
+ null,
105
+ 'This is a modal interface for selecting fields.'
106
+ ),
107
+ Object.entries( fieldsList || {} ).map(
108
+ ( [ key, field ] ) =>
109
+ el( ModalButton, {
110
+ key,
111
+ fieldKey: key,
112
+ fieldLabel: field?.label || key,
113
+ attribute,
114
+ closeModal,
115
+ } )
116
+ )
117
+ );
118
+ },
119
+ };
120
+ },
31
121
  } );
32
122
 
33
123
  registerBlockBindingsSource( {
@@ -18,21 +18,26 @@ function gutenberg_test_block_bindings_registration() {
18
18
  $upload_dir = wp_upload_dir();
19
19
  $testing_url = $upload_dir['url'] . '/1024x768_e2e_test_image_size.jpeg';
20
20
  $fields_list = array(
21
- 'text_field' => array(
21
+ 'text_field' => array(
22
22
  'label' => 'Text Field Label',
23
23
  'value' => 'Text Field Value',
24
24
  'type' => 'string',
25
25
  ),
26
- 'url_field' => array(
26
+ 'url_field' => array(
27
27
  'label' => 'URL Field Label',
28
28
  'value' => $testing_url,
29
29
  'type' => 'string',
30
30
  ),
31
- 'empty_field' => array(
31
+ 'empty_field' => array(
32
32
  'label' => 'Empty Field Label',
33
33
  'value' => '',
34
34
  'type' => 'string',
35
35
  ),
36
+ 'number_custom_field' => array(
37
+ 'label' => 'Number Custom Field Label',
38
+ 'value' => 10.5,
39
+ 'type' => 'number',
40
+ ),
36
41
  );
37
42
 
38
43
  // Enqueue a custom script for the plugin.
@@ -69,7 +74,9 @@ function gutenberg_test_block_bindings_registration() {
69
74
  if ( ! isset( $source_args['key'] ) || ! isset( $fields_list[ $source_args['key'] ] ) ) {
70
75
  return null;
71
76
  }
72
- return $fields_list[ $source_args['key'] ]['value']; },
77
+ return $fields_list[ $source_args['key'] ]['value'];
78
+ },
79
+ 'uses_context' => array( 'postType', 'postId' ),
73
80
  )
74
81
  );
75
82
  register_block_bindings_source(
@@ -164,7 +171,7 @@ function gutenberg_test_block_bindings_registration() {
164
171
  );
165
172
  register_meta(
166
173
  'post',
167
- 'number',
174
+ 'number_custom_field',
168
175
  array(
169
176
  'label' => 'Number custom field',
170
177
  'type' => 'number',
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/deferred-store",
5
5
  "title": "E2E Interactivity tests - deferred store",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/directive-bind",
5
5
  "title": "E2E Interactivity tests - directive bind",
6
6
  "category": "text",
@@ -97,4 +97,15 @@
97
97
  >Toggle</button>
98
98
  </div>
99
99
  <?php endforeach; ?>
100
+
101
+ <div data-wp-context='{"test": true}'>
102
+ <div
103
+ data-testid="without-unique-id"
104
+ data-wp-bind--data-test="context.test"
105
+ ></div>
106
+ <div
107
+ data-testid="with-unique-id"
108
+ data-wp-bind--data-test---unique-id="context.test"
109
+ ></div>
110
+ </div>
100
111
  </div>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/directive-class",
5
5
  "title": "E2E Interactivity tests - directive class",
6
6
  "category": "text",
@@ -79,8 +79,10 @@
79
79
  ></div>
80
80
 
81
81
  <div
82
- data-wp-class--main-bg----color="state.trueValue"
83
82
  data-testid="can use classes with several dashes"
83
+ data-wp-class--main-bg--color="state.trueValue"
84
+ data-wp-class--main-bg---color="state.trueValue"
85
+ data-wp-class--main-bg----color="state.trueValue"
84
86
  ></div>
85
87
 
86
88
  <div data-wp-context='{ "value": false }'>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/directive-context",
5
5
  "title": "E2E Interactivity tests - directive context",
6
6
  "category": "text",
@@ -166,6 +166,14 @@
166
166
  <button data-testid="async navigate" data-wp-on--click="actions.asyncNavigate">Async Navigate</button>
167
167
  </div>
168
168
 
169
+ <!-- Count of succesfull client-side navigations -->
170
+ <div
171
+ data-testid="navigation count"
172
+ data-wp-interactive="directive-context-navigate"
173
+ data-wp-watch="callbacks.updateNavigationCount"
174
+ data-wp-text="state.navigationCount"
175
+ ></div>
176
+
169
177
  <div
170
178
  data-wp-interactive='{"namespace": "directive-context-non-default"}'
171
179
  data-wp-context--non-default='{ "text": "non default" }'
@@ -233,3 +241,23 @@
233
241
  ></span>
234
242
  </div>
235
243
  </div>
244
+
245
+ <div
246
+ data-wp-interactive="directive-context/multiple"
247
+ data-wp-context='{ "prop": "parent", "parent": true }'
248
+ >
249
+ <div
250
+ data-wp-context='{ "prop": "default", "default": true }'
251
+ data-wp-context---id1='{ "prop": "id1", "id1": true }'
252
+ data-wp-context---id2='other-namespace::{ "prop": true }'
253
+ >
254
+ <span
255
+ data-testid="multiple context in the same element"
256
+ data-wp-bind--data-test-prop="context.prop"
257
+ data-wp-bind--data-test-parent="context.parent"
258
+ data-wp-bind--data-test-default="context.default"
259
+ data-wp-bind--data-test-id1="context.id1"
260
+ data-wp-bind--data-test-other="other-namespace::context.prop"
261
+ ></span>
262
+ </div>
263
+ </div>
@@ -70,7 +70,14 @@ const html = `
70
70
  <button data-testid="async navigate" data-wp-on--click="actions.asyncNavigate">Async Navigate</button>
71
71
  </div>`;
72
72
 
73
- const { actions } = store( 'directive-context-navigate', {
73
+ const { actions, state } = store( 'directive-context-navigate', {
74
+ state: {
75
+ get navigationCount() {
76
+ const { __navigationCount } = state;
77
+ return isNaN( __navigationCount ) ? 0 : __navigationCount;
78
+ },
79
+ __navigationCount: NaN,
80
+ },
74
81
  actions: {
75
82
  toggleText() {
76
83
  const ctx = getContext();
@@ -99,6 +106,15 @@ const { actions } = store( 'directive-context-navigate', {
99
106
  ctx.newText = 'changed from async action';
100
107
  },
101
108
  },
109
+ callbacks: {
110
+ updateNavigationCount() {
111
+ const { state: routerState } = store( 'core/router' );
112
+ if ( routerState.url && isNaN( state.__navigationCount ) ) {
113
+ state.__navigationCount = 0;
114
+ }
115
+ state.__navigationCount++;
116
+ },
117
+ },
102
118
  } );
103
119
 
104
120
  store( 'directive-context-watch', {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/directive-each",
5
5
  "title": "E2E Interactivity tests - directive each",
6
6
  "category": "text",
@@ -311,3 +311,32 @@
311
311
  >
312
312
  <template data-wp-each="state.eachIterator"><p data-wp-text="context.item"></p></template>
313
313
  </div>
314
+
315
+ <div
316
+ data-wp-interactive="directive-each"
317
+ data-testid="each-with-multiple-directives"
318
+ >
319
+ <template
320
+ data-wp-each="state.eachArray"
321
+ data-wp-each--item="state.eachArray"
322
+ >
323
+ <p data-wp-text="context.item"></p>
324
+ </template>
325
+ <template
326
+ data-wp-each---unique-id="state.eachArray"
327
+ >
328
+ <p data-wp-text="context.item"></p>
329
+ </template>
330
+ </div>
331
+
332
+ <ul
333
+ data-wp-interactive="directive-each"
334
+ data-testid="nested-with-same-item-key"
335
+ >
336
+ <template data-wp-each="context.list" data-wp-context='{"list":["parent1","parent2"]}'>
337
+ <template data-wp-each="context.list" data-wp-context='{"list":["child1","child2"]}'>
338
+ <li data-wp-text="context.item"></li>
339
+ </template>
340
+ <li data-wp-text="context.item"></li>
341
+ </template>
342
+ </ul>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/directive-init",
5
5
  "title": "E2E Interactivity tests - directive init",
6
6
  "category": "text",
@@ -20,7 +20,7 @@
20
20
  data-testid="multiple inits"
21
21
  data-wp-context='{"isReady":[false,false],"calls":[0,0]}'
22
22
  data-wp-init--one="actions.initOne"
23
- data-wp-init--two="actions.initTwo"
23
+ data-wp-init---two="actions.initTwo"
24
24
  >
25
25
  <p data-wp-text="state.isReady" data-testid="isReady">false,false</p>
26
26
  <p data-wp-text="state.calls" data-testid="calls">0,0</p>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/directive-key",
5
5
  "title": "E2E Interactivity tests - directive key",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/directive-on",
5
5
  "title": "E2E Interactivity tests - directive on",
6
6
  "category": "text",
@@ -67,7 +67,7 @@
67
67
  data-testid="multiple handlers button"
68
68
  data-wp-on--click="actions.setClicked"
69
69
  data-wp-on--click--counter="actions.countClick"
70
- data-wp-on--click--toggle="actions.toggle"
70
+ data-wp-on--click---toggle="actions.toggle"
71
71
  >Click me!</button>
72
72
  </div>
73
73
  </div>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/directive-on-document",
5
5
  "title": "E2E Interactivity tests - directive on document",
6
6
  "category": "text",
@@ -24,8 +24,13 @@
24
24
  <p data-wp-text="state.counter" data-testid="counter">0</p>
25
25
  </div>
26
26
  </div>
27
- <div data-wp-on-document--keydown="actions.keydownHandler" data-wp-on-document--keydown--second="actions.keydownSecondHandler">
27
+ <div
28
+ data-wp-on-document--keydown="actions.keydownHandler"
29
+ data-wp-on-document--keydown--second="actions.keydownSecondHandler"
30
+ data-wp-on-document--keydown---third="actions.keydownThirdHandler"
31
+ >
28
32
  <p data-wp-text="state.keydownHandler" data-testid="keydownHandler">no</p>
29
33
  <p data-wp-text="state.keydownSecondHandler" data-testid="keydownSecondHandler">no</p>
34
+ <p data-wp-text="state.keydownThirdHandler" data-testid="keydownThirdHandler">no</p>
30
35
  </div>
31
36
  </div>
@@ -31,6 +31,7 @@ const { state } = store( 'directive-on-document', {
31
31
  isEventAttached: 'no',
32
32
  keydownHandler: 'no',
33
33
  keydownSecondHandler: 'no',
34
+ keydownThirdHandler: 'no',
34
35
  },
35
36
  callbacks: {
36
37
  keydownHandler() {
@@ -51,5 +52,8 @@ const { state } = store( 'directive-on-document', {
51
52
  keydownSecondHandler: () => {
52
53
  state.keydownSecondHandler = 'yes';
53
54
  },
55
+ keydownThirdHandler: () => {
56
+ state.keydownThirdHandler = 'yes';
57
+ },
54
58
  },
55
59
  } );
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/directive-on-window",
5
5
  "title": "E2E Interactivity tests - directive on window",
6
6
  "category": "text",
@@ -21,8 +21,13 @@
21
21
  <p data-wp-text="state.counter" data-testid="counter">0</p>
22
22
  </div>
23
23
  </div>
24
- <div data-wp-on-window--resize="actions.resizeHandler" data-wp-on-window--resize--second="actions.resizeSecondHandler">
24
+ <div
25
+ data-wp-on-window--resize="actions.resizeHandler"
26
+ data-wp-on-window--resize--second="actions.resizeSecondHandler"
27
+ data-wp-on-window--resize---third="actions.resizeThirdHandler"
28
+ >
25
29
  <p data-wp-text="state.resizeHandler" data-testid="resizeHandler">no</p>
26
30
  <p data-wp-text="state.resizeSecondHandler" data-testid="resizeSecondHandler">no</p>
31
+ <p data-wp-text="state.resizeThirdHandler" data-testid="resizeThirdHandler">no</p>
27
32
  </div>
28
33
  </div>
@@ -31,6 +31,7 @@ const { state } = store( 'directive-on-window', {
31
31
  isEventAttached: 'no',
32
32
  resizeHandler: 'no',
33
33
  resizeSecondHandler: 'no',
34
+ resizeThirdHandler: 'no',
34
35
  },
35
36
  callbacks: {
36
37
  resizeHandler() {
@@ -51,5 +52,8 @@ const { state } = store( 'directive-on-window', {
51
52
  resizeSecondHandler: () => {
52
53
  state.resizeSecondHandler = 'yes';
53
54
  },
55
+ resizeThirdHandler: () => {
56
+ state.resizeThirdHandler = 'yes';
57
+ },
54
58
  },
55
59
  } );
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/directive-priorities",
5
5
  "title": "E2E Interactivity tests - directive priorities",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/directive-run",
5
5
  "title": "E2E Interactivity tests - directive run",
6
6
  "category": "text",
@@ -16,8 +16,8 @@
16
16
  <div data-testid="navigated">no</div>
17
17
 
18
18
  <div
19
- data-wp-run--hydrated="callbacks.updateIsHydrated"
20
- data-wp-run--renderCount="callbacks.updateRenderCount"
19
+ data-wp-run---hydrated="callbacks.updateIsHydrated"
20
+ data-wp-run---renderCount="callbacks.updateRenderCount"
21
21
  data-wp-text="state.clickCount"
22
22
  ></div>
23
23
  </div>
@@ -44,7 +44,7 @@
44
44
  >
45
45
  <div
46
46
  data-wp-run--mounted="callbacks.updateIsMounted"
47
- data-wp-run--hooks="callbacks.useHooks"
47
+ data-wp-run---hooks="callbacks.useHooks"
48
48
  >
49
49
  Element with wp-run using hooks
50
50
  </div>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/directive-style",
5
5
  "title": "E2E Interactivity tests - directive style",
6
6
  "category": "text",
@@ -89,4 +89,14 @@
89
89
  Toggle context
90
90
  </button>
91
91
  </div>
92
+
93
+ <div data-wp-style----var="state.color">
94
+ <span style="color: var(--var);" data-testid="can use CSS variables">
95
+ Uses CSS variables
96
+ </span>
97
+ </div>
98
+
99
+ <div data-wp-style--color---unique-id="state.color" data-testid="ignores unique-ids">
100
+ Ignores unique-ids
101
+ </div>
92
102
  </div>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/directive-text",
5
5
  "title": "E2E Interactivity tests - directive text",
6
6
  "category": "text",
@@ -45,5 +45,14 @@
45
45
  data-wp-text="state.boolean"
46
46
  data-testid="show state boolean"
47
47
  ></span>
48
+
49
+ <span
50
+ data-wp-text--suffix="state.text"
51
+ data-testid="ignores suffixes"
52
+ ></span>
53
+ <span
54
+ data-wp-text---unique-id="state.text"
55
+ data-testid="ignores unique-ids"
56
+ ></span>
48
57
  </div>
49
58
  </div>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/directive-watch",
5
5
  "title": "E2E Interactivity tests - directive watch",
6
6
  "category": "text",
@@ -29,6 +29,14 @@
29
29
  0
30
30
  </div>
31
31
 
32
+ <div
33
+ data-testid="multiple watches"
34
+ data-wp-watch--one="callbacks.watch1"
35
+ data-wp-watch---two="callbacks.watch2"
36
+ data-wp-bind--data-watch-one="state.watch1"
37
+ data-wp-bind--data-watch-two="state.watch2"
38
+ ></div>
39
+
32
40
  <button data-testid="toggle" data-wp-on--click="actions.toggle">
33
41
  Update
34
42
  </button>
@@ -34,6 +34,8 @@ const { state } = store( 'directive-watch', {
34
34
  ? 'element is in the DOM'
35
35
  : 'element is not in the DOM';
36
36
  },
37
+ watch1: false,
38
+ watch2: false,
37
39
  },
38
40
  actions: {
39
41
  toggle() {
@@ -59,5 +61,11 @@ const { state } = store( 'directive-watch', {
59
61
  infiniteLoop: () => {
60
62
  state.counter = state.counter + 1;
61
63
  },
64
+ watch1: () => {
65
+ state.watch1 = true;
66
+ },
67
+ watch2: () => {
68
+ state.watch2 = true;
69
+ },
62
70
  },
63
71
  } );
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/generator-scope",
5
5
  "title": "E2E Interactivity tests - generator scope",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/get-server-context",
5
5
  "title": "E2E Interactivity tests - getServerContext",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/get-server-state",
5
5
  "title": "E2E Interactivity tests - getServerState",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test-namespace/directive-bind",
5
5
  "title": "E2E Interactivity tests - directive bind",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/negation-operator",
5
5
  "title": "E2E Interactivity tests - negation operator",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/router-navigate",
5
5
  "title": "E2E Interactivity tests - router navigate",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/router-regions",
5
5
  "title": "E2E Interactivity tests - router regions",
6
6
  "category": "text",
@@ -110,18 +110,54 @@
110
110
  </section>
111
111
 
112
112
  <div data-wp-interactive="router-regions">
113
- <div data-wp-router-region="invalid-region-1">
114
- <p data-testid="invalid-region-text-1">
115
- content from page <?php echo $attributes['page']; ?>
116
- </p>
117
- </div>
118
- <div data-wp-interactive="router-regions" data-wp-router-region="invalid-region-2">
119
- <p data-testid="invalid-region-text-2">
113
+ <!-- Router region inside data-wp-interactive -->
114
+ <div
115
+ data-testid="valid-inside-interactive"
116
+ data-wp-interactive="router-regions"
117
+ data-wp-router-region="valid-inside-interactive"
118
+ data-wp-context='{ "counter": { "value": 0 } }'
119
+ >
120
+ <p data-testid="text-1">
120
121
  content from page <?php echo $attributes['page']; ?>
121
122
  </p>
123
+ <button
124
+ data-testid="valid-inside-interactive-counter"
125
+ data-wp-text="context.counter.value"
126
+ data-wp-on--click="actions.counter.increment"
127
+ >
128
+ NaN
129
+ </button>
130
+
131
+ <!-- Router region inside data-wp-router-region -->
132
+ <div
133
+ data-testid="valid-inside-router-region"
134
+ data-wp-interactive="router-regions"
135
+ data-wp-router-region="valid-inside-router-region"
136
+ data-wp-context='{ "counter": { "value": 0 } }'
137
+ >
138
+ <p data-testid="text-2">
139
+ content from page <?php echo $attributes['page']; ?>
140
+ </p>
141
+ <button
142
+ data-testid="valid-inside-router-region-counter"
143
+ data-wp-text="context.counter.value"
144
+ data-wp-on--click="actions.counter.increment"
145
+ >
146
+ NaN
147
+ </button>
148
+ </div>
122
149
  </div>
123
150
  </div>
124
151
 
152
+ <div
153
+ data-testid="invalid-outside-interactive"
154
+ data-wp-router-region="invalid-outside-interactive"
155
+ >
156
+ <p data-testid="text-3">
157
+ content from page <?php echo $attributes['page']; ?>
158
+ </p>
159
+ </div>
160
+
125
161
  <div id="regions-with-attach-to" data-testid="regions-with-attach-to">
126
162
  <?php
127
163
  /*
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/router-script-modules-alpha",
5
5
  "title": "E2E Interactivity tests - router modules - Alpha",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/router-script-modules-bravo",
5
5
  "title": "E2E Interactivity tests - router modules - Bravo",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/router-script-modules-charlie",
5
5
  "title": "E2E Interactivity tests - router modules - Charlie",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/router-script-modules-wrapper",
5
5
  "title": "E2E Interactivity tests - router modules - Wrapper",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/router-styles-blue",
5
5
  "title": "E2E Interactivity tests - router styles - Blue",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/router-styles-green",
5
5
  "title": "E2E Interactivity tests - router styles - Green",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/router-styles-red",
5
5
  "title": "E2E Interactivity tests - router styles - Red",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/router-styles-wrapper",
5
5
  "title": "E2E Interactivity tests - router styles - Wrapper",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/store",
5
5
  "title": "E2E Interactivity tests - store definition",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/store-tag",
5
5
  "title": "E2E Interactivity tests - store tag",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/tovdom",
5
5
  "title": "E2E Interactivity tests - tovdom",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/tovdom-islands",
5
5
  "title": "E2E Interactivity tests - tovdom islands",
6
6
  "category": "text",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://schemas.wp.org/trunk/block.json",
3
- "apiVersion": 2,
3
+ "apiVersion": 3,
4
4
  "name": "test/with-scope",
5
5
  "title": "E2E Interactivity tests - with scope",
6
6
  "category": "text",
@@ -43,5 +43,43 @@ add_action(
43
43
  'editor_script_handles' => array( 'server-side-rendered-block' ),
44
44
  )
45
45
  );
46
+
47
+ // PHP-only block with auto_register flag, will be auto-registered without JS code
48
+ register_block_type(
49
+ 'test/auto-register-block',
50
+ array(
51
+ 'render_callback' => static function ( $attributes ) {
52
+ $wrapper_attributes = get_block_wrapper_attributes(
53
+ array(
54
+ 'class' => 'auto-register-example',
55
+ )
56
+ );
57
+
58
+ return sprintf(
59
+ '<div %1$s><p>Auto-register block content</p><p>Background: %2$s</p></div>',
60
+ $wrapper_attributes,
61
+ isset( $attributes['backgroundColor'] ) ? esc_html( $attributes['backgroundColor'] ) : 'default'
62
+ );
63
+ },
64
+ 'supports' => array(
65
+ 'auto_register' => true,
66
+ 'color' => array(
67
+ 'background' => true,
68
+ 'text' => false,
69
+ ),
70
+ ),
71
+ )
72
+ );
73
+
74
+ // PHP-only block WITHOUT auto_register flag, will NOT be auto-registered without JS code
75
+ register_block_type(
76
+ 'test/php-only-no-auto-register',
77
+ array(
78
+ 'api_version' => 3,
79
+ 'render_callback' => static function () {
80
+ return '<div>PHP-only block content</div>';
81
+ },
82
+ )
83
+ );
46
84
  }
47
85
  );