@@ -67,6 +67,28 @@ export function getWPDataObject() {
6767 } ) ;
6868}
6969
70+ /**
71+ * Wait for WordPress data stores to be fully initialized.
72+ * This prevents race conditions where wp.data exists but stores aren't registered yet.
73+ */
74+ export function waitForDataStores ( ) {
75+ return cy . window ( ) . should ( ( win ) => {
76+ // eslint-disable-next-line no-unused-expressions
77+ expect ( win . wp ) . to . exist ;
78+ // eslint-disable-next-line no-unused-expressions
79+ expect ( win . wp . data ) . to . exist ;
80+ // eslint-disable-next-line no-unused-expressions
81+ expect ( win . wp . data . select ) . to . be . a ( 'function' ) ;
82+
83+ // Ensure core stores are registered
84+ const coreEditPostSelect = win . wp . data . select ( 'core/edit-post' ) ;
85+ // eslint-disable-next-line no-unused-expressions
86+ expect ( coreEditPostSelect ) . to . exist ;
87+ // eslint-disable-next-line no-unused-expressions
88+ expect ( coreEditPostSelect . isFeatureActive ) . to . be . a ( 'function' ) ;
89+ } ) ;
90+ }
91+
7092/**
7193 * Safely obtain the window blocks object or error
7294 * when the window object is not available.
@@ -81,17 +103,19 @@ export function getWPBlocksObject() {
81103 * Disable Gutenberg Tips
82104 */
83105export function disableGutenbergFeatures ( ) {
84- return getWPDataObject ( ) . then ( ( data ) => {
85- // Enable "Top Toolbar"
86- if ( ! data . select ( 'core/edit-post' ) . isFeatureActive ( 'fixedToolbar' ) ) {
87- data . dispatch ( 'core/edit-post' ) . toggleFeature ( 'fixedToolbar' ) ;
88- }
106+ return waitForDataStores ( ) . then ( ( ) => {
107+ return getWPDataObject ( ) . then ( ( data ) => {
108+ // Enable "Top Toolbar"
109+ if ( ! data . select ( 'core/edit-post' ) . isFeatureActive ( 'fixedToolbar' ) ) {
110+ data . dispatch ( 'core/edit-post' ) . toggleFeature ( 'fixedToolbar' ) ;
111+ }
89112
90- if ( data . select ( 'core/edit-post' ) . isFeatureActive ( 'welcomeGuide' ) ) {
91- data . dispatch ( 'core/edit-post' ) . toggleFeature ( 'welcomeGuide' ) ;
92- }
113+ if ( data . select ( 'core/edit-post' ) . isFeatureActive ( 'welcomeGuide' ) ) {
114+ data . dispatch ( 'core/edit-post' ) . toggleFeature ( 'welcomeGuide' ) ;
115+ }
93116
94- data . dispatch ( 'core/editor' ) . disablePublishSidebar ( ) ;
117+ data . dispatch ( 'core/editor' ) . disablePublishSidebar ( ) ;
118+ } ) ;
95119 } ) ;
96120}
97121
@@ -125,11 +149,13 @@ export function addBlockToPost( blockName, clearEditor = false ) {
125149 * Note: This method is preferred over the old method because
126150 * we do not need to test the Core controls around block insertion.
127151 */
128- getWPDataObject ( ) . then ( ( data ) => {
129- getWPBlocksObject ( ) . then ( ( blocks ) => {
130- data . dispatch ( 'core/block-editor' ) . insertBlock (
131- blocks . createBlock ( blockName )
132- ) ;
152+ waitForDataStores ( ) . then ( ( ) => {
153+ getWPDataObject ( ) . then ( ( data ) => {
154+ getWPBlocksObject ( ) . then ( ( blocks ) => {
155+ data . dispatch ( 'core/block-editor' ) . insertBlock (
156+ blocks . createBlock ( blockName )
157+ ) ;
158+ } ) ;
133159 } ) ;
134160 } ) ;
135161
@@ -293,10 +319,12 @@ export function editPage() {
293319 * Clear all blocks from the editor and wait for them to be fully removed
294320 */
295321export function clearBlocks ( ) {
296- getWPDataObject ( ) . then ( ( data ) => {
297- data . dispatch ( 'core/block-editor' ) . removeBlocks (
298- data . select ( 'core/block-editor' ) . getBlocks ( ) . map ( ( block ) => block . clientId )
299- ) ;
322+ waitForDataStores ( ) . then ( ( ) => {
323+ getWPDataObject ( ) . then ( ( data ) => {
324+ data . dispatch ( 'core/block-editor' ) . removeBlocks (
325+ data . select ( 'core/block-editor' ) . getBlocks ( ) . map ( ( block ) => block . clientId )
326+ ) ;
327+ } ) ;
300328 } ) ;
301329
302330 // Simple wait and verify no blocks remain
@@ -354,24 +382,26 @@ export function selectBlock( name ) {
354382 cy . get ( `[data-type*="${ name } "], [data-title*="${ name } "]` ) . should ( 'exist' ) ;
355383
356384 let id = '' ; // The block client ID.
357- cy . window ( ) . then ( ( win ) => {
358- // Prefer selector from data-store.
359- id = win . wp . data . select ( 'core/block-editor' ) . getBlocks ( ) . filter ( ( i ) => i ?. name === name ) [ 0 ] ?. clientId ;
360-
361- // Fallback to selector from DOM.
362- if ( ! id ) {
363- cy . get ( `[data-type*="${ name } "], [data-title*="${ name } "]` )
364- . invoke ( 'attr' , 'data-block' )
365- . then ( ( clientId ) => id = clientId ) ;
366- }
367- } ) ;
385+ waitForDataStores ( ) . then ( ( ) => {
386+ cy . window ( ) . then ( ( win ) => {
387+ // Prefer selector from data-store.
388+ id = win . wp . data . select ( 'core/block-editor' ) . getBlocks ( ) . filter ( ( i ) => i ?. name === name ) [ 0 ] ?. clientId ;
389+
390+ // Fallback to selector from DOM.
391+ if ( ! id ) {
392+ cy . get ( `[data-type*="${ name } "], [data-title*="${ name } "]` )
393+ . invoke ( 'attr' , 'data-block' )
394+ . then ( ( clientId ) => id = clientId ) ;
395+ }
396+ } ) ;
368397
369- cy . window ( ) . then ( ( win ) => {
370- win . wp . data . dispatch ( 'core/block-editor' ) . selectBlock ( id ) ;
371- } ) ;
398+ cy . window ( ) . then ( ( win ) => {
399+ win . wp . data . dispatch ( 'core/block-editor' ) . selectBlock ( id ) ;
400+ } ) ;
372401
373- cy . window ( ) . then ( ( win ) => {
374- win . wp . data . dispatch ( 'core/edit-post' ) . openGeneralSidebar ( 'edit-post/block' ) ;
402+ cy . window ( ) . then ( ( win ) => {
403+ win . wp . data . dispatch ( 'core/edit-post' ) . openGeneralSidebar ( 'edit-post/block' ) ;
404+ } ) ;
375405 } ) ;
376406 // Wait for sidebar to be visible
377407 cy . get ( '.interface-interface-skeleton__sidebar' ) . should ( 'be.visible' ) ;
0 commit comments