@@ -11,8 +11,6 @@ test.describe( 'Collaboration - CRDT persistence', () => {
1111 page,
1212 requestUtils,
1313 } ) => {
14- await collaborationUtils . setCollaboration ( true ) ;
15-
1614 // Create a draft post — it will not have _crdt_document meta.
1715 const post = await requestUtils . createPost ( {
1816 title : 'Persistence Test - Draft' ,
@@ -30,73 +28,23 @@ test.describe( 'Collaboration - CRDT persistence', () => {
3028 fullscreenMode : false ,
3129 } ) ;
3230
33- // Wait for the entity record resolver to finish.
34- await page . waitForFunction (
35- ( ) => {
36- const postId = ( window as any ) . wp . data
37- . select ( 'core/editor' )
38- . getCurrentPostId ( ) ;
39- if ( ! postId ) {
40- return false ;
41- }
42- return ( window as any ) . wp . data
43- . select ( 'core' )
44- . hasFinishedResolution ( 'getEntityRecord' , [
45- 'postType' ,
46- 'post' ,
47- postId ,
48- ] ) ;
49- } ,
50- { timeout : 5000 }
51- ) ;
52-
53- const persistedCrdtDoc = await page . evaluate ( ( ) => {
54- return window . wp . data
55- . select ( 'core' )
56- . getEntityRecord (
57- 'postType' ,
58- 'post' ,
59- window . wp . data . select ( 'core/editor' ) . getCurrentPostId ( )
60- ) . meta . _crdt_document ;
61- } ) ;
31+ // Wait for collaboration runtime and entity record to be ready.
32+ await collaborationUtils . waitForEntityReady ( page ) ;
6233
34+ const persistedCrdtDoc =
35+ await collaborationUtils . getCrdtDocument ( page ) ;
6336 expect ( persistedCrdtDoc ) . toBeTruthy ( ) ;
6437
65- // Refresh the page and verify the CRDT document is loaded from the persisted meta.
38+ // Refresh the page and verify the CRDT document is loaded from the
39+ // persisted meta and no reconciliation save is triggered.
6640 await page . reload ( ) ;
41+ await collaborationUtils . waitForEntityReady ( page ) ;
6742
68- // Wait for the entity record resolver to finish.
69- await page . waitForFunction (
70- ( ) => {
71- const postId = ( window as any ) . wp . data
72- . select ( 'core/editor' )
73- . getCurrentPostId ( ) ;
74- if ( ! postId ) {
75- return false ;
76- }
77- return ( window as any ) . wp . data
78- . select ( 'core' )
79- . hasFinishedResolution ( 'getEntityRecord' , [
80- 'postType' ,
81- 'post' ,
82- postId ,
83- ] ) ;
84- } ,
85- { timeout : 5000 }
86- ) ;
87-
88- const reloadedCrdtDoc = await page . evaluate ( ( ) => {
89- return window . wp . data
90- . select ( 'core' )
91- . getEntityRecord (
92- 'postType' ,
93- 'post' ,
94- window . wp . data . select ( 'core/editor' ) . getCurrentPostId ( )
95- ) . meta . _crdt_document ;
96- } ) ;
43+ const reloadedCrdtDoc =
44+ await collaborationUtils . getCrdtDocument ( page ) ;
9745
98- // No invalidations should occur on reload, so the CRDT document should be
99- // the same as before.
46+ // No invalidations should occur on reload, so the CRDT document should
47+ // be identical to the one persisted before reload .
10048 expect ( reloadedCrdtDoc ) . toBe ( persistedCrdtDoc ) ;
10149 } ) ;
10250
@@ -106,51 +54,82 @@ test.describe( 'Collaboration - CRDT persistence', () => {
10654 editor,
10755 page,
10856 } ) => {
109- await collaborationUtils . setCollaboration ( true ) ;
110-
11157 // Navigate to create a new post (auto-draft).
11258 await admin . visitAdminPage ( 'post-new.php' ) ;
11359 await editor . setPreferences ( 'core/edit-post' , {
11460 welcomeGuide : false ,
11561 fullscreenMode : false ,
11662 } ) ;
11763
118- // Wait for collaboration runtime to initialize.
64+ // Wait for collaboration runtime to initialize separately first, then
65+ // wait for the entity record resolver to finish.
11966 await page . waitForFunction (
12067 ( ) => ( window as any ) . _wpCollaborationEnabled === true ,
12168 { timeout : 5000 }
12269 ) ;
70+ await collaborationUtils . waitForEntityReady ( page , {
71+ requireCollaboration : false ,
72+ } ) ;
12373
124- // Wait for the entity record resolver to finish.
125- await page . waitForFunction (
126- ( ) => {
127- const postId = ( window as any ) . wp . data
128- . select ( 'core/editor' )
129- . getCurrentPostId ( ) ;
130- if ( ! postId ) {
131- return false ;
132- }
133- return ( window as any ) . wp . data
134- . select ( 'core' )
135- . hasFinishedResolution ( 'getEntityRecord' , [
136- 'postType' ,
137- 'post' ,
138- postId ,
139- ] ) ;
140- } ,
141- { timeout : 5000 }
142- ) ;
74+ const persistedCrdtDoc =
75+ await collaborationUtils . getCrdtDocument ( page ) ;
76+ expect ( persistedCrdtDoc ) . toBeFalsy ( ) ;
77+ } ) ;
14378
144- const persistedCrdtDoc = await page . evaluate ( ( ) => {
145- return window . wp . data
146- . select ( 'core' )
147- . getEntityRecord (
148- 'postType' ,
149- 'post' ,
150- window . wp . data . select ( 'core/editor' ) . getCurrentPostId ( )
151- ) . meta . _crdt_document ;
79+ test ( 'persisted CRDT document matches content after save and reload' , async ( {
80+ admin,
81+ collaborationUtils,
82+ editor,
83+ page,
84+ requestUtils,
85+ } ) => {
86+ // Create a draft post with initial content.
87+ const post = await requestUtils . createPost ( {
88+ title : 'Persistence Test - Save Reload' ,
89+ content :
90+ '<!-- wp:paragraph -->\n<p>Initial content</p>\n<!-- /wp:paragraph -->' ,
91+ status : 'draft' ,
92+ date_gmt : new Date ( ) . toISOString ( ) ,
15293 } ) ;
15394
154- expect ( persistedCrdtDoc ) . toBeFalsy ( ) ;
95+ // Open the post in the editor.
96+ await admin . visitAdminPage (
97+ 'post.php' ,
98+ `post=${ post . id } &action=edit`
99+ ) ;
100+ await editor . setPreferences ( 'core/edit-post' , {
101+ welcomeGuide : false ,
102+ fullscreenMode : false ,
103+ } ) ;
104+
105+ // Wait for collaboration runtime and entity record to be ready.
106+ await collaborationUtils . waitForEntityReady ( page ) ;
107+
108+ // Edit the paragraph to ensure Y.Doc reflects meaningful changes.
109+ await editor . canvas
110+ . getByRole ( 'document' , { name : 'Block: Paragraph' } )
111+ . click ( ) ;
112+ await page . keyboard . press ( 'Meta+a' ) ;
113+ await page . keyboard . type ( 'Updated content' ) ;
114+
115+ // saveDraft() resolves only after the "Draft saved" notice appears,
116+ // so isSavingPost() is already false when it returns.
117+ await editor . saveDraft ( ) ;
118+
119+ const crdtDocAfterSave =
120+ await collaborationUtils . getCrdtDocument ( page ) ;
121+ expect ( crdtDocAfterSave ) . toBeTruthy ( ) ;
122+
123+ // Reload and wait for entity resolution and any in-flight save to
124+ // settle before reading store values.
125+ await page . reload ( ) ;
126+ await collaborationUtils . waitForEntityReadyAndSaveSettled ( page ) ;
127+
128+ // The CRDT document must be unchanged after reload. A difference means
129+ // the _crdt_document persisted during save was stale (e.g. deferred
130+ // Y.Doc updates not yet flushed at serialization time).
131+ const crdtDocAfterReload =
132+ await collaborationUtils . getCrdtDocument ( page ) ;
133+ expect ( crdtDocAfterReload ) . toBe ( crdtDocAfterSave ) ;
155134 } ) ;
156135} ) ;
0 commit comments