From 7cc32cc3fb65225f21c02366c33618f3bac81318 Mon Sep 17 00:00:00 2001 From: Hiroshiba Date: Mon, 30 Dec 2024 07:50:01 +0900 Subject: [PATCH] =?UTF-8?q?test:=20VVPP=E3=83=87=E3=83=95=E3=82=A9?= =?UTF-8?q?=E3=83=AB=E3=83=88=E3=82=A8=E3=83=B3=E3=82=B8=E3=83=B3=E3=82=92?= =?UTF-8?q?=E4=BD=BF=E3=81=86=E3=83=86=E3=82=B9=E3=83=88=E3=82=92=E6=9B=B8?= =?UTF-8?q?=E3=81=8F=20(#2444)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.test-electron-default-vvpp | 17 ++++ .../electron/engineAndVvppController.ts | 2 +- src/domain/defaultEngine/envEngineInfo.ts | 7 +- tests/e2e/electron/example.spec.ts | 93 +++++++++++++------ vite.config.mts | 15 ++- 5 files changed, 100 insertions(+), 34 deletions(-) create mode 100644 .env.test-electron-default-vvpp diff --git a/.env.test-electron-default-vvpp b/.env.test-electron-default-vvpp new file mode 100644 index 0000000000..94255249d3 --- /dev/null +++ b/.env.test-electron-default-vvpp @@ -0,0 +1,17 @@ +# VVPPデフォルトエンジンでのテスト用の.envファイル。 + +VITE_APP_NAME=voicevox +VITE_DEFAULT_ENGINE_INFOS=`[ + { + "type": "downloadVvpp", + "name": "VOICEVOX Nemo Engine", + "uuid": "208cf94d-43d2-4cf5-abc0-9783cac36d29", + "executionEnabled": true, + "executionArgs": [], + "host": "http://127.0.0.1:50121", + "latestUrl": "https://voicevox.hiroshiba.jp/nemoLatestDefaultEngineInfos.json" + } +]` +VITE_OFFICIAL_WEBSITE_URL=https://voicevox.hiroshiba.jp/ +VITE_LATEST_UPDATE_INFOS_URL=https://voicevox.hiroshiba.jp/updateInfos.json +VITE_GTM_CONTAINER_ID=GTM-DUMMY diff --git a/src/backend/electron/engineAndVvppController.ts b/src/backend/electron/engineAndVvppController.ts index 5e0622c3ef..076a484570 100644 --- a/src/backend/electron/engineAndVvppController.ts +++ b/src/backend/electron/engineAndVvppController.ts @@ -50,11 +50,11 @@ export class EngineAndVvppController { await this.vvppManager.install(vvppPath); return true; } catch (e) { + log.error(`Failed to install ${vvppPath},`, e); dialog.showErrorBox( "インストールエラー", `${vvppPath} をインストールできませんでした。`, ); - log.error(`Failed to install ${vvppPath},`, e); return false; } } diff --git a/src/domain/defaultEngine/envEngineInfo.ts b/src/domain/defaultEngine/envEngineInfo.ts index f45098c264..4feee23d5c 100644 --- a/src/domain/defaultEngine/envEngineInfo.ts +++ b/src/domain/defaultEngine/envEngineInfo.ts @@ -5,6 +5,7 @@ import { z } from "zod"; import { engineIdSchema } from "@/type/preload"; +import { isElectron } from "@/helpers/platform"; /** .envに書くデフォルトエンジン情報のスキーマ */ const envEngineInfoSchema = z @@ -34,8 +35,12 @@ type EnvEngineInfoType = z.infer; /** .envからデフォルトエンジン情報を読み込む */ export function loadEnvEngineInfos(): EnvEngineInfoType[] { + // electronのときはプロセスの環境変数を参照する。 + // NOTE: electronテスト環境を切り替えるため。テスト環境が1本化されればimport.meta.envを使う。 const defaultEngineInfosEnv = - import.meta.env.VITE_DEFAULT_ENGINE_INFOS ?? "[]"; + (isElectron + ? process.env.VITE_DEFAULT_ENGINE_INFOS + : import.meta.env.VITE_DEFAULT_ENGINE_INFOS) ?? "[]"; // FIXME: 「.envを書き換えてください」というログを出したい // NOTE: domainディレクトリなのでログを出す方法がなく、Errorオプションのcauseを用いてもelectron-logがcauseのログを出してくれない diff --git a/tests/e2e/electron/example.spec.ts b/tests/e2e/electron/example.spec.ts index c2616c1f2c..d67508d9c0 100644 --- a/tests/e2e/electron/example.spec.ts +++ b/tests/e2e/electron/example.spec.ts @@ -3,10 +3,9 @@ import os from "os"; import path from "path"; import { _electron as electron, test } from "@playwright/test"; import dotenv from "dotenv"; +import { BrowserWindow, MessageBoxSyncOptions } from "electron"; test.beforeAll(async () => { - dotenv.config(); // FIXME: エンジンの設定直読み - console.log("Waiting for main.js to be built..."); while (true) { try { @@ -19,40 +18,80 @@ test.beforeAll(async () => { console.log("main.js is built."); }); -// キャッシュなどでテスト結果が変化しないように、appDataをテスト起動時に毎回消去する。 -// cf: https://www.electronjs.org/ja/docs/latest/api/app#appgetpathname -const appDataMap: Partial> = { - win32: process.env.APPDATA, - darwin: os.homedir() + "/Library/Application Support", - linux: process.env.XDG_CONFIG_HOME || os.homedir() + "/.config", -} as const; +test.beforeEach(async () => { + // キャッシュなどでテスト結果が変化しないように、appDataをテスト起動時に毎回消去する。 + // cf: https://www.electronjs.org/ja/docs/latest/api/app#appgetpathname + const appDataMap: Partial> = { + win32: process.env.APPDATA, + darwin: os.homedir() + "/Library/Application Support", + linux: process.env.XDG_CONFIG_HOME || os.homedir() + "/.config", + } as const; -const appData = appDataMap[process.platform]; -if (!appData) { - throw new Error("Unsupported platform"); -} -const userDir = path.resolve(appData, `${process.env.VITE_APP_NAME}-test`); + const appData = appDataMap[process.platform]; + if (!appData) { + throw new Error("Unsupported platform"); + } + const userDir = path.resolve(appData, `${process.env.VITE_APP_NAME}-test`); -test.beforeEach(async () => { await fs.rm(userDir, { recursive: true, force: true, }); }); -test("起動したら「利用規約に関するお知らせ」が表示される", async () => { - const app = await electron.launch({ - args: ["--no-sandbox", "."], // NOTE: --no-sandbox はUbuntu 24.04で動かすのに必要 - timeout: process.env.CI ? 0 : 60000, - }); +[ + { + envName: ".env環境", + envPath: ".env", + }, + { + envName: "VVPPデフォルトエンジン", + envPath: ".env.test-electron-default-vvpp", + }, +].forEach(({ envName, envPath }) => { + test.describe(`${envName}`, () => { + test.beforeEach(() => { + dotenv.config({ path: envPath, override: true }); + }); - const sut = await app.firstWindow({ - timeout: process.env.CI ? 60000 : 30000, - }); + test("起動したら「利用規約に関するお知らせ」が表示される", async () => { + const app = await electron.launch({ + args: ["--no-sandbox", "."], // NOTE: --no-sandbox はUbuntu 24.04で動かすのに必要 + timeout: process.env.CI ? 0 : 60000, + }); + + // ダイアログのモック + await app.evaluate((electron) => { + // @ts-expect-error 2種のオーバーロードを無視する + electron.dialog.showMessageBoxSync = ( + win: BrowserWindow, + options: MessageBoxSyncOptions, + ) => { + // デフォルトエンジンのインストールの確認ダイアログ + if ( + options.title == "デフォルトエンジンのインストール" && + options.buttons?.[0] == "インストール" + ) { + return 0; + } + + throw new Error(`Unexpected dialog: ${JSON.stringify(options)}`); + }; + }); + + // ログを表示 + app.on("console", (msg) => { + console.log(msg.text()); + }); - // エンジンが起動し「利用規約に関するお知らせ」が表示されるのを待つ - await sut.waitForSelector("text=利用規約に関するお知らせ", { - timeout: 60000, + const sut = await app.firstWindow({ + timeout: process.env.CI ? 60000 : 30000, + }); + // エンジンが起動し「利用規約に関するお知らせ」が表示されるのを待つ + await sut.waitForSelector("text=利用規約に関するお知らせ", { + timeout: 60000, + }); + await app.close(); + }); }); - await app.close(); }); diff --git a/vite.config.mts b/vite.config.mts index c3834795a7..e4da29c038 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -8,13 +8,18 @@ import vue from "@vitejs/plugin-vue"; import checker from "vite-plugin-checker"; import { BuildOptions, defineConfig, loadEnv, Plugin } from "vite"; import { quasar } from "@quasar/vite-plugin"; +import { z } from "zod"; const isElectron = process.env.VITE_TARGET === "electron"; const isBrowser = process.env.VITE_TARGET === "browser"; export default defineConfig((options) => { + const mode = z + .enum(["development", "test", "production"]) + .parse(options.mode); + const packageName = process.env.npm_package_name; - const env = loadEnv(options.mode, import.meta.dirname); + const env = loadEnv(mode, import.meta.dirname); if (!packageName?.startsWith(env.VITE_APP_NAME)) { throw new Error( `"package.json"の"name":"${packageName}"は"VITE_APP_NAME":"${env.VITE_APP_NAME}"から始まっている必要があります`, @@ -32,19 +37,19 @@ export default defineConfig((options) => { throw new Error(`Unsupported platform: ${process.platform}`); } process.env.VITE_7Z_BIN_NAME = - (options.mode === "development" + (mode !== "production" ? path.join(import.meta.dirname, "vendored", "7z") + path.sep : "") + sevenZipBinName; process.env.VITE_APP_VERSION = process.env.npm_package_version; - const shouldEmitSourcemap = ["development", "test"].includes(options.mode); + const shouldEmitSourcemap = ["development", "test"].includes(mode); const sourcemap: BuildOptions["sourcemap"] = shouldEmitSourcemap ? "inline" : false; // ref: electronの起動をスキップしてデバッグ起動を軽くする const skipLahnchElectron = - options.mode === "test" || process.env.SKIP_LAUNCH_ELECTRON === "1"; + mode === "test" || process.env.SKIP_LAUNCH_ELECTRON === "1"; return { root: path.resolve(import.meta.dirname, "src"), @@ -71,7 +76,7 @@ export default defineConfig((options) => { plugins: [ vue(), quasar({ autoImportComponentCase: "pascal" }), - options.mode !== "test" && + mode !== "test" && checker({ overlay: false, eslint: {