@@ -21,12 +21,16 @@ test.afterEach(async ({ page }) => {
2121 expect ( runtimeErrors . get ( page ) ?? [ ] , 'authenticated shell emitted runtime errors' ) . toEqual ( [ ] )
2222} )
2323
24- async function installAuthenticatedMatrixMock ( page : Page ) : Promise < void > {
25- await page . addInitScript ( ( ) => {
24+ async function installAuthenticatedMatrixMock (
25+ page : Page ,
26+ currentDeepLinks : string [ ] | null = null ,
27+ ) : Promise < void > {
28+ await page . addInitScript ( ( deepLinks ) => {
2629 const calls : IpcCall [ ] = [ ]
2730 const callbacks = new Map < number , ( ...args : unknown [ ] ) => void > ( )
2831 let nextCallbackId = 1
2932 let nextListenerId = 1
33+ let invitationJoined = false
3034
3135 const community = {
3236 id : '!mesh-e2e:mesh.test' ,
@@ -44,6 +48,14 @@ async function installAuthenticatedMatrixMock(page: Page): Promise<void> {
4448 role : 'member' ,
4549 joinedAt : '2026-07-24T00:00:00.000Z' ,
4650 }
51+ const invitedCommunity = {
52+ id : '!invited:mesh.test' ,
53+ name : 'Invited Mesh Community' ,
54+ description : 'Joined from the cold-start invitation' ,
55+ memberCount : 4 ,
56+ role : 'member' ,
57+ joinedAt : '2026-07-29T00:00:00.000Z' ,
58+ }
4759 const channels = [
4860 {
4961 id : '!general:mesh.test' ,
@@ -156,7 +168,20 @@ async function installAuthenticatedMatrixMock(page: Page): Promise<void> {
156168 warnings : [ ] ,
157169 }
158170 case 'matrix_list_communities' :
159- return [ community , secondCommunity ]
171+ return invitationJoined
172+ ? [ community , secondCommunity , invitedCommunity ]
173+ : [ community , secondCommunity ]
174+ case 'matrix_join_community' :
175+ if (
176+ args . roomOrAlias !== invitedCommunity . id
177+ || ! Array . isArray ( args . via )
178+ || args . via . length !== 1
179+ || args . via [ 0 ] !== 'mesh.test'
180+ ) {
181+ throw new Error ( 'Cold-start invitation was not forwarded to Matrix correctly' )
182+ }
183+ invitationJoined = true
184+ return invitedCommunity
160185 case 'matrix_room_is_encrypted' :
161186 return true
162187 case 'matrix_devices' :
@@ -214,7 +239,17 @@ async function installAuthenticatedMatrixMock(page: Page): Promise<void> {
214239 matrixProfile . displayName = String ( args . displayName )
215240 return { ...matrixProfile }
216241 case 'matrix_list_channels' :
217- return args . communityId === secondCommunity . id
242+ return args . communityId === invitedCommunity . id
243+ ? [
244+ {
245+ id : '!invited-general:mesh.test' ,
246+ communityId : invitedCommunity . id ,
247+ name : 'welcome' ,
248+ channelType : 'text' ,
249+ unreadCount : 0 ,
250+ } ,
251+ ]
252+ : args . communityId === secondCommunity . id
218253 ? secondCommunityChannels
219254 : channels
220255 case 'matrix_list_members' :
@@ -287,6 +322,8 @@ async function installAuthenticatedMatrixMock(page: Page): Promise<void> {
287322 case 'matrix_clear_composer_draft' :
288323 case 'plugin:event|unlisten' :
289324 return null
325+ case 'plugin:deep-link|get_current' :
326+ return deepLinks
290327 case 'matrix_wait_for_room_update' :
291328 // The real command long-polls the SDK room-update stream. Keeping
292329 // this promise pending models that boundary without a CPU-heavy loop.
@@ -343,18 +380,23 @@ async function installAuthenticatedMatrixMock(page: Page): Promise<void> {
343380 } ) . __TAURI_EVENT_PLUGIN_INTERNALS__ = {
344381 unregisterListener : ( ) => { } ,
345382 }
346- } )
383+ } , currentDeepLinks )
347384}
348385
349- async function openAuthenticatedShell ( page : Page ) : Promise < void > {
350- await installAuthenticatedMatrixMock ( page )
386+ async function openAuthenticatedShell (
387+ page : Page ,
388+ currentDeepLinks : string [ ] | null = null ,
389+ ) : Promise < void > {
390+ await installAuthenticatedMatrixMock ( page , currentDeepLinks )
351391 await page . goto ( '/' )
352392 await expect (
353393 page . getByRole ( 'navigation' , { name : 'Communities and direct messages' } ) ,
354394 ) . toBeVisible ( { timeout : 10_000 } )
355- await expect ( page . getByRole ( 'log' , { name : 'Messages in #general' } ) ) . toBeVisible ( {
356- timeout : 10_000 ,
357- } )
395+ if ( ! currentDeepLinks ?. length ) {
396+ await expect ( page . getByRole ( 'log' , { name : 'Messages in #general' } ) ) . toBeVisible ( {
397+ timeout : 10_000 ,
398+ } )
399+ }
358400}
359401
360402function ipcCalls ( page : Page ) : Promise < IpcCall [ ] > {
@@ -387,6 +429,31 @@ test.describe('authenticated desktop shell', () => {
387429 await expect ( page . getByText ( 'Anonymous' , { exact : true } ) ) . toHaveCount ( 0 )
388430 } )
389431
432+ test ( 'joins a cold-start Mesh invitation through Matrix and opens the community' , async ( { page } ) => {
433+ const invite =
434+ 'mesh://join?v=3&kind=matrix&room=!invited:mesh.test&via=mesh.test&service=https%3A%2F%2Fmatrix.mesh.test'
435+ await openAuthenticatedShell ( page , [ invite ] )
436+
437+ await expect . poll ( async ( ) => (
438+ ( await ipcCalls ( page ) ) . filter ( ( call ) => call . command === 'matrix_join_community' )
439+ ) ) . toEqual ( [ {
440+ command : 'matrix_join_community' ,
441+ args : {
442+ roomOrAlias : '!invited:mesh.test' ,
443+ via : [ 'mesh.test' ] ,
444+ } ,
445+ } ] )
446+ await expect (
447+ page . getByRole ( 'button' , { name : 'Invited Mesh Community' , exact : true } ) ,
448+ ) . toHaveAttribute ( 'aria-current' , 'true' )
449+ await expect ( page . getByRole ( 'button' , { name : 'Text room: welcome' } ) ) . toHaveAttribute (
450+ 'aria-current' ,
451+ 'page' ,
452+ )
453+ await expect ( page . getByRole ( 'dialog' , { name : 'Join a community' } ) ) . toHaveCount ( 0 )
454+
455+ } )
456+
390457 test ( '@a11y has no automated WCAG A/AA violations in the shell and settings' , async ( { page } ) => {
391458 await openAuthenticatedShell ( page )
392459 await expectNoWcagViolations ( page , 'Authenticated desktop shell' )
0 commit comments