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

Move Enterprise Erin tests from Puppeteer to Cypress #8569

Merged
merged 15 commits into from
May 26, 2022
35 changes: 35 additions & 0 deletions cypress/integration/2-login/login.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,39 @@ describe("Login", () => {
cy.url().should('contain', '/#/home');
});
});

describe("logout", () => {
beforeEach(() => {
cy.initTestUser(synapse, "Erin");
MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
});

it("should go to login page on logout", () => {
cy.get('[aria-label="User menu"]').click();

cy.get(".mx_UserMenu_contextMenu").within(() => {
cy.get(".mx_UserMenu_iconSignOut").click();
});

cy.url().should("contain", "/#/login");
});

it("should respect logout_redirect_url", () => {
cy.tweakConfig({
// We redirect to decoder-ring because it's a predictable page that isn't Element itself.
// We could use example.org, matrix.org, or something else, however this puts dependency of external
t3chguy marked this conversation as resolved.
Show resolved Hide resolved
// infrastructure on our tests. In the same vein, we don't really want to figure out how to ship a
// `test-landing.html` page when running with an uncontrolled Element (via `yarn start`).
// Using the decoder-ring is just as fine, and we can search for strategic names.
logout_redirect_url: "/decoder-ring/",
});

cy.get('[aria-label="User menu"]').click();

cy.get(".mx_UserMenu_contextMenu").within(() => {
cy.get(".mx_UserMenu_iconSignOut").click();
});

cy.url().should("contains", "decoder-ring");
});
});
});
2 changes: 1 addition & 1 deletion cypress/integration/3-user-menu/user-menu.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe("User Menu", () => {

it("should contain our name & userId", () => {
cy.get('[aria-label="User menu"]').click();
cy.get(".mx_ContextualMenu").within(() => {
cy.get(".mx_UserMenu_contextMenu").within(() => {
cy.get(".mx_UserMenu_contextMenu_displayName").should("contain", "Jeff");
cy.get(".mx_UserMenu_contextMenu_userId").should("contain", user.userId);
});
Expand Down
43 changes: 43 additions & 0 deletions cypress/support/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/// <reference types="cypress" />

import "./client"; // XXX: without an (any) import here, types break down
import Chainable = Cypress.Chainable;
import AUTWindow = Cypress.AUTWindow;

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
interface Chainable {
/**
* Applies tweaks to the config read from config.json
*/
tweakConfig(tweaks: Record<string, any>): Chainable<AUTWindow>;
}
}
}

Cypress.Commands.add("tweakConfig", (tweaks: Record<string, any>): Chainable<AUTWindow> => {
return cy.window().then(win => {
// note: we can't *set* the object because the window version is effectively a pointer.
for (const [k, v] of Object.entries(tweaks)) {
// @ts-ignore - for some reason it's not picking up on global.d.ts types.
win.mxReactSdkConfig[k] = v;
}
});
});
1 change: 1 addition & 0 deletions cypress/support/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ import "./login";
import "./client";
import "./settings";
import "./bot";
import "./app";
9 changes: 1 addition & 8 deletions test/end-to-end-tests/src/scenario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,12 @@ import { spacesScenarios } from './scenarios/spaces';
import { RestSession } from "./rest/session";
import { stickerScenarios } from './scenarios/sticker';
import { userViewScenarios } from "./scenarios/user-view";
import { ssoCustomisationScenarios } from "./scenarios/sso-customisations";
import { updateScenarios } from "./scenarios/update";

export async function scenario(createSession: (s: string) => Promise<ElementSession>,
restCreator: RestSessionCreator): Promise<void> {
let firstUser = true;
async function createUser(username) {
async function createUser(username: string) {
const session = await createSession(username);
if (firstUser) {
// only show browser version for first browser opened
Expand Down Expand Up @@ -68,12 +67,6 @@ export async function scenario(createSession: (s: string) => Promise<ElementSess
const stickerSession = await createSession("sally");
await stickerScenarios("sally", "ilikestickers", stickerSession, restCreator);

// we spawn yet another session for SSO stuff because it involves authentication and
// logout, which can/does affect other tests dramatically. See notes above regarding
// stickers for the performance loss of doing this.
const ssoSession = await createUser("enterprise_erin");
await ssoCustomisationScenarios(ssoSession);

// Create a new window to test app auto-updating
const updateSession = await createSession("update");
await updateScenarios(updateSession);
Expand Down
50 changes: 0 additions & 50 deletions test/end-to-end-tests/src/scenarios/sso-customisations.ts

This file was deleted.

43 changes: 0 additions & 43 deletions test/end-to-end-tests/src/usecases/logout.ts

This file was deleted.

13 changes: 1 addition & 12 deletions test/end-to-end-tests/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const range = function(start: number, amount: number, step = 1): Array<nu
return r;
};

export const delay = function(ms): Promise<void> {
export const delay = function(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
};

Expand All @@ -44,17 +44,6 @@ export const measureStop = function(session: ElementSession, name: string): Prom
}, name);
};

// TODO: Proper types on `config` - for some reason won't accept an import of ConfigOptions.
export async function applyConfigChange(session: ElementSession, config: any): Promise<void> {
await session.page.evaluate((_config) => {
// note: we can't *set* the object because the window version is effectively a pointer.
for (const [k, v] of Object.entries(_config)) {
// @ts-ignore - for some reason it's not picking up on global.d.ts types.
window.mxReactSdkConfig[k] = v;
}
}, config);
}

export async function serializeLog(msg: ConsoleMessage): Promise<string> {
// 9 characters padding is somewhat arbitrary ("warning".length + some)
let s = `${new Date().toISOString()} | ${ padEnd(msg.type(), 9, ' ')}| ${msg.text()} `; // trailing space is intentional
Expand Down