Skip to content

Commit 71c24b4

Browse files
authored
Merge pull request #12 from matrix-org/refactor
Refactor trafficlight adapter
2 parents 74c89d2 + 8e7a841 commit 71c24b4

File tree

10 files changed

+541
-222
lines changed

10 files changed

+541
-222
lines changed

cypress.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import installLogsPrinter from "cypress-terminal-report/src/installLogsPrinter";
2020
export default defineConfig({
2121
videoUploadOnPasses: false,
2222
experimentalInteractiveRunEvents: true,
23-
defaultCommandTimeout: 30000,
23+
defaultCommandTimeout: 45000,
2424
chromeWebSecurity: false,
2525
e2e: {
2626
baseUrl: 'https://develop.element.io/',
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
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+
export function register(data: any): string {
20+
cy.visit("/#/register");
21+
cy.get(".mx_ServerPicker_change").click();
22+
cy.get(".mx_ServerPickerDialog_continue").should("be.visible");
23+
cy.get(".mx_ServerPickerDialog_otherHomeserver").type(
24+
data["homeserver_url"]["local"],
25+
);
26+
cy.get(".mx_ServerPickerDialog_continue").click();
27+
// wait for the dialog to go away
28+
cy.get(".mx_ServerPickerDialog").should("not.exist");
29+
cy.get("#mx_RegistrationForm_username").should("be.visible");
30+
// Hide the server text as it contains the randomly allocated Synapse port
31+
cy.get("#mx_RegistrationForm_username").type(data["username"]);
32+
cy.get("#mx_RegistrationForm_password").type(data["password"]);
33+
cy.get("#mx_RegistrationForm_passwordConfirm").type(data["password"]);
34+
cy.get(".mx_Login_submit").click();
35+
cy.get(".mx_UseCaseSelection_skip > .mx_AccessibleButton").click();
36+
return "registered";
37+
}
38+
39+
export function login(data: any): string {
40+
cy.visit('/#/login');
41+
cy.get('#mx_LoginForm_username').should('be.visible');
42+
cy.get('.mx_ServerPicker_change').click();
43+
cy.get('.mx_ServerPickerDialog_otherHomeserver').clear().type(data['homeserver_url']['local']);
44+
cy.get('.mx_ServerPickerDialog_continue').click();
45+
// wait for the dialog to go away
46+
cy.get('.mx_ServerPickerDialog').should('not.exist');
47+
cy.get('#mx_LoginForm_username').type(data['username']);
48+
cy.get('#mx_LoginForm_password').type(data['password']);
49+
cy.get('.mx_Login_submit').click();
50+
// Try to restore from key backup if needed
51+
if (data["key_backup_passphrase"]) {
52+
cy.log("Restoring from keybackup ...");
53+
cy.get(".mx_CompleteSecurity_actionRow .mx_AccessibleButton_kind_primary").last().click();
54+
cy.get("#mx_passPhraseInput").clear().type(data["key_backup_passphrase"]);
55+
cy.get(".mx_AccessSecretStorageDialog_primaryContainer [data-testid='dialog-primary-button']").click();
56+
cy.get(".mx_CompleteSecurity_actionRow .mx_AccessibleButton_kind_primary").click();
57+
} else {
58+
cy.log("Skipping security popup ...");
59+
cy.wait(3000).then(() => {
60+
Cypress.$(".mx_CompleteSecurity_skip")?.first()?.trigger("click");
61+
Cypress.$(".mx_AccessibleButton_kind_danger_outline")?.first()?.trigger("click");
62+
});
63+
}
64+
return 'logged_in';
65+
}
66+
67+
export function logout(): string {
68+
cy.get(".mx_UserMenu_userAvatar").click();
69+
cy.get(".mx_ContextualMenu")
70+
.contains("Sign out")
71+
.click()
72+
.wait(2000)
73+
.then(() => {
74+
Cypress.$("button:contains('Sign out')")?.trigger("click");
75+
});
76+
cy.wait(2000).then(() => {
77+
Cypress.$(".mx_ErrorDialog .mx_Dialog_primary")?.first().trigger("click");
78+
});
79+
return "logged_out";
80+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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+
export function idle(): void {
20+
cy.wait(5000);
21+
}
22+
23+
export function wait(time: string): string {
24+
const _time = time ? parseInt(time, 10): 5000;
25+
cy.wait(_time);
26+
return "wait_over";
27+
}
28+
29+
export function advanceClock(milliseconds: string): string {
30+
const millisecondsAsNumber = parseInt(milliseconds, 10);
31+
if (isNaN(millisecondsAsNumber)) {
32+
throw new Error(`Cannot convert ${milliseconds} to integer!`);
33+
}
34+
cy.clock().tick(millisecondsAsNumber);
35+
return "advanced_clock";
36+
}
37+
38+
export function clearIDBStorage(): string {
39+
cy.window().then((window) => {
40+
return window.indexedDB.databases().then(databases => {
41+
const databaseNames: string[] = databases
42+
.map((db) => db.name)
43+
.filter((name) => name !== undefined) as string[];
44+
for (const name of databaseNames) {
45+
cy.log("Deleting indexedDb database", name);
46+
window.indexedDB.deleteDatabase(name);
47+
}
48+
});
49+
});
50+
cy.wait(5000);
51+
return "storage_cleared";
52+
}
53+
54+
export function exit(): void {
55+
cy.log('Client asked to exit, test complete or server teardown');
56+
}
57+
58+
export function reload(): string {
59+
cy.visit("/");
60+
return "reloaded";
61+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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+
export function startCrossSigning(userId: string): string {
20+
if (userId) {
21+
cy.get(".mx_RightPanel_roomSummaryButton").click();
22+
cy.get(".mx_RoomSummaryCard_icon_people").click();
23+
cy.get(".mx_MemberList_query").type(userId);
24+
cy.get(".mx_MemberList_wrapper .mx_EntityTile").click();
25+
cy.get(".mx_UserInfo_verifyButton").click();
26+
cy.get(".mx_UserInfo_startVerification").click();
27+
} else {
28+
cy.gotoAllSettings();
29+
cy.get("[data-testid='settings-tab-USER_SECURITY_TAB']").click();
30+
cy.contains("Verify").first().click();
31+
cy.contains("Verify with another device").click();
32+
}
33+
return 'started_crosssign';
34+
}
35+
36+
export function acceptCrossSigningRequest(): string {
37+
// Can we please tag some buttons :)
38+
// Click 'Verify' when it comes up
39+
cy.get('.mx_Toast_buttons > .mx_AccessibleButton_kind_primary').click();
40+
return 'accepted_crosssign';
41+
}
42+
43+
export function verifyCrossSigningEmoji(): string {
44+
// Click to move to emoji verification
45+
cy.wait(1000).then(() => {
46+
// Choose whichever exists
47+
Cypress.$(".mx_VerificationPanel_verifyByEmojiButton")?.trigger("click");
48+
Cypress.$('.mx_VerificationPanel_QRPhase_startOption > .mx_AccessibleButton')?.trigger("click");
49+
});
50+
cy.contains("They match").click();
51+
cy.contains("Got it").click();
52+
return 'verified_crosssign';
53+
}
54+
55+
export function verifyDeviceIsTrusted(): string {
56+
cy.gotoAllSettings();
57+
cy.get("[data-testid='settings-tab-USER_SECURITY_TAB']").click();
58+
// For now, we only care if there are any verified devices
59+
// Eventually, we'd want to check if a device is verified by name
60+
cy.contains(/^Verified devices$/);
61+
cy.get(".mx_DevicesPanel_device").children();
62+
return "verified";
63+
}
64+
65+
export function enableKeyBackup(passphrase: string): string {
66+
cy.gotoAllSettings();
67+
cy.get("[data-testid='settings-tab-USER_SECURITY_TAB']").click();
68+
cy.get(".mx_SecureBackupPanel_buttonRow").contains("Set up").click();
69+
cy.get(".mx_CreateSecretStorageDialog_optionIcon_securePhrase").click();
70+
cy.get(".mx_CreateSecretStorageDialog [data-testid='dialog-primary-button']").click();
71+
cy.get(".mx_CreateSecretStorageDialog_passPhraseContainer input[type='password']").type(passphrase);
72+
cy.get("[data-testid='dialog-primary-button']").click();
73+
// confirm the password again
74+
cy.get(".mx_CreateSecretStorageDialog_passPhraseContainer input[type='password']").type(passphrase);
75+
cy.get("[data-testid='dialog-primary-button']").click();
76+
// Continue to next screen
77+
cy.get("[data-testid='dialog-primary-button']").click();
78+
// Classic flakiness fix
79+
cy.wait(500);
80+
cy.get(".mx_CreateSecretStorageDialog").contains("Continue").click();
81+
return "key_backup_enabled";
82+
}
83+
84+
export function enableDehydratedDevice(passphrase: string): string {
85+
cy.gotoAllSettings();
86+
cy.get("[data-testid='settings-tab-USER_LABS_TAB']").click();
87+
cy.get("[aria-label='Offline encrypted messaging using dehydrated devices']").click();
88+
cy.get(".mx_Dialog_cancelButton").click();
89+
enableKeyBackup(passphrase);
90+
return "enabled_dehydrated_device";
91+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
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+
export function createRoom(name: string, topic: string): string {
20+
cy.get('.mx_RoomListHeader_plusButton').click();
21+
cy.get('.mx_ContextualMenu').contains('New room').click();
22+
cy.get('.mx_CreateRoomDialog_name input').type(name);
23+
if (topic) {
24+
cy.get('.mx_CreateRoomDialog_topic input').type(topic);
25+
}
26+
// do this to prevent https://github.com/vector-im/element-web/issues/22590, weirdly
27+
// cy.get('.mx_CreateRoomDialog_name input').click();
28+
// cy.wait(5000);
29+
30+
cy.get('.mx_Dialog_primary').click();
31+
//cy.get('.mx_RoomHeader_nametext').should('contain', data['name']);
32+
return "room_created";
33+
}
34+
35+
export function createDm(userId: string): string {
36+
cy.get('.mx_RoomListHeader_plusButton').click();
37+
cy.get('.mx_ContextualMenu').contains('Start new chat').click();
38+
cy.get('[data-testid="invite-dialog-input"]').type(`@${userId}`);
39+
cy.get('.mx_InviteDialog_goButton').click();
40+
return "dm_created";
41+
}
42+
43+
export function changeRoomHistoryVisibility(historyVisibility: string): string {
44+
cy.get(".mx_RightPanel_roomSummaryButton").click();
45+
cy.get(".mx_RoomSummaryCard_icon_settings").click();
46+
cy.get(`[data-testid='settings-tab-ROOM_SECURITY_TAB']`).click();
47+
// should be either "shared", "invited" or "joined"
48+
cy.get(`#historyVis-${historyVisibility}`).parents("label").click();
49+
cy.get(".mx_Dialog_cancelButton").click();
50+
cy.get("[data-test-id=base-card-close-button]").click();
51+
return "changed";
52+
}
53+
54+
export function openRoom(name: string): string {
55+
cy.get(".mx_RoomSublist_tiles").contains(name).click();
56+
return "room_opened";
57+
}
58+
59+
export function acceptInvite(): string {
60+
cy.get(".mx_RoomTile").click();
61+
cy.get(".mx_RoomPreviewBar_actions .mx_AccessibleButton_kind_primary").click();
62+
return "accepted";
63+
}
64+
65+
export function inviteUser(userId: string): string {
66+
cy.get(".mx_RightPanel_roomSummaryButton").click();
67+
cy.get(".mx_RoomSummaryCard_icon_people").click();
68+
cy.get(".mx_MemberList_invite").click();
69+
cy.get(".mx_InviteDialog_addressBar input")
70+
.type(`@${userId}`)
71+
.type("{enter}");
72+
cy.get(".mx_InviteDialog_goButton").click();
73+
cy.get(".mx_AccessibleButton.mx_BaseCard_back").click();
74+
cy.get(".mx_AccessibleButton.mx_BaseCard_close", { timeout: 30000 }).click();
75+
return "invited";
76+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
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+
export function sendMessage(message: string): string {
20+
cy.get(".mx_SendMessageComposer div[contenteditable=true]")
21+
.click()
22+
.type(message)
23+
.type("{enter}");
24+
//cy.contains(data['message']).closest('mx_EventTile').should('have.class', 'mx_EventTile_receiptSent');
25+
return "message_sent";
26+
}
27+
28+
export function verifyMessageInTimeline(message: string): string {
29+
cy.contains(message);
30+
return "verified";
31+
}
32+
33+
export function verifyLastMessageIsUTD(): string {
34+
// verifies that the last tile is an UTD
35+
cy.get(".mx_EventTile").then((elements) => {
36+
const lastEventTile = Array.isArray(elements) ? elements[elements.length - 1] : elements;
37+
cy.get(".mx_UnknownBody", { withinSubject: lastEventTile });
38+
});
39+
cy.get(".mx_UnknownBody");
40+
return "verified";
41+
}
42+
43+
export function verifyLastMessageIsTrusted(): string {
44+
cy.get(".mx_EventTile")
45+
.last()
46+
.find(".mx_EventTile_e2eIcon").should("not.exist");
47+
return "verified";
48+
}

0 commit comments

Comments
 (0)