@@ -30,7 +30,8 @@ function createIframeWithPowerSyncClient(
3030 dbFilename : string ,
3131 identifier : string ,
3232 vfs ?: WASQLiteVFS ,
33- waitForConnection ?: boolean
33+ waitForConnection ?: boolean ,
34+ configureMockResponses ?: boolean
3435) : IframeClientResult {
3536 const iframe = document . createElement ( 'iframe' ) ;
3637 // Make iframe visible for debugging
@@ -88,7 +89,7 @@ function createIframeWithPowerSyncClient(
8889 </div>
8990 <script type="module">
9091 import { setupPowerSyncInIframe } from '${ modulePath } ';
91- setupPowerSyncInIframe('${ dbFilename } ', '${ identifier } ', ${ vfs ? `'${ vfs } '` : 'undefined' } , ${ waitForConnection ? 'true' : 'false' } );
92+ setupPowerSyncInIframe('${ dbFilename } ', '${ identifier } ', ${ vfs ? `'${ vfs } '` : 'undefined' } , ${ waitForConnection ? 'true' : 'false' } , ${ configureMockResponses ? 'true' : 'false' } );
9293 </script>
9394</body>
9495</html>` ;
@@ -296,7 +297,7 @@ function createIframeWithPowerSyncClient(
296297 */
297298function createMultipleTabsTest ( vfs ?: WASQLiteVFS ) {
298299 const vfsName = vfs || 'IndexedDB' ;
299- describe ( `Multiple Tabs with Iframes (${ vfsName } )` , { sequential : true , timeout : 60_000 } , ( ) => {
300+ describe ( `Multiple Tabs with Iframes (${ vfsName } )` , { sequential : true , timeout : 30_000 } , ( ) => {
300301 const dbFilename = `test-multi-tab-${ uuid ( ) } .db` ;
301302
302303 // Number of tabs to create
@@ -305,8 +306,20 @@ function createMultipleTabsTest(vfs?: WASQLiteVFS) {
305306 const MIDDLE_TAB_INDEX = 49 ;
306307
307308 it ( 'should handle opening and closing many tabs quickly' , async ( ) => {
309+ // Step 0: Create an iframe to set up PowerSync and configure mock responses (401)
310+ const setupIdentifier = `setup-${ uuid ( ) } ` ;
311+ const setupIframe = createIframeWithPowerSyncClient ( dbFilename , setupIdentifier , vfs , false , true ) ;
312+ onTestFinished ( async ( ) => {
313+ try {
314+ await setupIframe . cleanup ( ) ;
315+ } catch ( e ) {
316+ // Ignore cleanup errors
317+ }
318+ } ) ;
319+ // Wait for the setup iframe to be ready (this ensures PowerSync is initialized and mock responses are configured)
320+ await setupIframe . ready ;
308321 // Step 1: Open 100 tabs (don't wait for them to be ready)
309- const tabResults : IframeClientResult [ ] = [ ] ;
322+ const tabResults : IframeClientResult [ ] = [ setupIframe ] ;
310323
311324 for ( let i = 0 ; i < NUM_TABS ; i ++ ) {
312325 const identifier = `tab-${ i } ` ;
@@ -323,7 +336,8 @@ function createMultipleTabsTest(vfs?: WASQLiteVFS) {
323336 } ) ;
324337 }
325338
326- expect ( tabResults . length ) . toBe ( NUM_TABS ) ;
339+ // Total iframes: 1 setup + NUM_TABS tabs
340+ expect ( tabResults . length ) . toBe ( NUM_TABS + 1 ) ;
327341
328342 // Verify all iframes are created (they're created immediately)
329343 for ( const result of tabResults ) {
@@ -333,32 +347,37 @@ function createMultipleTabsTest(vfs?: WASQLiteVFS) {
333347 // Step 2: Wait 1 second
334348 await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) ) ;
335349
336- // Step 3: Close all tabs except the middle (50th) tab
350+ // Step 3: Close all tabs except the setup iframe (index 0) and the middle (50th) tab
351+ // The middle tab is at index 1 + MIDDLE_TAB_INDEX (since index 0 is the setup iframe)
352+ const middleTabArrayIndex = 1 + MIDDLE_TAB_INDEX ;
337353 const tabsToClose : IframeClientResult [ ] = [ ] ;
338- for ( let i = 0 ; i < NUM_TABS ; i ++ ) {
339- if ( i !== MIDDLE_TAB_INDEX ) {
354+ for ( let i = 0 ; i < tabResults . length ; i ++ ) {
355+ // Skip the setup iframe (index 0) and the middle tab
356+ if ( i !== 0 && i !== middleTabArrayIndex ) {
340357 tabsToClose . push ( tabResults [ i ] ) ;
341358 }
342359 }
343360
344- // Close all tabs except the middle one simultaneously (without waiting for ready)
361+ // Close all tabs except the setup iframe and middle one simultaneously (without waiting for ready)
345362 const closePromises = tabsToClose . map ( ( result ) => result . cleanup ( ) ) ;
346363 await Promise . all ( closePromises ) ;
347364
348365 // Verify closed tabs are removed
349- for ( let i = 0 ; i < NUM_TABS ; i ++ ) {
350- if ( i !== MIDDLE_TAB_INDEX ) {
366+ for ( let i = 0 ; i < tabResults . length ; i ++ ) {
367+ if ( i !== 0 && i !== middleTabArrayIndex ) {
351368 expect ( tabResults [ i ] . iframe . isConnected ) . toBe ( false ) ;
352369 expect ( document . body . contains ( tabResults [ i ] . iframe ) ) . toBe ( false ) ;
353370 }
354371 }
355372
356- // Verify the middle tab is still present
357- expect ( tabResults [ MIDDLE_TAB_INDEX ] . iframe . isConnected ) . toBe ( true ) ;
358- expect ( document . body . contains ( tabResults [ MIDDLE_TAB_INDEX ] . iframe ) ) . toBe ( true ) ;
373+ // Verify the setup iframe and middle tab are still present
374+ expect ( tabResults [ 0 ] . iframe . isConnected ) . toBe ( true ) ;
375+ expect ( document . body . contains ( tabResults [ 0 ] . iframe ) ) . toBe ( true ) ;
376+ expect ( tabResults [ middleTabArrayIndex ] . iframe . isConnected ) . toBe ( true ) ;
377+ expect ( document . body . contains ( tabResults [ middleTabArrayIndex ] . iframe ) ) . toBe ( true ) ;
359378
360379 // Step 4: Wait for the middle tab to be ready, then execute a test query to verify its DB is still functional
361- const middleTabClient = await tabResults [ MIDDLE_TAB_INDEX ] . ready ;
380+ const middleTabClient = await tabResults [ middleTabArrayIndex ] . ready ;
362381 const queryResult = await middleTabClient . executeQuery ( 'SELECT 1 as value' ) ;
363382
364383 // Verify the query result
0 commit comments