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

Commit f60f7a1

Browse files
authored
Display redacted body on ThreadView in the same way as normal messages (#9016)
1 parent 6fa00a2 commit f60f7a1

File tree

3 files changed

+235
-58
lines changed

3 files changed

+235
-58
lines changed

cypress/e2e/polls/polls.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ limitations under the License.
1818

1919
import { HomeserverInstance } from "../../plugins/utils/homeserver";
2020
import { MatrixClient } from "../../global";
21+
import { SettingLevel } from "../../../src/settings/SettingLevel";
22+
import { Layout } from "../../../src/settings/enums/Layout";
2123
import Chainable = Cypress.Chainable;
2224

2325
const hidePercyCSS = ".mx_MessageTimestamp, .mx_RoomView_myReadMarker { visibility: hidden !important; }";
@@ -313,6 +315,18 @@ describe("Polls", () => {
313315
// and thread view
314316
cy.get(".mx_ThreadView .mx_MPollBody_totalVotes").should("contain", "2 votes cast");
315317

318+
// Take snapshots of poll on ThreadView
319+
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.Bubble);
320+
cy.get(".mx_ThreadView .mx_EventTile[data-layout='bubble']").should("be.visible");
321+
cy.get(".mx_ThreadView").percySnapshotElement("ThreadView with a poll on bubble layout", {
322+
percyCSS: hidePercyCSS,
323+
});
324+
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.Group);
325+
cy.get(".mx_ThreadView .mx_EventTile[data-layout='group']").should("be.visible");
326+
cy.get(".mx_ThreadView").percySnapshotElement("ThreadView with a poll on group layout", {
327+
percyCSS: hidePercyCSS,
328+
});
329+
316330
cy.get(".mx_RoomView_body").within(() => {
317331
// vote 'Maybe' in the main timeline poll
318332
getPollOption(pollId, pollParams.options[2]).click("topLeft");

cypress/e2e/threads/threads.spec.ts

Lines changed: 187 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { HomeserverInstance } from "../../plugins/utils/homeserver";
2020
import { MatrixClient } from "../../global";
2121
import { SettingLevel } from "../../../src/settings/SettingLevel";
2222
import { Layout } from "../../../src/settings/enums/Layout";
23+
import Chainable = Cypress.Chainable;
2324

2425
describe("Threads", () => {
2526
let homeserver: HomeserverInstance;
@@ -64,6 +65,9 @@ describe("Threads", () => {
6465
// --MessageTimestamp-color = #acacac = rgb(172, 172, 172)
6566
// See: _MessageTimestamp.pcss
6667
const MessageTimestampColor = "rgb(172, 172, 172)";
68+
const ThreadViewGroupSpacingStart = "56px"; // --ThreadView_group_spacing-start
69+
// Exclude timestamp and read marker from snapshots
70+
const percyCSS = ".mx_MessageTimestamp, .mx_RoomView_myReadMarker { visibility: hidden !important; }";
6771

6872
// User sends message
6973
cy.get(".mx_RoomView_body .mx_BasicMessageComposer_input").type("Hello Mr. Bot{enter}");
@@ -90,9 +94,29 @@ describe("Threads", () => {
9094
});
9195

9296
// User asserts timeline thread summary visible & clicks it
93-
cy.get(".mx_RoomView_body .mx_ThreadSummary .mx_ThreadSummary_sender").should("contain", "BotBob");
94-
cy.get(".mx_RoomView_body .mx_ThreadSummary .mx_ThreadSummary_content").should("contain", "Hello there");
95-
cy.get(".mx_RoomView_body .mx_ThreadSummary").click();
97+
cy.get(".mx_RoomView_body").within(() => {
98+
cy.get(".mx_ThreadSummary .mx_ThreadSummary_sender").should("contain", "BotBob");
99+
cy.get(".mx_ThreadSummary .mx_ThreadSummary_content").should("contain", "Hello there");
100+
cy.get(".mx_ThreadSummary").click();
101+
});
102+
103+
// Wait until the both messages are read
104+
cy.get(".mx_ThreadView .mx_EventTile_last[data-layout=group]").within(() => {
105+
cy.get(".mx_EventTile_line .mx_MTextBody").should("have.text", MessageLong);
106+
cy.get(".mx_ReadReceiptGroup .mx_BaseAvatar_image").should("be.visible");
107+
108+
// Make sure the CSS style for spacing is applied to mx_EventTile_line on group/modern layout
109+
cy.get(".mx_EventTile_line").should("have.css", "padding-inline-start", ThreadViewGroupSpacingStart);
110+
});
111+
112+
// Take Percy snapshots in group layout and bubble layout (IRC layout is not available on ThreadView)
113+
cy.get(".mx_ThreadView").percySnapshotElement("Initial ThreadView on group layout", { percyCSS });
114+
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.Bubble);
115+
cy.get(".mx_ThreadView .mx_EventTile[data-layout='bubble']").should("be.visible");
116+
cy.get(".mx_ThreadView").percySnapshotElement("Initial ThreadView on bubble layout", { percyCSS });
117+
118+
// Set the group layout
119+
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.Group);
96120

97121
cy.get(".mx_ThreadView .mx_EventTile[data-layout='group'].mx_EventTile_last").within(() => {
98122
// Wait until the messages are rendered
@@ -130,8 +154,17 @@ describe("Threads", () => {
130154
);
131155

132156
// User asserts summary was updated correctly
133-
cy.get(".mx_RoomView_body .mx_ThreadSummary .mx_ThreadSummary_sender").should("contain", "Tom");
134-
cy.get(".mx_RoomView_body .mx_ThreadSummary .mx_ThreadSummary_content").should("contain", "Test");
157+
cy.get(".mx_RoomView_body .mx_ThreadSummary").within(() => {
158+
cy.get(".mx_ThreadSummary_sender").should("contain", "Tom");
159+
cy.get(".mx_ThreadSummary_content").should("contain", "Test");
160+
});
161+
162+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
163+
// Check reactions and hidden events
164+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
165+
166+
// Enable hidden events to make the event for reaction displayed
167+
cy.setSettingValue("showHiddenEventsInTimeline", null, SettingLevel.DEVICE, true);
135168

136169
// User reacts to message instead
137170
cy.contains(".mx_ThreadView .mx_EventTile .mx_EventTile_line", "Hello there")
@@ -142,6 +175,58 @@ describe("Threads", () => {
142175
cy.contains('[role="menuitem"]', "👋").click();
143176
});
144177

178+
cy.get(".mx_ThreadView").within(() => {
179+
// Make sure the CSS style for spacing is applied to mx_ReactionsRow on group/modern layout
180+
cy.get(".mx_EventTile[data-layout=group] .mx_ReactionsRow").should(
181+
"have.css",
182+
"margin-inline-start",
183+
ThreadViewGroupSpacingStart,
184+
);
185+
186+
// Make sure the CSS style for spacing is applied to the hidden event on group/modern layout
187+
cy.get(
188+
".mx_GenericEventListSummary[data-layout=group] .mx_EventTile_info.mx_EventTile_last " +
189+
".mx_EventTile_line",
190+
).should("have.css", "padding-inline-start", ThreadViewGroupSpacingStart);
191+
});
192+
193+
// Take Percy snapshot of group layout (IRC layout is not available on ThreadView)
194+
cy.get(".mx_ThreadView").percySnapshotElement("ThreadView with reaction and a hidden event on group layout", {
195+
percyCSS,
196+
});
197+
198+
// Enable bubble layout
199+
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.Bubble);
200+
201+
// Make sure the CSS style for spacing is applied to the hidden event on bubble layout
202+
cy.get(
203+
".mx_ThreadView .mx_GenericEventListSummary[data-layout=bubble] .mx_EventTile_info.mx_EventTile_last",
204+
).within(() => {
205+
cy.get(".mx_EventTile_line .mx_EventTile_content")
206+
// 76px: ThreadViewGroupSpacingStart + 14px + 6px
207+
// 14px: avatar width
208+
// See: _EventTile.pcss
209+
.should("have.css", "margin-inline-start", "76px");
210+
cy.get(".mx_EventTile_line")
211+
// Make sure the margin is NOT applied to mx_EventTile_line
212+
.should("have.css", "margin-inline-start", "0px");
213+
});
214+
215+
// Take Percy snapshot of bubble layout
216+
cy.get(".mx_ThreadView").percySnapshotElement("ThreadView with reaction and a hidden event on bubble layout", {
217+
percyCSS,
218+
});
219+
220+
// Disable hidden events
221+
cy.setSettingValue("showHiddenEventsInTimeline", null, SettingLevel.DEVICE, false);
222+
223+
// Reset to the group layout
224+
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.Group);
225+
226+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
227+
// Check redactions
228+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
229+
145230
// User redacts their prior response
146231
cy.contains(".mx_ThreadView .mx_EventTile .mx_EventTile_line", "Test")
147232
.find('[aria-label="Options"]')
@@ -153,6 +238,23 @@ describe("Threads", () => {
153238
cy.contains(".mx_Dialog_primary", "Remove").click();
154239
});
155240

241+
// Wait until the response is redacted
242+
cy.get(".mx_ThreadView .mx_EventTile_last .mx_EventTile_receiptSent").should("be.visible");
243+
244+
// Take Percy snapshots in group layout and bubble layout (IRC layout is not available on ThreadView)
245+
cy.get(".mx_ThreadView .mx_EventTile[data-layout='group']").should("be.visible");
246+
cy.get(".mx_ThreadView").percySnapshotElement("ThreadView with redacted messages on group layout", {
247+
percyCSS,
248+
});
249+
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.Bubble);
250+
cy.get(".mx_ThreadView .mx_EventTile[data-layout='bubble']").should("be.visible");
251+
cy.get(".mx_ThreadView").percySnapshotElement("ThreadView with redacted messages on bubble layout", {
252+
percyCSS,
253+
});
254+
255+
// Set the group layout
256+
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.Group);
257+
156258
// User asserts summary was updated correctly
157259
cy.get(".mx_RoomView_body .mx_ThreadSummary .mx_ThreadSummary_sender").should("contain", "BotBob");
158260
cy.get(".mx_RoomView_body .mx_ThreadSummary .mx_ThreadSummary_content").should("contain", "Hello there");
@@ -182,9 +284,15 @@ describe("Threads", () => {
182284
cy.get(".mx_EventTile_body").should("contain", "Hello Mr. Bot");
183285
cy.get(".mx_ThreadSummary_content").should("contain", "How are things?");
184286

287+
// Check the number of the replies
288+
cy.get(".mx_ThreadPanel_replies_amount").should("have.text", "2");
289+
185290
// Check the colour of timestamp on thread list
186291
cy.get(".mx_EventTile_details .mx_MessageTimestamp").should("have.css", "color", MessageTimestampColor);
187292

293+
// Make sure the notification dot is visible
294+
cy.get(".mx_NotificationBadge_visible").should("be.visible");
295+
188296
// User opens thread via threads list
189297
cy.get(".mx_EventTile_line").click();
190298
});
@@ -281,6 +389,80 @@ describe("Threads", () => {
281389
cy.get(".mx_ThreadView .mx_MVoiceMessageBody").should("have.length", 1);
282390
});
283391

392+
it("should send location and reply to the location on ThreadView", () => {
393+
// See: location.spec.ts
394+
const selectLocationShareTypeOption = (shareType: string): Chainable<JQuery> => {
395+
return cy.get(`[data-test-id="share-location-option-${shareType}"]`);
396+
};
397+
const submitShareLocation = (): void => {
398+
cy.get('[data-testid="location-picker-submit-button"]').click();
399+
};
400+
401+
let bot: MatrixClient;
402+
cy.getBot(homeserver, {
403+
displayName: "BotBob",
404+
autoAcceptInvites: false,
405+
}).then((_bot) => {
406+
bot = _bot;
407+
});
408+
409+
let roomId: string;
410+
cy.createRoom({}).then((_roomId) => {
411+
roomId = _roomId;
412+
cy.inviteUser(roomId, bot.getUserId());
413+
bot.joinRoom(roomId);
414+
cy.visit("/#/room/" + roomId);
415+
});
416+
417+
// Exclude timestamp, read marker, and mapboxgl-map from snapshots
418+
const percyCSS =
419+
".mx_MessageTimestamp, .mx_RoomView_myReadMarker, .mapboxgl-map { visibility: hidden !important; }";
420+
421+
// User sends message
422+
cy.get(".mx_RoomView_body .mx_BasicMessageComposer_input").type("Hello Mr. Bot{enter}");
423+
424+
// Wait for message to send, get its ID and save as @threadId
425+
cy.contains(".mx_RoomView_body .mx_EventTile[data-scroll-tokens]", "Hello Mr. Bot")
426+
.invoke("attr", "data-scroll-tokens")
427+
.as("threadId");
428+
429+
// Bot starts thread
430+
cy.get<string>("@threadId").then((threadId) => {
431+
bot.sendMessage(roomId, threadId, {
432+
body: "Hello there",
433+
msgtype: "m.text",
434+
});
435+
});
436+
437+
// User clicks thread summary
438+
cy.get(".mx_RoomView_body .mx_ThreadSummary").click();
439+
440+
// User sends location on ThreadView
441+
cy.get(".mx_ThreadView").should("exist");
442+
cy.openMessageComposerOptions(true).find("[aria-label='Location']").click();
443+
selectLocationShareTypeOption("Pin").click();
444+
cy.get("#mx_LocationPicker_map").click("center");
445+
submitShareLocation();
446+
cy.get(".mx_ThreadView .mx_EventTile_last .mx_MLocationBody", { timeout: 10000 }).should("exist");
447+
448+
// User replies to the location
449+
cy.get(".mx_ThreadView").within(() => {
450+
cy.get(".mx_EventTile_last")
451+
.realHover()
452+
.within(() => {
453+
cy.get("[aria-label='Reply']").click({ force: false });
454+
});
455+
456+
cy.get(".mx_BasicMessageComposer_input").type("Please come here.{enter}");
457+
458+
// Wait until the reply is sent
459+
cy.get(".mx_EventTile_last .mx_EventTile_receiptSent").should("be.visible");
460+
});
461+
462+
// Take a snapshot of reply to the shared location
463+
cy.get(".mx_ThreadView").percySnapshotElement("Reply to the location on ThreadView", { percyCSS });
464+
});
465+
284466
it("right panel behaves correctly", () => {
285467
// Create room
286468
let roomId: string;

0 commit comments

Comments
 (0)