π μμ± μ λ ₯μ΄ νμν ν μ€νΈ νλ©΄
μμ¦ νμ¬ μλΉμ€ ν
μ€νΈ μλν μ½λλ₯Ό Playwright + TypeScriptλ‘ μμ±νκ³ μλ€.
λ²νΌ ν΄λ¦, μ
λ ₯μ°½ κ²μ¦ κ°μ κΈ°λ³Έμ μΈ UI ν
μ€νΈλ μ΄λ μ λ μ΅μν΄μ‘λλ°,
μ΄λ²μ μ²μμΌλ‘ λ§μ΄ν¬ μ
λ ₯μ΄ νμμΈ νλ©΄μ μλνν΄μΌ νλ€.
μ€μ λ‘ μμ± μ
λ ₯μ΄ μλ μνμμλ λ€μ λ¨κ³λ‘ λμ΄κ° μ μλλ‘ λ§ν μμκ³ ,
λ§€λ² μ¬λμ΄ μ§μ λ§ν΄μΌ νλ€λ©΄ νκ· ν
μ€νΈλ λ°λ³΅ ν
μ€νΈμμ μλνμ μλ―Έκ° ν¬κ² μ€μ΄λ λ€.
κ·Έλμ μ΄λ»κ²λ μ¬λμ λͺ©μ리λ₯Ό μ°μ§ μκ³ ν
μ€νΈν λ°©λ²μ μ°Ύμλ³΄κΈ°λ‘ νλ€.
π μμ± νμΌμ λ§μ΄ν¬ μ λ ₯μ²λΌ μ°λ λ°©μ
κ²°λ‘ λΆν° λ§νλ©΄, μ€μ λ§μ΄ν¬ λμ 미리 μ€λΉν μμ± νμΌμ λ§μ΄ν¬ μ λ ₯μ²λΌ μ¬μ©νλ λ°©μμ μ ννλ€.
λ¨Όμ ν
μ€νΈμ μ¬μ©ν λ¬Έμ₯μ μ§μ μμ±νλ€.
μ€μ μ¬μ©μκ° λ§ν λ²ν λλ³Έμ κΈ°μ€μΌλ‘ λ¬Έμ₯μ λ§λ€κ³ ,
ElevenLabsλ₯Ό μ΄μ©ν΄ mp3 μμ± νμΌλ‘ μμ±νλ€.
μ²μμ mp3 νμΌμ κ·Έλλ‘ μ¬μ©νλ©΄ λ μ€ μμμ§λ§,
Playwrightμμ κ°μ§ λ§μ΄ν¬ μ
λ ₯μΌλ‘ μ¬μ©ν μ μλ νμΌ νμμ wav νμΌμ΄μλ€.
κ·Έλμ mp3 -> wav λ³νμ μ§ννκ³ , freeconvertλ₯Ό μ¬μ©ν΄ κ°λ¨ν ν΄κ²°νλ€.
π λ§μ΄ν¬ μλνμ ν΅μ¬μ μ΄ 3κ°μ§ μ΅μ
μ¬λ¬ μνμ°©μ€ λμ μκ² λ μ¬μ€μ,
λ§μ΄ν¬ μλνμ ν΅μ¬μ ν
μ€νΈ μ½λλ³΄λ€ λΈλΌμ°μ μ€ν μ΅μ
μ μλ€λ κ²μ΄μλ€.
μλ 3κ°μ§ μ΅μ μ΄ νμνλ€.
--use-fake-device-for-media-stream // νμ
μ°¨λ¨
--use-fake-ui-for-media-stream // μ₯μΉ λ체
--use-file-for-fake-audio-capture=PATH_TO_WAV // μ
λ ₯ μ리 μ 곡
μ΄ μ΅μ λ€μ΄ μ μ©λλ©΄ ν μ€νΈ νκ²½μμλ λ€μκ³Ό κ°μ μΌμ΄ λ²μ΄μ§λ€.
- λ§μ΄ν¬ permission νμ μ΄ λ¨μ§ μκ³
- Chromiumμ΄ μ€μ λ§μ΄ν¬ λμ κ°μ§ λ§μ΄ν¬ μ₯μΉ(fake mic)λ₯Ό μ¬μ©νλ©°
- μ§μ ν wav νμΌμ λ§μ΄ν¬ μ λ ₯ μ€νΈλ¦ΌμΌλ‘ νλ €λ³΄λΈλ€
μ¬κΈ°μ κ°μ₯ μ€μνλ ν¬μΈνΈλ μ΄κ±΄ ‘λ Ήμ’μ΄ μλλΌ ‘μ λ ₯’μ΄λ€.
wav νμΌμ κ·Έλ₯ μ¬μνλ κ² μλλ€. λΈλΌμ°μ μ
μ₯μμλ μ§μ§ μ
λ ₯ μ₯μΉμμ μλ¦¬κ° λ€μ΄μ€κ³ μλ€κ³ λ―Ώλ μνκ° λλ€.
κ·Έλμ STT(Speech To Text) κΈ°λ₯λ "μ§κΈ λκ΅°κ° λ§νκ³ μλ€"κ³ μΈμνκ³ μ μμ μΌλ‘ λμνλ€.
π Playwright μ€μ (JavaScript / TypeScript κΈ°μ€)
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
browserName: 'chromium',
launchOptions: {
args: [
'--use-fake-device-for-media-stream',
'--use-fake-ui-for-media-stream',
'--use-file-for-fake-audio-capture={wav νμΌ κ²½λ‘}'
],
},
},
});
π μλ리μ€μμλ μ΄λ κ² λμνλ€
μ΄ μνμμ ν μ€νΈ μλ리μ€μμ λ§μ΄ν¬ λ²νΌμ ν΄λ¦νλ©΄,
await page.getByRole('button', { name: 'λ§μ΄ν¬' }).click();
μ€μ λ§μ΄ν¬κ° μΌμ§λ λμ , 미리 μ€λΉν΄ λ wav νμΌμ΄ λ§μ΄ν¬ μ λ ₯μΌλ‘ λ€μ΄κ°λ€.
λλΆμ λ΄κ° κ²ͺκ³ μλ λ¬Έμ μλ, μ무 μλ¦¬κ° μμΌλ©΄ λ€μ λ¨κ³λ‘ λͺ» λμ΄κ°μ§ λͺ»νλ λ¬Έμ κ° κΉλνκ² ν΄κ²°λλ€.
μ¬λμ΄ μ§μ λ§νμ§ μμλ, μμ€ν
μ μμ±μ΄ μ
λ ₯λμλ€κ³ μΈμνκ³ λ€μ λ¨κ³λ‘ λμ΄κ°λ€.
π λ§λ¬΄λ¦¬νλ©°
λ§μ΄ν¬ μ λ ₯μ΄ νμν νλ©΄μ μλννκΈ° μ΄λ ΅λ€κ³ λ§μ°ν μκ°νλλ°, λ§μ ꡬ쑰λ₯Ό μ΄ν΄νκ³ λλ λΈλΌμ°μ κ° μ λ ₯μ μ΄λ»κ² μΈμνλμ§κ° ν΅μ¬μ΄μλ€.
λ€λ§ μ΄ λ°©μμ λͺ©μ μ λΆλͺ ν ν΄λ νμκ° μλ€. μ΄ μλνλ λ§μ΄ν¬ μ λ ₯ κΈ°λ₯ μ체μ μ νλλ₯Ό κ²μ¦νκΈ° μν μ©λλ μλλ€.
νμ λμΌν wav νμΌμ΄ μ λ ₯λκΈ° λλ¬Έμ, μμ± μΈμμ νμ§μ΄λ STT κ²°κ³Όμ μ νμ±μ ν μ€νΈνλ λ°μλ μ ν©νμ§ μλ€.
λ΄κ° μ΄ λ°©μμ μ¬μ©ν μ΄μ λ "μμ± μ λ ₯μ΄ μμ΄μΌλ§ λ€μ λ¨κ³λ‘ λμ΄κ° μ μλ νλ©΄μ μλννκΈ° μν΄μ" λ¨ νλμλ€.
μ¦, λ§μ΄ν¬ κΈ°λ₯μ ν μ€νΈνκΈ° μν μλνκ° μλλΌ λ§μ΄ν¬ μ λ ₯μ΄λΌλ 쑰건μ μμ μ μΌλ‘ ν΅κ³ΌνκΈ° μν μλ¨μ΄μλ€.
μ΄λ κ² μ κ·Όνλ μ¬λμ΄ μ§μ λ§νμ§ μμλ λκ³ , νκ· ν μ€νΈλ λ°λ³΅ ν μ€νΈμμλ λ§νμ§ μλ μλν νλ¦μ λ§λ€ μ μμλ€.
μλνμμ μ€μν 건 λͺ¨λ κΈ°λ₯μ μλ²½νκ² κ²μ¦νλ κ²λ³΄λ€, μ΄λκΉμ§λ₯Ό μλνλ‘ μ»€λ²ν μ§ λͺ νν μ νλ κ²μ΄λΌλ μκ°λ ν¨κ» λ€μλ€.
'π Quality Assurance > π Experience & Insight' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
| π§ λ€μν μΈ‘λ©΄μμ μ±μ₯ν μ μμλ λ¦΄λ¦¬μ¦ νκ³ (2) | 2026.01.31 |
|---|---|
| π§ λ€μ¬λ€λνλ λ¦΄λ¦¬μ¦ νκ³ (2) | 2026.01.03 |
| π‘ about:blank, λ²κ·Έκ° μλμλ€ (0) | 2025.12.13 |
| π§ κ°μ΄ μ‘°κΈμ© μ‘νκΈ° μμν λ¦΄λ¦¬μ¦ νκ³ (6) | 2025.11.01 |
| π§ μ μ 1μΈ QA μμ§λμ΄μ μΈμ 첫 λ¦΄λ¦¬μ¦ νκ³ (8) | 2025.10.12 |