From 182c62a38ba64b85b5e3d421bfc887e4124a8e13 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Tue, 15 Oct 2024 13:44:50 +0100 Subject: [PATCH 1/5] Add support for loading the config from a given config location. --- src/electron-main.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/electron-main.ts b/src/electron-main.ts index 9ff8f8f16c..9df1295756 100644 --- a/src/electron-main.ts +++ b/src/electron-main.ts @@ -44,6 +44,7 @@ if (argv["help"]) { console.log(" --profile-dir {path}: Path to where to store the profile."); console.log(" --profile {name}: Name of alternate profile to use, allows for running multiple accounts."); console.log(" --devtools: Install and use react-devtools and react-perf."); + console.log(` --config: Path to the config.json file. Otherwise use the default user location '${app.getPath("userData")}'`); console.log(" --no-update: Disable automatic updating."); console.log(" --hidden: Start the application hidden in the system tray."); console.log(" --help: Displays this help message."); @@ -147,7 +148,7 @@ async function loadConfig(): Promise { try { // Load local config and use it to override values from the one baked with the build - const localConfig = loadJsonFile(app.getPath("userData"), "config.json"); + const localConfig = argv["config"] ? loadJsonFile(argv["config"]) : loadJsonFile(app.getPath("userData"), "config.json"); // If the local config has a homeserver defined, don't use the homeserver from the build // config. This is to avoid a problem where Riot thinks there are multiple homeservers From f2986c6fca0360838d4fe1a7fe13ea9cc0931450 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Tue, 15 Oct 2024 13:52:58 +0100 Subject: [PATCH 2/5] Support using an env variable too. --- src/electron-main.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/electron-main.ts b/src/electron-main.ts index 9df1295756..f2d0538391 100644 --- a/src/electron-main.ts +++ b/src/electron-main.ts @@ -44,7 +44,10 @@ if (argv["help"]) { console.log(" --profile-dir {path}: Path to where to store the profile."); console.log(" --profile {name}: Name of alternate profile to use, allows for running multiple accounts."); console.log(" --devtools: Install and use react-devtools and react-perf."); - console.log(` --config: Path to the config.json file. Otherwise use the default user location '${app.getPath("userData")}'`); + console.log( + ` --config: Path to the config.json file. May also be specified via the ELEMENT_DESKTOP_CONFIG_JSON environment variable.\n` + + ` Otherwise use the default user location '${app.getPath("userData")}'`, + ); console.log(" --no-update: Disable automatic updating."); console.log(" --hidden: Start the application hidden in the system tray."); console.log(" --help: Displays this help message."); @@ -52,6 +55,8 @@ if (argv["help"]) { app.exit(); } +const LocalConfigLocation = process.env.ELEMENT_DESKTOP_CONFIG_JSON ?? argv["config"]; + // Electron creates the user data directory (with just an empty 'Dictionaries' directory...) // as soon as the app path is set, so pick a random path in it that must exist if it's a // real user data directory. @@ -148,7 +153,9 @@ async function loadConfig(): Promise { try { // Load local config and use it to override values from the one baked with the build - const localConfig = argv["config"] ? loadJsonFile(argv["config"]) : loadJsonFile(app.getPath("userData"), "config.json"); + const localConfig = LocalConfigLocation + ? loadJsonFile(LocalConfigLocation) + : loadJsonFile(app.getPath("userData"), "config.json"); // If the local config has a homeserver defined, don't use the homeserver from the build // config. This is to avoid a problem where Riot thinks there are multiple homeservers From a365621e79ee65e698dce3126f8e723beb902bbd Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Tue, 15 Oct 2024 13:55:22 +0100 Subject: [PATCH 3/5] Add docs. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index f39e2cb073..e284729e11 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,10 @@ $PROFILE` in which case it becomes `Element-$PROFILE`, or it is using one of the above created by a pre-1.7 install, in which case it will be `Riot` or `Riot-$PROFILE`. +You may also specify a different path entirely for the `config.json` file by +providing the `--config $YOUR_CONFIG_JSON_FILE` to the process, or via the +`ELEMENT_DESKTOP_CONFIG_JSON` environment variable. + # Translations To add a new translation, head to the [translating doc](https://github.com/vector-im/element-web/blob/develop/docs/translating.md). From e6a44d753d06e015e590dd0ae7aa1d3bedd511c8 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Thu, 17 Oct 2024 09:47:58 +0100 Subject: [PATCH 4/5] Add test for configuration arguments --- playwright/e2e/launch/config-options.spec.ts | 41 ++++++++++++++++++++ playwright/element-desktop-test.ts | 20 ++++++++-- playwright/fixtures/custom-config.json | 10 +++++ 3 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 playwright/e2e/launch/config-options.spec.ts create mode 100644 playwright/fixtures/custom-config.json diff --git a/playwright/e2e/launch/config-options.spec.ts b/playwright/e2e/launch/config-options.spec.ts new file mode 100644 index 0000000000..89ff428cd0 --- /dev/null +++ b/playwright/e2e/launch/config-options.spec.ts @@ -0,0 +1,41 @@ +/* +Copyright 2024 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only +Please see LICENSE files in the repository root for full details. +*/ + +import { resolve } from "node:path"; + +import { test, expect } from "../../element-desktop-test"; + +test.describe.only("App config options", () => { + test.describe("Should load custom config via env", () => { + test.slow(); + test.use({ + extraEnv: { + ELEMENT_DESKTOP_CONFIG_JSON: resolve(__dirname, "../..", "fixtures/custom-config.json"), + }, + }); + test("should launch and use configured homeserver", async ({ page }) => { + await page.locator("#matrixchat").waitFor(); + await page.locator(".mx_Welcome").waitFor(); + await expect(page).toHaveURL("vector://vector/webapp/#/welcome"); + await page.getByText("Sign in").click(); + await page.getByText("matrix.example.org", { exact: true }).waitFor(); + }); + }); + test.describe("Should load custom config via argument", () => { + test.slow(); + test.use({ + extraArgs: ["--config", resolve(__dirname, "../..", "fixtures/custom-config.json")], + }); + test("should launch and use configured homeserver", async ({ page }) => { + await page.locator("#matrixchat").waitFor(); + await page.locator(".mx_Welcome").waitFor(); + await expect(page).toHaveURL("vector://vector/webapp/#/welcome"); + await page.getByText("Sign in").click(); + await page.getByText("matrix.example.org", { exact: true }).waitFor(); + }); + }); +}); diff --git a/playwright/element-desktop-test.ts b/playwright/element-desktop-test.ts index 49d4e13697..4bdf691fc7 100644 --- a/playwright/element-desktop-test.ts +++ b/playwright/element-desktop-test.ts @@ -11,7 +11,16 @@ import fs from "node:fs/promises"; import path from "node:path"; import os from "node:os"; -export const test = base.extend<{ app: ElectronApplication; tmpDir: string }>({ +interface Fixtures { + app: ElectronApplication; + tmpDir: string; + extraEnv: Record; + extraArgs: string[]; +} + +export const test = base.extend({ + extraEnv: {}, + extraArgs: [], // eslint-disable-next-line no-empty-pattern tmpDir: async ({}, use) => { const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "element-desktop-tests-")); @@ -19,7 +28,7 @@ export const test = base.extend<{ app: ElectronApplication; tmpDir: string }>({ await use(tmpDir); await fs.rm(tmpDir, { recursive: true }); }, - app: async ({ tmpDir }, use) => { + app: async ({ tmpDir, extraEnv, extraArgs }, use) => { const args = ["--profile-dir", tmpDir]; const executablePath = process.env["ELEMENT_DESKTOP_EXECUTABLE"]; @@ -29,9 +38,12 @@ export const test = base.extend<{ app: ElectronApplication; tmpDir: string }>({ } const app = await electron.launch({ - env: process.env, + env: { + ...process.env, + ...extraEnv, + }, executablePath, - args, + args: [...args, ...extraArgs], }); app.process().stdout.pipe(process.stdout); diff --git a/playwright/fixtures/custom-config.json b/playwright/fixtures/custom-config.json new file mode 100644 index 0000000000..bcbc938c32 --- /dev/null +++ b/playwright/fixtures/custom-config.json @@ -0,0 +1,10 @@ +{ + "default_server_config": { + "m.homeserver": { + "base_url": "https://matrix.example.org" + }, + "m.identity_server": { + "base_url": "https://identity.example.org" + } + } +} From b79c75762a0e34f89537272de821876166f00d38 Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Thu, 17 Oct 2024 12:56:00 +0100 Subject: [PATCH 5/5] remove .only --- playwright/e2e/launch/config-options.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playwright/e2e/launch/config-options.spec.ts b/playwright/e2e/launch/config-options.spec.ts index 89ff428cd0..90afb19bda 100644 --- a/playwright/e2e/launch/config-options.spec.ts +++ b/playwright/e2e/launch/config-options.spec.ts @@ -9,7 +9,7 @@ import { resolve } from "node:path"; import { test, expect } from "../../element-desktop-test"; -test.describe.only("App config options", () => { +test.describe("App config options", () => { test.describe("Should load custom config via env", () => { test.slow(); test.use({