diff --git a/playwright/e2e/threads/threads.spec.ts b/playwright/e2e/threads/threads.spec.ts index 34fe287d47..5e32516646 100644 --- a/playwright/e2e/threads/threads.spec.ts +++ b/playwright/e2e/threads/threads.spec.ts @@ -447,4 +447,72 @@ test.describe("Threads", () => { await expect(locator.locator(".mx_EventTile").first().getByText("Hello Mr. Bot")).toBeAttached(); await expect(locator.locator(".mx_EventTile").last().getByText("Hello Mr. User")).toBeAttached(); }); + + test("navigate through right panel", async ({ page, app, user }) => { + // Create room + const roomId = await app.client.createRoom({}); + await page.goto("/#/room/" + roomId); + + /** + * Send a message in the main timeline + * @param message + */ + const sendMessage = async (message: string) => { + const messageComposer = page.getByRole("region", { name: "Message composer" }); + const textbox = messageComposer.getByRole("textbox", { name: "Send a messageā€¦" }); + await textbox.fill(message); + await textbox.press("Enter"); + }; + + /** + * Create a thread from the rootMessage and send a message in the thread + * @param rootMessage + * @param threadMessage + */ + const createThread = async (rootMessage: string, threadMessage: string) => { + // First create a thread + const roomViewBody = page.locator(".mx_RoomView_body"); + const messageTile = roomViewBody + .locator(".mx_EventTile[data-scroll-tokens]") + .filter({ hasText: rootMessage }); + await messageTile.hover(); + await messageTile.getByRole("button", { name: "Reply in thread" }).click(); + await expect(page.locator(".mx_ThreadView_timelinePanelWrapper")).toHaveCount(1); + + // Send a message in the thread + const threadPanel = page.locator(".mx_ThreadPanel"); + const textbox = threadPanel.getByRole("textbox", { name: "Send a messageā€¦" }); + await textbox.fill(threadMessage); + await textbox.press("Enter"); + await expect(threadPanel.locator(".mx_EventTile_last").getByText(threadMessage)).toBeVisible(); + // Close thread + await threadPanel.getByRole("button", { name: "Close" }).click(); + }; + + await sendMessage("Hello Mr. Bot"); + await sendMessage("Hello again Mr. Bot"); + await createThread("Hello Mr. Bot", "Hello Mr. User in a thread"); + await createThread("Hello again Mr. Bot", "Hello again Mr. User in a thread"); + + // Open thread panel + await page.getByRole("button", { name: "Threads" }).click(); + const threadPanel = page.locator(".mx_ThreadPanel"); + await expect( + threadPanel.locator(".mx_EventTile_last").getByText("Hello again Mr. User in a thread"), + ).toBeVisible(); + + // Open threads list + await threadPanel.getByRole("button", { name: "Threads" }).click(); + const rightPanel = page.locator(".mx_RightPanel"); + // Check that the threads are listed + await expect(rightPanel.locator(".mx_EventTile").getByText("Hello Mr. User in a thread")).toBeVisible(); + await expect(rightPanel.locator(".mx_EventTile").getByText("Hello again Mr. User in a thread")).toBeVisible(); + + // Open the first thread + await rightPanel.locator(".mx_EventTile").getByText("Hello Mr. User in a thread").click(); + await expect(rightPanel.locator(".mx_EventTile").getByText("Hello Mr. User in a thread")).toBeVisible(); + await expect( + rightPanel.locator(".mx_EventTile").getByText("Hello again Mr. User in a thread"), + ).not.toBeVisible(); + }); }); diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index f9d4604972..a15ddbf774 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -707,6 +707,8 @@ export class RoomView extends React.Component { newState.initialEventPixelOffset = undefined; const thread = initialEvent?.getThread(); + // Handle the use case of a link to a thread message + // ie: #/room/roomId/eventId (eventId of a thread message) if (thread?.rootEvent && !initialEvent?.isThreadRoot) { dis.dispatch({ action: Action.ShowThread, @@ -719,16 +721,6 @@ export class RoomView extends React.Component { newState.initialEventId = initialEventId; newState.isInitialEventHighlighted = this.context.roomViewStore.isInitialEventHighlighted(); newState.initialEventScrollIntoView = this.context.roomViewStore.initialEventScrollIntoView(); - - if (thread?.rootEvent && initialEvent?.isThreadRoot) { - dis.dispatch({ - action: Action.ShowThread, - rootEvent: thread.rootEvent, - initialEvent, - highlighted: this.context.roomViewStore.isInitialEventHighlighted(), - scroll_into_view: this.context.roomViewStore.initialEventScrollIntoView(), - }); - } } }