@@ -132,11 +132,21 @@ describe('Database View Tabs', () => {
132132 }
133133 } ) ;
134134
135- // Verify children exist
135+ // Verify children exist and match the database views (Grid, Board, Calendar)
136136 PageSelectors . itemByName ( 'New Database' , { timeout : 10000 } ) . within ( ( ) => {
137137 PageSelectors . names ( ) . should ( 'have.length.at.least' , 3 ) ;
138+ // Verify each view type exists in sidebar
139+ cy . contains ( 'Grid' ) . should ( 'exist' ) ;
140+ cy . contains ( 'Board' ) . should ( 'exist' ) ;
141+ cy . contains ( 'Calendar' ) . should ( 'exist' ) ;
138142 } ) ;
139143
144+ // Step 7.1: Verify tab bar and sidebar have matching views
145+ cy . task ( 'log' , '[STEP 7.1] Verifying tab bar and sidebar views match' ) ;
146+ DatabaseViewSelectors . viewTab ( ) . contains ( 'Grid' ) . should ( 'exist' ) ;
147+ DatabaseViewSelectors . viewTab ( ) . contains ( 'Board' ) . should ( 'exist' ) ;
148+ DatabaseViewSelectors . viewTab ( ) . contains ( 'Calendar' ) . should ( 'exist' ) ;
149+
140150 // Step 8: Navigate away and back to verify tabs persist
141151 cy . task ( 'log' , '[STEP 8] Navigating away and back' ) ;
142152 AddPageSelectors . inlineAddButton ( ) . first ( ) . click ( { force : true } ) ;
@@ -225,4 +235,113 @@ describe('Database View Tabs', () => {
225235 cy . task ( 'log' , '[TEST COMPLETE] Tab selection updates sidebar' ) ;
226236 } ) ;
227237 } ) ;
238+
239+ /**
240+ * Regression test for: newly created views should appear immediately in tab bar.
241+ *
242+ * Previously, views wouldn't appear until the folder/outline synced from the server.
243+ * The fix ensures views from Yjs (database_update) are shown immediately without
244+ * waiting for folder sync.
245+ *
246+ * See: selector.ts - useDatabaseViewsSelector now includes non-embedded views from Yjs
247+ */
248+ it ( 'newly created view appears immediately in tab bar (no sync delay)' , ( ) => {
249+ const testEmail = generateRandomEmail ( ) ;
250+
251+ cy . task ( 'log' , `[TEST] Immediate view appearance - Email: ${ testEmail } ` ) ;
252+
253+ cy . visit ( '/login' , { failOnStatusCode : false } ) ;
254+ cy . wait ( 2000 ) ;
255+
256+ const authUtils = new AuthTestUtils ( ) ;
257+ authUtils . signInWithTestUrl ( testEmail ) . then ( ( ) => {
258+ cy . url ( { timeout : 30000 } ) . should ( 'include' , '/app' ) ;
259+ cy . wait ( 3000 ) ;
260+
261+ // Create a Grid database
262+ cy . task ( 'log' , '[STEP 1] Creating Grid database' ) ;
263+ AddPageSelectors . inlineAddButton ( ) . first ( ) . click ( { force : true } ) ;
264+ waitForReactUpdate ( 1000 ) ;
265+ AddPageSelectors . addGridButton ( ) . should ( 'be.visible' ) . click ( { force : true } ) ;
266+ cy . wait ( 5000 ) ;
267+
268+ // Verify initial state - should have exactly 1 tab (Grid)
269+ cy . task ( 'log' , '[STEP 2] Verifying initial tab count' ) ;
270+ DatabaseViewSelectors . viewTab ( ) . should ( 'have.length.at.least' , 1 ) ;
271+ DatabaseViewSelectors . viewTab ( ) . then ( ( $tabs ) => {
272+ cy . wrap ( $tabs . length ) . as ( 'initialTabCount' ) ;
273+ } ) ;
274+
275+ // Click + button to add Board view
276+ cy . task ( 'log' , '[STEP 3] Clicking + button to add Board view' ) ;
277+ DatabaseViewSelectors . addViewButton ( ) . scrollIntoView ( ) . click ( { force : true } ) ;
278+ waitForReactUpdate ( 300 ) ; // Short wait for menu to appear
279+
280+ // Click Board option
281+ cy . get ( '[role="menu"], [role="menuitem"]' , { timeout : 5000 } )
282+ . should ( 'be.visible' )
283+ . contains ( 'Board' )
284+ . click ( { force : true } ) ;
285+
286+ // CRITICAL: Verify tab appears quickly (within 1s)
287+ // This tests that the view appears from Yjs immediately, not waiting for folder sync
288+ // Previously this would fail because views only appeared after folder sync (3+ seconds)
289+ cy . task ( 'log' , '[STEP 4] Verifying Board tab appears quickly (within 1s)' ) ;
290+ waitForReactUpdate ( 200 ) ; // Minimal wait for React to process the state update
291+ cy . get ( '@initialTabCount' ) . then ( ( initialCount ) => {
292+ cy . get ( '[data-testid^="view-tab-"]' , { timeout : 1000 } ) . should (
293+ 'have.length' ,
294+ ( initialCount as number ) + 1
295+ ) ;
296+ } ) ;
297+
298+ // Verify the Board tab is active (selected)
299+ cy . task ( 'log' , '[STEP 5] Verifying Board tab is active' ) ;
300+ DatabaseViewSelectors . activeViewTab ( ) . should ( 'exist' ) ;
301+ cy . get ( '[data-testid^="view-tab-"][data-state="active"]' )
302+ . should ( 'contain.text' , 'Board' ) ;
303+
304+ // Add Calendar view with same immediate check
305+ cy . task ( 'log' , '[STEP 6] Adding Calendar view' ) ;
306+ DatabaseViewSelectors . addViewButton ( ) . scrollIntoView ( ) . click ( { force : true } ) ;
307+ waitForReactUpdate ( 300 ) ;
308+
309+ cy . get ( '[role="menu"], [role="menuitem"]' , { timeout : 5000 } )
310+ . should ( 'be.visible' )
311+ . contains ( 'Calendar' )
312+ . click ( { force : true } ) ;
313+
314+ // Verify Calendar tab appears immediately
315+ cy . task ( 'log' , '[STEP 7] Verifying Calendar tab appears IMMEDIATELY' ) ;
316+ cy . get ( '@initialTabCount' ) . then ( ( initialCount ) => {
317+ cy . get ( '[data-testid^="view-tab-"]' , { timeout : 500 } ) . should (
318+ 'have.length' ,
319+ ( initialCount as number ) + 2
320+ ) ;
321+ } ) ;
322+
323+ // Step 8: Verify sidebar matches tab bar views
324+ cy . task ( 'log' , '[STEP 8] Verifying sidebar matches tab bar views' ) ;
325+ ensureSpaceExpanded ( spaceName ) ;
326+ waitForReactUpdate ( 500 ) ;
327+
328+ // Expand the database to see children
329+ PageSelectors . itemByName ( 'New Database' , { timeout : 10000 } ) . then ( ( $dbItem ) => {
330+ const expandToggle = $dbItem . find ( '[data-testid="outline-toggle-expand"]' ) ;
331+ if ( expandToggle . length > 0 ) {
332+ cy . wrap ( expandToggle ) . first ( ) . click ( { force : true } ) ;
333+ waitForReactUpdate ( 500 ) ;
334+ }
335+ } ) ;
336+
337+ // Verify sidebar contains all view types
338+ PageSelectors . itemByName ( 'New Database' , { timeout : 10000 } ) . within ( ( ) => {
339+ cy . contains ( 'Grid' ) . should ( 'exist' ) ;
340+ cy . contains ( 'Board' ) . should ( 'exist' ) ;
341+ cy . contains ( 'Calendar' ) . should ( 'exist' ) ;
342+ } ) ;
343+
344+ cy . task ( 'log' , '[TEST COMPLETE] Views appear immediately without sync delay' ) ;
345+ } ) ;
346+ } ) ;
228347} ) ;
0 commit comments