Go to welcome on logout (#33306)

* Go to welcome on logout

Instead of login, for QR login project

* Update tests

* Add tests

* Delint

* Update comments
This commit is contained in:
Michael Telatynski 2026-04-28 11:24:47 +01:00 committed by GitHub
parent c363d2eb82
commit 5f770bfe4c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 45 additions and 26 deletions

View File

@ -57,6 +57,6 @@ test.describe("Logout tests", () => {
await locator.getByRole("menuitem", { name: "Remove this device", exact: true }).click();
// Should have logged out directly
await expect(page.getByRole("heading", { name: "Sign in" })).toBeVisible();
await expect(page.getByRole("heading", { name: "Be in your element" })).toBeVisible();
});
});

View File

@ -245,7 +245,7 @@ export async function logIntoElementAndVerify(page: Page, credentials: Credentia
}
/**
* Click the "sign out" option in Element, and wait for the login page to load
* Click the "sign out" option in Element, and wait for the welcome page to load
*
* @param page - Playwright `Page` object.
* @param discardKeys - if true, expect a "You'll lose access to your encrypted messages" dialog, and dismiss it.
@ -259,8 +259,8 @@ export async function logOutOfElement(page: Page, discardKeys: boolean = false)
await page.locator(".mx_Dialog .mx_QuestionDialog").getByRole("button", { name: "Remove this device" }).click();
}
// Wait for the login page to load
await page.getByRole("heading", { name: "Sign in" }).click();
// Wait for the welcome page to load
await expect(page.getByRole("heading", { name: "Be in your element" })).toBeVisible();
}
/**

View File

@ -334,7 +334,7 @@ test.describe("Login", () => {
});
test.describe("logout", () => {
test("should go to login page on logout", async ({ page, user }) => {
test("should go to welcome page on logout", async ({ page, user }) => {
await page.getByRole("button", { name: "User menu" }).click();
await expect(page.getByText(user.displayName, { exact: true })).toBeVisible();
@ -345,7 +345,7 @@ test.describe("Login", () => {
.locator(".mx_UserMenu_contextMenu")
.getByRole("menuitem", { name: "Remove this device" })
.click();
await expect(page).toHaveURL(/\/#\/login$/);
await expect(page).toHaveURL(/\/#\/welcome$/);
});
});
});

View File

@ -123,7 +123,7 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
// Allow the outstanding requests queue to settle before logging out
await page.waitForTimeout(2000);
await page.locator(".mx_UserMenu_contextMenu").getByRole("menuitem", { name: "Remove this device" }).click();
await expect(page).toHaveURL(/\/#\/login$/);
await expect(page).toHaveURL(/\/#\/welcome$/);
// Log in again
await page.goto("/#/login");
@ -159,7 +159,7 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
.locator(".mx_UserMenu_contextMenu")
.getByRole("menuitem", { name: "Remove this device" })
.click();
await expect(page).toHaveURL(/\/#\/login$/);
await expect(page).toHaveURL(/\/#\/welcome$/);
// Log in again
await page.goto("/#/login");
@ -209,7 +209,7 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
.locator(".mx_UserMenu_contextMenu")
.getByRole("menuitem", { name: "Remove this device" })
.click();
await expect(page).toHaveURL(/\/#\/login$/);
await expect(page).toHaveURL(/\/#\/welcome$/);
// Log in again
await page.goto("/#/login");

View File

@ -1133,7 +1133,7 @@ export async function onLoggedOut(): Promise<void> {
// customisations got the memo.
if (SdkConfig.get().logout_redirect_url) {
logger.log("Redirecting to external provider to finish logout");
// XXX: Defer this so that it doesn't race with MatrixChat unmounting the world by going to /#/login
// XXX: Defer this so that it doesn't race with MatrixChat unmounting the world by going to /#/welcome
window.setTimeout(() => {
window.location.href = SdkConfig.get().logout_redirect_url!;
}, 100);

View File

@ -25,15 +25,15 @@ Please see LICENSE files in the repository root for full details.
*
* No previous session
*
* (from all other states
* except LOCK_STOLEN) WELCOME
*
* Client logged out
*
* "Sign in" "Create account"
*
*
* "Forgot ▼ "Create an
* (from all other states Client logged out
* except LOCK_STOLEN) WELCOME
*
*
*
* "Sign in" "Create account"
*
*
* "Forgot ▼ "Create an
* password" ┌─────────────────┐ account"
* FORGOT_PASSWORD LOGIN REGISTER
*

View File

@ -422,7 +422,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
this.onShowPostLoginScreen();
}
const promisesList: Promise<any>[] = [this.firstSyncPromise.promise];
const promisesList: Promise<unknown>[] = [this.firstSyncPromise.promise];
let crossSigningIsSetUp = false;
if (cryptoEnabled) {
// check if the user has previously published public cross-signing keys,
@ -1101,17 +1101,18 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
}
private viewWelcome(): void {
private viewWelcome(otherState?: Partial<IState>): void {
if (shouldUseLoginForWelcome(SdkConfig.get())) {
return this.viewLogin();
return this.viewLogin(otherState);
}
this.setStateForNewView({
view: Views.WELCOME,
...otherState,
});
this.notifyNewScreen("welcome");
}
private viewLogin(otherState?: any): void {
private viewLogin(otherState?: Partial<IState>): void {
this.setStateForNewView({
view: Views.LOGIN,
...otherState,
@ -1555,7 +1556,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
* Called when the session is logged out
*/
private onLoggedOut(): void {
this.viewLogin({
this.viewWelcome({
ready: false,
collapseLhs: false,
currentRoomId: null,

View File

@ -588,8 +588,10 @@ describe("<MatrixChat />", () => {
});
});
const getComponentAndWaitForReady = async (): Promise<RenderResult> => {
const renderResult = getComponent();
const getComponentAndWaitForReady = async (
props: Partial<ComponentProps<typeof MatrixChat>> = {},
): Promise<RenderResult> => {
const renderResult = getComponent(props);
// we think we are logged in, but are still waiting for the /sync to complete
await screen.findByText("Logout");
@ -1023,6 +1025,22 @@ describe("<MatrixChat />", () => {
expect(PlatformPeg.get()!.destroyPickleKey).toHaveBeenCalledWith(userId, deviceId);
});
it("should go to welcome", async () => {
await getComponentAndWaitForReady();
await dispatchLogoutAndWait();
expect(defaultProps.onNewScreen).toHaveBeenLastCalledWith("welcome", false);
});
it("should go to login if welcome disabled", async () => {
await getComponentAndWaitForReady({
config: { ...defaultProps.config, embedded_pages: { login_for_welcome: true } },
});
await dispatchLogoutAndWait();
expect(defaultProps.onNewScreen).toHaveBeenLastCalledWith("login", false);
});
describe("without delegated auth", () => {
it("should call /logout", async () => {
await getComponentAndWaitForReady();