@@ -5,15 +5,21 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
55Please see LICENSE in the repository root for full details.
66*/
77
8- import { expect , type Page , test , type Request } from "@playwright/test" ;
8+ import {
9+ expect ,
10+ type Page ,
11+ test ,
12+ type Request ,
13+ type Browser ,
14+ } from "@playwright/test" ;
915
1016import { SpaHelpers } from "./spa-helpers" ;
1117
12- test ( "One to One call using matrix rtc 2.0 aka sticky events" , async ( {
13- browser,
14- page,
15- browserName,
16- } ) = > {
18+ async function setupTwoUserSpaCall (
19+ browser : Browser ,
20+ page : Page ,
21+ browserName : string ,
22+ ) : Promise < { guestPage : Page } > {
1723 test . skip (
1824 browserName === "firefox" ,
1925 "The is test is not working on firefox CI environment. No mic/audio device inputs so cam/mic are disabled" ,
@@ -63,13 +69,49 @@ test("One to One call using matrix rtc 2.0 aka sticky events", async ({
6369 "Pevara" ,
6470 "2_0" ,
6571 ) ;
72+ // Assert both sides have sent sticky membership events
73+ expect ( androlHasSentStickyEvent ) . toEqual ( true ) ;
74+ expect ( pevaraHasSentStickyEvent ) . toEqual ( true ) ;
75+
76+ return { guestPage } ;
77+ }
78+
79+ test ( "One to One call using matrix rtc 2.0 aka sticky events" , async ( {
80+ browser,
81+ page,
82+ browserName,
83+ } ) => {
84+ const { guestPage } = await setupTwoUserSpaCall ( browser , page , browserName ) ;
6685
6786 await SpaHelpers . expectVideoTilesCount ( page , 2 ) ;
6887 await SpaHelpers . expectVideoTilesCount ( guestPage , 2 ) ;
88+ } ) ;
6989
70- // Assert both sides have sent sticky membership events
71- expect ( androlHasSentStickyEvent ) . toEqual ( true ) ;
72- expect ( pevaraHasSentStickyEvent ) . toEqual ( true ) ;
90+ // This issue occurs when a member leave but does not clean up their sticky event.
91+ // If they rejoin they will use a new stickye key (stickyKey = member.id = UUID())
92+ // We end up with two memberships with the same user and device id. This previously
93+ // was a impossible case since that would be the same state event. Now its possible.
94+ // We need to ALWAYS key by userId, deviceId and member.id. This test checks that.
95+ test ( "One to One rejoin after improper leave does not crash EC" , async ( {
96+ browser,
97+ page,
98+ browserName,
99+ } ) => {
100+ const { guestPage } = await setupTwoUserSpaCall ( browser , page , browserName ) ;
101+
102+ await SpaHelpers . expectVideoTilesCount ( page , 2 ) ;
103+ await SpaHelpers . expectVideoTilesCount ( guestPage , 2 ) ;
104+
105+ await guestPage . reload ( ) ;
106+ await expect ( guestPage . getByTestId ( "lobby_joinCall" ) ) . toBeVisible ( ) ;
107+
108+ // Check if rejoining with the same browser context (device) breaks EC.
109+ // This has happened on versions that do not consider the member.id as part of the key for a media tile.
110+ await guestPage . getByTestId ( "lobby_joinCall" ) . click ( ) ;
111+
112+ // We cannot use the `expectVideoTilesCount` helper here since one of them is expected to show waiting for media
113+ await expect ( page . getByTestId ( "videoTile" ) ) . toHaveCount ( 3 ) ;
114+ await expect ( guestPage . getByTestId ( "videoTile" ) ) . toHaveCount ( 2 ) ;
73115} ) ;
74116
75117function isStickySend ( url : string ) : boolean {
0 commit comments