diff --git a/cypress/e2e/module-system/roomViewLifecycle.spec.ts b/cypress/e2e/module-system/roomViewLifecycle.spec.ts new file mode 100644 index 00000000000..09194701129 --- /dev/null +++ b/cypress/e2e/module-system/roomViewLifecycle.spec.ts @@ -0,0 +1,68 @@ +/* +Copyright 2023 Nordeck IT + Consulting GmbH. + +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"; + +describe("RoomViewLifecycle", () => { + let homeserver: HomeserverInstance; + + beforeEach(() => { + cy.window().then((win) => { + win.localStorage.setItem("mx_local_settings", '{"language":"en"}'); // Ensure the language is set to a consistent value + }); + cy.startHomeserver("default").then((data) => { + homeserver = data; + + cy.intercept( + { method: "GET", pathname: "/config.json" }, + { body: { default_server_config: { "m.homeserver": { base_url: data.baseUrl } } } }, + ); + }); + }); + + afterEach(() => { + cy.stopHomeserver(homeserver); + }); + + it("should show login without the PreviewRoomNotLoggedIn lifecycle", () => { + cy.visit(`/#/room/!example:localhost`); + + cy.contains("Join the conversation with an account"); + cy.contains("Sign Up"); + cy.contains("Sign In"); + }); + + it("should show login with the PreviewRoomNotLoggedIn lifecycle", () => { + // we must reload the page first, otherwise, the module system settings get lost... + cy.visit("/"); + cy.contains("Welcome"); + + // we need to set the data to local storage again because of the reload + cy.window().then((win) => { + win.localStorage.setItem("mx_local_settings", '{"language":"en"}'); // Ensure the language is set to a consistent value + }); + cy.enableModuleSystem(); + cy.moduleSystemPreviewRoom("!example:localhost"); + + cy.visit(`/#/room/!example:localhost`); + cy.reload(); + + cy.contains("Join the room to participate"); + cy.contains("Join"); + }); +}); diff --git a/cypress/e2e/module-system/translations.spec.ts b/cypress/e2e/module-system/translations.spec.ts new file mode 100644 index 00000000000..ff84b40819e --- /dev/null +++ b/cypress/e2e/module-system/translations.spec.ts @@ -0,0 +1,44 @@ +/* +Copyright 2023 Nordeck IT + Consulting GmbH. + +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"; + +describe("Custom translations module", () => { + let homeserver: HomeserverInstance; + + beforeEach(() => { + cy.enableModuleSystem(); + + cy.window().then((win) => { + win.localStorage.setItem("mx_lhs_size", "0"); // Collapse left panel for these tests + }); + cy.startHomeserver("default").then((data) => { + homeserver = data; + + cy.initTestUser(homeserver, "Tom"); + }); + }); + + afterEach(() => { + cy.stopHomeserver(homeserver); + }); + + it("should override the 'Welcome' translation", () => { + cy.get("Howdy Tom (Changed by the Module System)"); + }); +}); diff --git a/cypress/example_module/ExampleModule.ts b/cypress/example_module/ExampleModule.ts new file mode 100644 index 00000000000..4a2e76c4aa5 --- /dev/null +++ b/cypress/example_module/ExampleModule.ts @@ -0,0 +1,48 @@ +/* + * Copyright 2023 Nordeck IT + Consulting GmbH + * + * 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 { ModuleApi } from "@matrix-org/react-sdk-module-api/lib/ModuleApi"; +import { RuntimeModule } from "@matrix-org/react-sdk-module-api/lib/RuntimeModule"; +import { + RoomPreviewListener, + RoomViewLifecycle, +} from "@matrix-org/react-sdk-module-api/lib/lifecycles/RoomViewLifecycle"; + +export default class ExampleModule extends RuntimeModule { + public constructor(moduleApi: ModuleApi) { + super(moduleApi); + + // Only apply the module when it is activated so we don't interfere with + // other tests that should not be affected by this module. + if (window.localStorage.getItem("cypress_module_system_enable") !== "true") { + return; + } + + this.moduleApi.registerTranslations({ + "Welcome %(name)s": { + en: "Howdy %(name)s (Changed by the Module System)", + }, + }); + + this.on(RoomViewLifecycle.PreviewRoomNotLoggedIn, this.onRoomPreview); + } + + protected onRoomPreview: RoomPreviewListener = (opts, roomId) => { + if (window.localStorage.getItem("cypress_module_system_preview_room_id") === roomId) { + opts.canJoin = true; + } + }; +} diff --git a/cypress/example_module/build_config.yaml b/cypress/example_module/build_config.yaml new file mode 100644 index 00000000000..1e1120ff475 --- /dev/null +++ b/cypress/example_module/build_config.yaml @@ -0,0 +1,5 @@ +# This file is included by the `yarn start:e2e` task in element-web. It will +# register the module in this folder as a module in the dev mode so that the +# Cypress tests can be executed correctly. +modules: + - "file:node_modules/matrix-react-sdk/cypress/example_module" diff --git a/cypress/example_module/package.json b/cypress/example_module/package.json new file mode 100644 index 00000000000..c2a5fe1cf34 --- /dev/null +++ b/cypress/example_module/package.json @@ -0,0 +1,8 @@ +{ + "name": "example_module", + "version": "1.0.0", + "main": "ExampleModule.ts", + "dependencies": { + "@matrix-org/react-sdk-module-api": "*" + } +} diff --git a/cypress/plugins/synapsedocker/templates/default/homeserver.yaml b/cypress/plugins/synapsedocker/templates/default/homeserver.yaml index aaad3420b99..a4eaa6191d9 100644 --- a/cypress/plugins/synapsedocker/templates/default/homeserver.yaml +++ b/cypress/plugins/synapsedocker/templates/default/homeserver.yaml @@ -74,3 +74,5 @@ suppress_key_server_warning: true ui_auth: session_timeout: "300s" + +allow_guest_access: true diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts index 2ff0197ba65..ece8fc5fc63 100644 --- a/cypress/support/e2e.ts +++ b/cypress/support/e2e.ts @@ -40,6 +40,7 @@ import "./network"; import "./composer"; import "./proxy"; import "./axe"; +import "./moduleSystem"; installLogsCollector({ // specify the types of logs to collect (and report to the node console at the end of the test) diff --git a/cypress/support/moduleSystem.ts b/cypress/support/moduleSystem.ts new file mode 100644 index 00000000000..34b194f4e0b --- /dev/null +++ b/cypress/support/moduleSystem.ts @@ -0,0 +1,50 @@ +/* +Copyright 2023 Nordeck IT + Consulting GmbH. + +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. +*/ + +/// + +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace Cypress { + interface Chainable { + // Enables the module system for the current session. + enableModuleSystem(): void; + moduleSystemPreviewRoom(roomId: string): void; + } + } +} + +beforeEach(() => { + cy.window().then((win) => { + win.localStorage.removeItem("cypress_module_system_enable"); + win.localStorage.removeItem("cypress_module_system_preview_room_id"); + }); +}); + +Cypress.Commands.add("enableModuleSystem", (): void => { + cy.window().then((win) => { + win.localStorage.setItem("cypress_module_system_enable", "true"); + }); +}); + +Cypress.Commands.add("moduleSystemPreviewRoom", (roomId: string): void => { + cy.window().then((win) => { + win.localStorage.setItem("cypress_module_system_preview_room_id", roomId); + }); +}); + +// Needed to make this file a module +export {};