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

Commit

Permalink
Add safety to the spotlight search dialog (#9177)
Browse files Browse the repository at this point in the history
* Add safety to the spotlight search dialog

Fixes element-hq/element-web#22851

This test was triggering the mentioned bug only occasionally because it was dependent on when the search settled: if it settled early then the length was wrong. In testing, the dialog was caught multiple times to have passed the length chat but update to show duplicated results before the test closed the client, indicating a race condition within the tests.

To fix this, we just make sure everything settles before moving on. We do this on unaffected tests too to ensure they don't regress later.

The affected test was "should find group DMs by usernames or user ids".

* Update cypress/e2e/spotlight/spotlight.spec.ts

Co-authored-by: Robin <robin@robin.town>

Co-authored-by: Robin <robin@robin.town>
  • Loading branch information
turt2live and robintown authored Aug 11, 2022
1 parent 4a5ed2f commit 8db7766
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
32 changes: 32 additions & 0 deletions cypress/e2e/spotlight/spotlight.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ Cypress.Commands.add("startDM", (name: string) => {
cy.openSpotlightDialog().within(() => {
cy.spotlightFilter(Filter.People);
cy.spotlightSearch().clear().type(name);
cy.wait(1000); // wait for the dialog code to settle
cy.get(".mx_Spinner").should("not.exist");
cy.spotlightResults().should("have.length", 1);
cy.spotlightResults().eq(0).should("contain", name);
Expand Down Expand Up @@ -216,6 +217,7 @@ describe("Spotlight", () => {
it("should find joined rooms", () => {
cy.openSpotlightDialog().within(() => {
cy.spotlightSearch().clear().type(room1Name);
cy.wait(1000); // wait for the dialog code to settle
cy.spotlightResults().should("have.length", 1);
cy.spotlightResults().eq(0).should("contain", room1Name);
cy.spotlightResults().eq(0).click();
Expand All @@ -229,6 +231,7 @@ describe("Spotlight", () => {
cy.openSpotlightDialog().within(() => {
cy.spotlightFilter(Filter.PublicRooms);
cy.spotlightSearch().clear().type(room1Name);
cy.wait(1000); // wait for the dialog code to settle
cy.spotlightResults().should("have.length", 1);
cy.spotlightResults().eq(0).should("contain", room1Name);
cy.spotlightResults().eq(0).should("contain", "View");
Expand All @@ -243,6 +246,7 @@ describe("Spotlight", () => {
cy.openSpotlightDialog().within(() => {
cy.spotlightFilter(Filter.PublicRooms);
cy.spotlightSearch().clear().type(room2Name);
cy.wait(1000); // wait for the dialog code to settle
cy.spotlightResults().should("have.length", 1);
cy.spotlightResults().eq(0).should("contain", room2Name);
cy.spotlightResults().eq(0).should("contain", "Join");
Expand All @@ -258,6 +262,7 @@ describe("Spotlight", () => {
cy.openSpotlightDialog().within(() => {
cy.spotlightFilter(Filter.PublicRooms);
cy.spotlightSearch().clear().type(room3Name);
cy.wait(1000); // wait for the dialog code to settle
cy.spotlightResults().should("have.length", 1);
cy.spotlightResults().eq(0).should("contain", room3Name);
cy.spotlightResults().eq(0).should("contain", "View");
Expand Down Expand Up @@ -296,6 +301,7 @@ describe("Spotlight", () => {
cy.openSpotlightDialog().within(() => {
cy.spotlightFilter(Filter.People);
cy.spotlightSearch().clear().type(bot1Name);
cy.wait(1000); // wait for the dialog code to settle
cy.spotlightResults().should("have.length", 1);
cy.spotlightResults().eq(0).should("contain", bot1Name);
cy.spotlightResults().eq(0).click();
Expand All @@ -308,6 +314,7 @@ describe("Spotlight", () => {
cy.openSpotlightDialog().within(() => {
cy.spotlightFilter(Filter.People);
cy.spotlightSearch().clear().type(bot2Name);
cy.wait(1000); // wait for the dialog code to settle
cy.spotlightResults().should("have.length", 1);
cy.spotlightResults().eq(0).should("contain", bot2Name);
cy.spotlightResults().eq(0).click();
Expand All @@ -324,6 +331,7 @@ describe("Spotlight", () => {
cy.openSpotlightDialog().within(() => {
cy.spotlightFilter(Filter.People);
cy.spotlightSearch().clear().type(bot2Name);
cy.wait(1000); // wait for the dialog code to settle
cy.spotlightResults().should("have.length", 1);
cy.spotlightResults().eq(0).should("contain", bot2Name);
cy.spotlightResults().eq(0).click();
Expand Down Expand Up @@ -352,6 +360,7 @@ describe("Spotlight", () => {
cy.openSpotlightDialog().within(() => {
cy.spotlightFilter(Filter.People);
cy.spotlightSearch().clear().type(bot1.getUserId());
cy.wait(1000); // wait for the dialog code to settle
cy.spotlightResults().should("have.length", 2);
cy.spotlightResults().eq(0).should("contain", `${bot1Name} and ${bot2Name}`);
});
Expand All @@ -360,15 +369,37 @@ describe("Spotlight", () => {
cy.openSpotlightDialog().within(() => {
cy.spotlightFilter(Filter.People);
cy.spotlightSearch().clear().type(bot2.getUserId());
cy.wait(1000); // wait for the dialog code to settle
cy.spotlightResults().should("have.length", 2);
cy.spotlightResults().eq(0).should("contain", `${bot1Name} and ${bot2Name}`);
});
});

// Test against https://github.com/vector-im/element-web/issues/22851
it("should show each person result only once", () => {
cy.openSpotlightDialog().within(() => {
cy.spotlightFilter(Filter.People);

// 2 rounds of search to simulate the bug conditions. Specifically, the first search
// should have 1 result (not 2) and the second search should also have 1 result (instead
// of the super buggy 3 described by https://github.com/vector-im/element-web/issues/22851)
//
// We search for user ID to trigger the profile lookup within the dialog.
for (let i = 0; i < 2; i++) {
cy.log("Iteration: " + i);
cy.spotlightSearch().clear().type(bot1.getUserId());
cy.wait(1000); // wait for the dialog code to settle
cy.spotlightResults().should("have.length", 1);
cy.spotlightResults().eq(0).should("contain", bot1.getUserId());
}
});
});

it("should allow opening group chat dialog", () => {
cy.openSpotlightDialog().within(() => {
cy.spotlightFilter(Filter.People);
cy.spotlightSearch().clear().type(bot2Name);
cy.wait(1000); // wait for the dialog code to settle
cy.spotlightResults().should("have.length", 1);
cy.spotlightResults().eq(0).should("contain", bot2Name);
cy.get(".mx_SpotlightDialog_startGroupChat").should("contain", "Start a group chat");
Expand All @@ -390,6 +421,7 @@ describe("Spotlight", () => {
cy.openSpotlightDialog().within(() => {
cy.spotlightFilter(Filter.People);
cy.spotlightSearch().clear().type(bot1Name);
cy.wait(1000); // wait for the dialog code to settle
cy.get(".mx_Spinner").should("not.exist");
cy.spotlightResults().should("have.length", 1);
});
Expand Down
4 changes: 3 additions & 1 deletion src/components/views/dialogs/spotlight/SpotlightDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,9 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
})),
...roomResults,
...userResults,
...(profile ? [new DirectoryMember(profile)] : []).map(toMemberResult),
...(profile && !alreadyAddedUserIds.has(profile.user_id)
? [new DirectoryMember(profile)]
: []).map(toMemberResult),
...publicRooms.map(toPublicRoomResult),
].filter(result => filter === null || result.filter.includes(filter));
},
Expand Down

0 comments on commit 8db7766

Please sign in to comment.