Port remaining login.spec.ts & soft_logout.spec.ts tests from Cypress to Playwright (#11917)

Co-authored-by: R Midhun Suresh <hi@midhun.dev>
This commit is contained in:
Michael Telatynski 2023-11-23 10:27:11 +00:00 committed by GitHub
parent 8dcd13eb6d
commit a6705304aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 465 additions and 386 deletions

View file

@ -1,103 +0,0 @@
/*
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 { HomeserverInstance } from "../../plugins/utils/homeserver";
import { doTokenRegistration } from "./utils";
describe("Login", () => {
let homeserver: HomeserverInstance;
afterEach(() => {
cy.stopHomeserver(homeserver);
});
// tests for old-style SSO login, in which we exchange tokens with Synapse, and Synapse talks to an auth server
describe("SSO login", () => {
beforeEach(() => {
cy.task("startOAuthServer")
.then((oAuthServerPort: number) => {
return cy.startHomeserver({ template: "default", oAuthServerPort });
})
.then((data) => {
homeserver = data;
});
});
afterEach(() => {
cy.task("stopOAuthServer");
});
it("logs in with SSO and lands on the home screen", () => {
// If this test fails with a screen showing "Timeout connecting to remote server", it is most likely due to
// your firewall settings: Synapse is unable to reach the OIDC server.
//
// If you are using ufw, try something like:
// sudo ufw allow in on docker0
//
doTokenRegistration(homeserver.baseUrl);
// Eventually, we should end up at the home screen.
cy.url().should("contain", "/#/home", { timeout: 30000 });
cy.findByRole("heading", { name: "Welcome Alice" });
});
});
describe("logout", () => {
beforeEach(() => {
cy.startHomeserver("consent").then((data) => {
homeserver = data;
cy.initTestUser(homeserver, "Erin");
});
});
it("should go to login page on logout", () => {
cy.findByRole("button", { name: "User menu" }).click();
// give a change for the outstanding requests queue to settle before logging out
cy.wait(2000);
cy.get(".mx_UserMenu_contextMenu").within(() => {
cy.findByRole("menuitem", { name: "Sign out" }).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
// 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.findByRole("button", { name: "User menu" }).click();
// give a change for the outstanding requests queue to settle before logging out
cy.wait(2000);
cy.get(".mx_UserMenu_contextMenu").within(() => {
cy.findByRole("menuitem", { name: "Sign out" }).click();
});
cy.url().should("contains", "decoder-ring");
});
});
});

View file

@ -1,141 +0,0 @@
/*
Copyright 2023 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.
*/
import { HomeserverInstance } from "../../plugins/utils/homeserver";
import { UserCredentials } from "../../support/login";
import { doTokenRegistration } from "./utils";
describe("Soft logout", () => {
let homeserver: HomeserverInstance;
beforeEach(() => {
cy.task("startOAuthServer")
.then((oAuthServerPort: number) => {
return cy.startHomeserver({ template: "default", oAuthServerPort });
})
.then((data) => {
homeserver = data;
});
});
afterEach(() => {
cy.stopHomeserver(homeserver);
cy.task("stopOAuthServer");
});
describe("with password user", () => {
let testUserCreds: UserCredentials;
beforeEach(() => {
cy.initTestUser(homeserver, "Alice").then((creds) => {
testUserCreds = creds;
});
});
it("shows the soft-logout page when a request fails, and allows a re-login", () => {
interceptRequestsWithSoftLogout();
cy.findByText("You're signed out");
cy.findByPlaceholderText("Password").type(testUserCreds.password).type("{enter}");
// back to the welcome page
cy.url().should("contain", "/#/home", { timeout: 30000 });
cy.findByRole("heading", { name: "Welcome Alice" });
});
it("still shows the soft-logout page when the page is reloaded after a soft-logout", () => {
interceptRequestsWithSoftLogout();
cy.findByText("You're signed out");
cy.reload();
cy.findByText("You're signed out");
});
});
describe("with SSO user", () => {
beforeEach(() => {
doTokenRegistration(homeserver.baseUrl);
// Eventually, we should end up at the home screen.
cy.url().should("contain", "/#/home", { timeout: 30000 });
cy.findByRole("heading", { name: "Welcome Alice" });
});
it("shows the soft-logout page when a request fails, and allows a re-login", () => {
cy.findByRole("heading", { name: "Welcome Alice" });
interceptRequestsWithSoftLogout();
cy.findByText("You're signed out");
cy.findByRole("button", { name: "Continue with OAuth test" }).click();
// click the submit button
cy.findByRole("button", { name: "Submit" }).click();
// Synapse prompts us to grant permission to Element
cy.findByRole("heading", { name: "Continue to your account" });
cy.findByRole("link", { name: "Continue" }).click();
// back to the welcome page
cy.url().should("contain", "/#/home", { timeout: 30000 });
cy.findByRole("heading", { name: "Welcome Alice" });
});
});
});
/**
* Intercept calls to /sync and have them fail with a soft-logout
*
* Any further requests to /sync with the same access token are blocked.
*/
function interceptRequestsWithSoftLogout(): void {
let expiredAccessToken: string | null = null;
cy.intercept(
{
pathname: "/_matrix/client/*/sync",
},
(req) => {
const accessToken = req.headers["authorization"] as string;
// on the first request, record the access token
if (!expiredAccessToken) {
console.log(`Soft-logout on access token ${accessToken}`);
expiredAccessToken = accessToken;
}
// now, if the access token on this request matches the expired one, block it
if (expiredAccessToken && accessToken === expiredAccessToken) {
console.log(`Intercepting request with soft-logged-out access token`);
req.reply({
statusCode: 401,
body: {
errcode: "M_UNKNOWN_TOKEN",
error: "Soft logout",
soft_logout: true,
},
});
return;
}
// otherwise, pass through as normal
req.continue();
},
);
// do something to make the active /sync return: create a new room
cy.getClient().then((client) => {
// don't wait for this to complete: it probably won't, because of the broken sync
return client.createRoom({});
});
}

View file

@ -1,49 +0,0 @@
/*
Copyright 2023 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.
*/
/** Visit the login page, choose to log in with "OAuth test", register a new account, and redirect back to Element
*/
export function doTokenRegistration(homeserverUrl: string) {
cy.visit("/#/login");
cy.findByRole("button", { name: "Edit" }).click();
cy.findByRole("textbox", { name: "Other homeserver" }).type(homeserverUrl);
cy.findByRole("button", { name: "Continue" }).click();
// wait for the dialog to go away
cy.get(".mx_ServerPickerDialog").should("not.exist");
// click on "Continue with OAuth test"
cy.findByRole("button", { name: "Continue with OAuth test" }).click();
// wait for the Test OAuth Page to load
cy.findByText("Test OAuth page");
// click the submit button
cy.findByRole("button", { name: "Submit" }).click();
// Synapse prompts us to pick a user ID
cy.findByRole("heading", { name: "Create your account" });
cy.findByRole("textbox", { name: "Username (required)" }).type("alice");
// wait for username validation to start, and complete
cy.wait(50);
cy.get("#field-username-output").should("have.value", "");
cy.findByRole("button", { name: "Continue" }).click();
// Synapse prompts us to grant permission to Element
cy.findByRole("heading", { name: "Continue to your account" });
cy.findByRole("link", { name: "Continue" }).click();
}