-
Notifications
You must be signed in to change notification settings - Fork 345
Add: VRTを追加 #1688
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add: VRTを追加 #1688
Changes from all commits
30c6540
56fda0f
45b11a4
7f42bf5
b41da3a
496fd97
d97d77e
0d36c2c
9ae7800
290fb11
5213d51
1a74aea
38f51ee
8447c9d
d30efed
a8c88a1
61e9447
6ee6829
d8bacab
651e524
c5af75f
d83d58d
2336571
b9616f1
d7bbc38
fae289c
16ec9d3
e8ecaec
857efe0
e209054
3adb508
28a6c14
fc6a9de
218e959
bee108e
267cd24
8d3e87e
7b300ee
383928e
392b88a
1840c7c
759f80c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 基本的に多分画面ごとにテストがあって、その中で1つのテストとしてスクリーンショットテストがあるのかなと想像してます。 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| import path from "path"; | ||
| import fs from "fs/promises"; | ||
| import { test, expect } from "@playwright/test"; | ||
| import { gotoHome, navigateToMain } from "../navigators"; | ||
| import { | ||
| Speaker, | ||
| SpeakerFromJSON, | ||
| SpeakerInfo, | ||
| SpeakerInfoFromJSON, | ||
| SpeakerInfoToJSON, | ||
| SpeakerToJSON, | ||
| } from "@/openapi"; | ||
|
|
||
| let speakerImages: { | ||
| portrait: string; | ||
| icon: string; | ||
| }[]; | ||
|
|
||
| /** | ||
| * 差し替え用の立ち絵・アイコンを取得する。 | ||
| */ | ||
| async function getSpeakerImages(): Promise< | ||
| { | ||
| portrait: string; | ||
| icon: string; | ||
| }[] | ||
| > { | ||
| if (!speakerImages) { | ||
| const assetsPath = path.resolve(__dirname, "assets"); | ||
| const images = await fs.readdir(assetsPath); | ||
| const icons = images.filter((image) => image.startsWith("icon")); | ||
| icons.sort( | ||
| (a, b) => | ||
| parseInt(a.split(".")[0].split("_")[1]) - | ||
| parseInt(b.split(".")[0].split("_")[1]) | ||
| ); | ||
| speakerImages = await Promise.all( | ||
| icons.map(async (iconPath) => { | ||
| const portraitPath = iconPath.replace("icon_", "portrait_"); | ||
| const portrait = await fs.readFile( | ||
| path.join(assetsPath, portraitPath), | ||
| "base64" | ||
| ); | ||
| const icon = await fs.readFile( | ||
| path.join(assetsPath, iconPath), | ||
| "base64" | ||
| ); | ||
|
|
||
| return { portrait, icon }; | ||
| }) | ||
| ); | ||
| } | ||
| return speakerImages; | ||
| } | ||
|
|
||
| test.beforeEach(async ({ page }) => { | ||
Hiroshiba marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| let speakers: Speaker[]; | ||
| const speakerImages = await getSpeakerImages(); | ||
| // Voicevox Nemo EngineでもVoicevox Engineでも同じ結果が選られるように、 | ||
| // GET /speakers、GET /speaker_infoの話者名、スタイル名、画像を差し替える。 | ||
| await page.route(/\/speakers$/, async (route) => { | ||
| const response = await route.fetch(); | ||
| const json: Speaker[] = await response | ||
| .json() | ||
| .then((json) => json.map(SpeakerFromJSON)); | ||
| let i = 0; | ||
| for (const speaker of json) { | ||
| i++; | ||
| speaker.name = `Speaker ${i}`; | ||
| let j = 0; | ||
| for (const style of speaker.styles) { | ||
| j++; | ||
| style.name = `Style ${i}-${j}`; | ||
| } | ||
| } | ||
| speakers = json; | ||
| await route.fulfill({ | ||
| status: 200, | ||
| headers: { | ||
| "Access-Control-Allow-Origin": "*", | ||
| "Content-Type": "application/json", | ||
| }, | ||
| body: JSON.stringify(json.map(SpeakerToJSON)), | ||
| }); | ||
| }); | ||
| await page.route(/\/speaker_info\?/, async (route) => { | ||
| if (!speakers) { | ||
| // Unreachableのはず | ||
| throw new Error("speakers is not initialized"); | ||
| } | ||
| const url = new URL(route.request().url()); | ||
| const speakerUuid = url.searchParams.get("speaker_uuid"); | ||
| if (!speakerUuid) { | ||
| throw new Error("speaker_uuid is not set"); | ||
| } | ||
| const response = await route.fetch(); | ||
| const json: SpeakerInfo = await response.json().then(SpeakerInfoFromJSON); | ||
| const speakerIndex = speakers.findIndex( | ||
| (speaker) => speaker.speakerUuid === speakerUuid | ||
| ); | ||
| if (speakerIndex === -1) { | ||
| throw new Error(`speaker_uuid=${speakerUuid} is not found`); | ||
| } | ||
| const image = speakerImages[speakerIndex % speakerImages.length]; | ||
| json.portrait = image.portrait; | ||
| for (const style of json.styleInfos) { | ||
| style.icon = image.icon; | ||
| if ("portrait" in style) { | ||
| delete style.portrait; | ||
| } | ||
| } | ||
| await route.fulfill({ | ||
| status: 200, | ||
| headers: { | ||
| "Access-Control-Allow-Origin": "*", | ||
| "Content-Type": "application/json", | ||
| }, | ||
| body: JSON.stringify(SpeakerInfoToJSON(json)), | ||
| }); | ||
| }); | ||
| }); | ||
| test.beforeEach(gotoHome); | ||
|
|
||
| test("メイン画面の表示", async ({ page }) => { | ||
| test.skip(process.platform !== "win32", "Windows以外のためスキップします"); | ||
| await navigateToMain(page); | ||
|
|
||
| // eslint-disable-next-line no-constant-condition | ||
| while (true) { | ||
|
Comment on lines
+128
to
+129
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. これ一生テストが終わらないとかありそうなので、20回ぐらいトライしたらエラーにするみたいな処理書いてもいいかも?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Playwright側でタイムアウトしてくれるので大丈夫だと思います。
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. なるほどです。 ESLintの警告を無視しているのも気になったのですが、調べた感じこれはデフォルトの挙動を変えないかという議論中でした。 |
||
| await page.locator(".audio-cell:nth-child(1) .q-field").click(); | ||
| await page.waitForTimeout(100); | ||
| if ( | ||
| (await page | ||
| .locator(".character-portrait-wrapper .character-name") | ||
| .innerText()) !== "(表示エラー)" && | ||
| (await page.locator(".character-portrait-wrapper .loading").count()) === 0 | ||
| ) { | ||
| break; | ||
| } | ||
| } | ||
| await expect(page).toHaveScreenshot("メイン画面.png"); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
今気づいたのですが、このjobを実行するかどうかを
shouldUpdateSnapshotsの出力から判定できるかもですね。if: steps.check-whether-to-update-snapshots.outputs.shouldUpdateSnapshots == 'true'をここに書くとかで。