Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 7587348

Browse files
authored
Merge branch 'develop' into weblate-element-web-matrix-react-sdk
2 parents 4d446b4 + a009f80 commit 7587348

File tree

151 files changed

+2752
-1617
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

151 files changed

+2752
-1617
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,6 @@ Now the yarn commands should work as normal.
211211
### End-to-End tests
212212

213213
Make sure you've got your Element development server running (by doing `yarn
214-
start` in element-web), and then in this project, run `yarn run e2etests`. See
215-
[`test/end-to-end-tests/README.md`](https://github.com/matrix-org/matrix-react-sdk/blob/develop/test/end-to-end-tests/README.md)
214+
start` in element-web), and then in this project, run `yarn run test:cypress`. See
215+
[`docs/cypress.md`](https://github.com/matrix-org/matrix-react-sdk/blob/develop/docs/cypress.md)
216216
for more information.

cypress.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
"runMode": 2,
99
"openMode": 0
1010
},
11+
"defaultCommandTimeout": 10000,
1112
"chromeWebSecurity": false
1213
}

cypress/global.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17+
import "../src/@types/global";
18+
import "../src/@types/svg";
19+
import "../src/@types/raw-loader";
1720
import "matrix-js-sdk/src/@types/global";
1821
import type {
1922
MatrixClient,
@@ -28,11 +31,13 @@ import type {
2831
} from "matrix-js-sdk/src/matrix";
2932
import type { MatrixDispatcher } from "../src/dispatcher/dispatcher";
3033
import type PerformanceMonitor from "../src/performance";
34+
import type SettingsStore from "../src/settings/SettingsStore";
3135

3236
declare global {
3337
// eslint-disable-next-line @typescript-eslint/no-namespace
3438
namespace Cypress {
3539
interface ApplicationWindow {
40+
mxSettingsStore: typeof SettingsStore;
3641
mxMatrixClientPeg: {
3742
matrixClient?: MatrixClient;
3843
};

cypress/integration/10-user-view/user-view.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe("UserView", () => {
2727
synapse = data;
2828

2929
cy.initTestUser(synapse, "Violet");
30-
cy.getBot(synapse, "Usman").as("bot");
30+
cy.getBot(synapse, { displayName: "Usman" }).as("bot");
3131
});
3232
});
3333

cypress/integration/11-room-directory/room-directory.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe("Room Directory", () => {
2727
synapse = data;
2828

2929
cy.initTestUser(synapse, "Ray");
30-
cy.getBot(synapse, "Paul").as("bot");
30+
cy.getBot(synapse, { displayName: "Paul" }).as("bot");
3131
});
3232
});
3333

cypress/integration/12-spotlight/spotlight.spec.ts

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,11 @@ describe("Spotlight", () => {
128128
cy.startSynapse("default").then(data => {
129129
synapse = data;
130130
cy.initTestUser(synapse, "Jim").then(() =>
131-
cy.getBot(synapse, bot1Name).then(_bot1 => {
131+
cy.getBot(synapse, { displayName: bot1Name }).then(_bot1 => {
132132
bot1 = _bot1;
133133
}),
134134
).then(() =>
135-
cy.getBot(synapse, bot2Name).then(_bot2 => {
135+
cy.getBot(synapse, { displayName: bot2Name }).then(_bot2 => {
136136
// eslint-disable-next-line @typescript-eslint/no-unused-vars
137137
bot2 = _bot2;
138138
}),
@@ -156,6 +156,7 @@ describe("Spotlight", () => {
156156
});
157157

158158
afterEach(() => {
159+
cy.visit("/#/home");
159160
cy.stopSynapse(synapse);
160161
});
161162

@@ -264,6 +265,47 @@ describe("Spotlight", () => {
264265
});
265266
});
266267

268+
it("should find group DMs by usernames or user ids", () => {
269+
// First we want to share a room with both bots to ensure we’ve got their usernames cached
270+
cy.inviteUser(room1Id, bot2.getUserId());
271+
272+
// Starting a DM with ByteBot (will be turned into a group dm later)
273+
cy.openSpotlightDialog().within(() => {
274+
cy.spotlightFilter(Filter.People);
275+
cy.spotlightSearch().clear().type(bot2Name);
276+
cy.spotlightResults().should("have.length", 1);
277+
cy.spotlightResults().eq(0).should("contain", bot2Name);
278+
cy.spotlightResults().eq(0).click();
279+
}).then(() => {
280+
cy.roomHeaderName().should("contain", bot2Name);
281+
cy.get(".mx_RoomSublist[aria-label=People]").should("contain", bot2Name);
282+
});
283+
284+
// Invite BotBob into existing DM with ByteBot
285+
cy.getDmRooms(bot2.getUserId()).then(dmRooms => dmRooms[0])
286+
.then(groupDmId => cy.inviteUser(groupDmId, bot1.getUserId()))
287+
.then(() => {
288+
cy.roomHeaderName().should("contain", `${bot1Name} and ${bot2Name}`);
289+
cy.get(".mx_RoomSublist[aria-label=People]").should("contain", `${bot1Name} and ${bot2Name}`);
290+
});
291+
292+
// Search for BotBob by id, should return group DM and user
293+
cy.openSpotlightDialog().within(() => {
294+
cy.spotlightFilter(Filter.People);
295+
cy.spotlightSearch().clear().type(bot1.getUserId());
296+
cy.spotlightResults().should("have.length", 2);
297+
cy.spotlightResults().eq(0).should("contain", `${bot1Name} and ${bot2Name}`);
298+
});
299+
300+
// Search for ByteBot by id, should return group DM and user
301+
cy.openSpotlightDialog().within(() => {
302+
cy.spotlightFilter(Filter.People);
303+
cy.spotlightSearch().clear().type(bot2.getUserId());
304+
cy.spotlightResults().should("have.length", 2);
305+
cy.spotlightResults().eq(0).should("contain", `${bot1Name} and ${bot2Name}`);
306+
});
307+
});
308+
267309
it("should allow opening group chat dialog", () => {
268310
cy.openSpotlightDialog().within(() => {
269311
cy.spotlightFilter(Filter.People);
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
/// <reference types="cypress" />
18+
19+
import { MessageEvent } from "matrix-events-sdk";
20+
21+
import type { ISendEventResponse } from "matrix-js-sdk/src/@types/requests";
22+
import type { EventType } from "matrix-js-sdk/src/@types/event";
23+
import type { MatrixClient } from "matrix-js-sdk/src/client";
24+
import { SynapseInstance } from "../../plugins/synapsedocker";
25+
import { SettingLevel } from "../../../src/settings/SettingLevel";
26+
import Chainable = Cypress.Chainable;
27+
28+
// The avatar size used in the timeline
29+
const AVATAR_SIZE = 30;
30+
// The resize method used in the timeline
31+
const AVATAR_RESIZE_METHOD = "crop";
32+
33+
const ROOM_NAME = "Test room";
34+
const OLD_AVATAR = "avatar_image1";
35+
const NEW_AVATAR = "avatar_image2";
36+
const OLD_NAME = "Alan";
37+
const NEW_NAME = "Alan (away)";
38+
39+
const getEventTilesWithBodies = (): Chainable<JQuery> => {
40+
return cy.get(".mx_EventTile").filter((_i, e) => e.getElementsByClassName("mx_EventTile_body").length > 0);
41+
};
42+
43+
const expectDisplayName = (e: JQuery<HTMLElement>, displayName: string): void => {
44+
expect(e.find(".mx_DisambiguatedProfile_displayName").text()).to.equal(displayName);
45+
};
46+
47+
const expectAvatar = (e: JQuery<HTMLElement>, avatarUrl: string): void => {
48+
cy.getClient().then((cli: MatrixClient) => {
49+
expect(e.find(".mx_BaseAvatar_image").attr("src")).to.equal(
50+
// eslint-disable-next-line no-restricted-properties
51+
cli.mxcUrlToHttp(avatarUrl, AVATAR_SIZE, AVATAR_SIZE, AVATAR_RESIZE_METHOD),
52+
);
53+
});
54+
};
55+
56+
const sendEvent = (roomId: string): Chainable<ISendEventResponse> => {
57+
return cy.sendEvent(
58+
roomId,
59+
null,
60+
"m.room.message" as EventType,
61+
MessageEvent.from("Message").serialize().content,
62+
);
63+
};
64+
65+
describe("Timeline", () => {
66+
let synapse: SynapseInstance;
67+
68+
let roomId: string;
69+
70+
let oldAvatarUrl: string;
71+
let newAvatarUrl: string;
72+
73+
describe("useOnlyCurrentProfiles", () => {
74+
beforeEach(() => {
75+
cy.startSynapse("default").then(data => {
76+
synapse = data;
77+
cy.initTestUser(synapse, OLD_NAME).then(() =>
78+
cy.window({ log: false }).then(() => {
79+
cy.createRoom({ name: ROOM_NAME }).then(_room1Id => {
80+
roomId = _room1Id;
81+
});
82+
}),
83+
).then(() => {
84+
cy.uploadContent(OLD_AVATAR).then((url) => {
85+
oldAvatarUrl = url;
86+
cy.setAvatarUrl(url);
87+
});
88+
}).then(() => {
89+
cy.uploadContent(NEW_AVATAR).then((url) => {
90+
newAvatarUrl = url;
91+
});
92+
});
93+
});
94+
});
95+
96+
afterEach(() => {
97+
cy.stopSynapse(synapse);
98+
});
99+
100+
it("should show historical profiles if disabled", () => {
101+
cy.setSettingValue("useOnlyCurrentProfiles", null, SettingLevel.ACCOUNT, false);
102+
sendEvent(roomId);
103+
cy.setDisplayName("Alan (away)");
104+
cy.setAvatarUrl(newAvatarUrl);
105+
// XXX: If we send the second event too quickly, there won't be
106+
// enough time for the client to register the profile change
107+
cy.wait(500);
108+
sendEvent(roomId);
109+
cy.viewRoomByName(ROOM_NAME);
110+
111+
const events = getEventTilesWithBodies();
112+
113+
events.should("have.length", 2);
114+
events.each((e, i) => {
115+
if (i === 0) {
116+
expectDisplayName(e, OLD_NAME);
117+
expectAvatar(e, oldAvatarUrl);
118+
} else if (i === 1) {
119+
expectDisplayName(e, NEW_NAME);
120+
expectAvatar(e, newAvatarUrl);
121+
}
122+
});
123+
});
124+
125+
it("should not show historical profiles if enabled", () => {
126+
cy.setSettingValue("useOnlyCurrentProfiles", null, SettingLevel.ACCOUNT, true);
127+
sendEvent(roomId);
128+
cy.setDisplayName(NEW_NAME);
129+
cy.setAvatarUrl(newAvatarUrl);
130+
// XXX: If we send the second event too quickly, there won't be
131+
// enough time for the client to register the profile change
132+
cy.wait(500);
133+
sendEvent(roomId);
134+
cy.viewRoomByName(ROOM_NAME);
135+
136+
const events = getEventTilesWithBodies();
137+
138+
events.should("have.length", 2);
139+
events.each((e) => {
140+
expectDisplayName(e, NEW_NAME);
141+
expectAvatar(e, newAvatarUrl);
142+
});
143+
});
144+
});
145+
});

cypress/integration/5-threads/threads.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ describe("Threads", () => {
7373

7474
it("should be usable for a conversation", () => {
7575
let bot: MatrixClient;
76-
cy.getBot(synapse, "BotBob").then(_bot => {
76+
cy.getBot(synapse, { displayName: "BotBob" }).then(_bot => {
7777
bot = _bot;
7878
});
7979

cypress/integration/6-spaces/spaces.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ describe("Spaces", () => {
167167

168168
it("should allow user to invite another to a space", () => {
169169
let bot: MatrixClient;
170-
cy.getBot(synapse, "BotBob").then(_bot => {
170+
cy.getBot(synapse, { displayName: "BotBob" }).then(_bot => {
171171
bot = _bot;
172172
});
173173

@@ -202,7 +202,7 @@ describe("Spaces", () => {
202202
});
203203
getSpacePanelButton("My Space").should("exist");
204204

205-
cy.getBot(synapse, "BotBob").then({ timeout: 10000 }, async bot => {
205+
cy.getBot(synapse, { displayName: "BotBob" }).then({ timeout: 10000 }, async bot => {
206206
const { room_id: roomId } = await bot.createRoom(spaceCreateOptions("Space Space"));
207207
await bot.invite(roomId, user.userId);
208208
});

0 commit comments

Comments
 (0)