feat: complete release preparation, 10+ ad mediation, CI/CD, and docker deployment
Some checks failed
CI Pipeline / Code Quality & Typecheck (push) Waiting to run
CI Pipeline / Test Suite (macos-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (ubuntu-latest) (push) Blocked by required conditions
CI Pipeline / Test Suite (windows-latest) (push) Blocked by required conditions
CI Pipeline / Build Validation (admin) (push) Blocked by required conditions
CI Pipeline / Build Validation (desktop) (push) Blocked by required conditions
Deploy Landing Page / deploy (push) Blocked by required conditions
Deploy Landing Page / build (push) Waiting to run
Release & Packaging Pipeline / Build & Publish Admin Docker Image (push) Failing after 8s
Release & Code Signing CA Pipeline / build-and-sign-windows (push) Failing after 1m51s
Build macOS / Build & Package (macOS) (push) Failing after 4s
Build macOS / Build & Package (macOS)-1 (push) Failing after 5s
Release & Code Signing CA Pipeline / build-and-sign-macos (push) Failing after 3s
Release & Packaging Pipeline / Package macOS Desktop App (push) Failing after 4s
Release & Packaging Pipeline / Package Windows Desktop App (push) Failing after 2m28s
Release & Packaging Pipeline / Publish Official GitHub Release (push) Has been skipped

This commit is contained in:
Yun Chan 2026-08-20 11:12:05 +09:00
parent 5cd1de6859
commit 708e20f747
406 changed files with 42464 additions and 6199 deletions

View file

@ -0,0 +1,93 @@
import { test, expect, _electron as electron } from '@playwright/test';
test.describe('Settings Modal E2E', () => {
test.describe.configure({ mode: 'serial' });
let electronApp: any;
let window: any;
test.beforeAll(async () => {
electronApp = await electron.launch({
// We assume this is run from apps/desktop or from root with appropriate context.
// Adjust this path if your build output is located elsewhere.
args: ['apps/desktop/out/main/index.js'],
env: {
...process.env,
NODE_ENV: 'test',
},
});
let found = false;
for (const w of electronApp.windows()) {
await w.waitForLoadState('domcontentloaded');
const t = await w.title();
if (t === 'D3RO Voice' || t === 'd3ro-voice') {
window = w;
found = true;
break;
}
}
if (!found) {
window = await electronApp.waitForEvent('window', {
predicate: async (page: any) => {
await page.waitForLoadState('domcontentloaded');
const t = await page.title();
return t === 'D3RO Voice' || t === 'd3ro-voice';
}
});
}
// Bypass onboarding for these tests
await window.evaluate(() => {
window.electronAPI.config.set({ key: 'onboardingCompleted', value: true });
});
// Reload window to apply bypassed onboarding
await window.reload();
await window.waitForLoadState('domcontentloaded');
});
test.afterAll(async () => {
if (electronApp) {
await electronApp.close();
}
});
test('should open Settings Modal and navigate through tabs', async () => {
// Open Settings Modal using IPC
await window.evaluate(() => {
window.dispatchEvent(new CustomEvent('d3ro:open-settings'));
});
// Wait for the Settings modal to appear by checking for a known tab or title
const tabs = window.locator('.MuiTab-root');
await expect(tabs.first()).toBeVisible({ timeout: 5000 });
// 1. General Tab (index 0)
await tabs.nth(0).click();
// Wait for something in General Tab to be visible
// "테마" or "언어" select boxes should be present. We'll check for switch inputs
await expect(window.locator('input[type="checkbox"]').first()).toBeVisible();
// 2. LLM Tab (index 3)
await tabs.nth(3).click();
// "D3RO API 서버 설정" is hardcoded in SettingsModal.tsx
await expect(window.locator('text="D3RO API 서버 설정"').first()).toBeVisible();
// 3. Cloud Sync Tab (index 5)
await tabs.nth(5).click();
// Cloud Sync tab might be empty or take time to render, give it a small wait
await window.waitForTimeout(500);
// 4. System / About Tab (index 6)
await tabs.nth(6).click();
// "D3RO-VOICE" is hardcoded in the About tab
await expect(window.locator('text="D3RO-VOICE"').first()).toBeVisible();
// Close the Settings Modal
// The close button has an X icon from lucide-react. Or we can just press Escape
await window.keyboard.press('Escape');
// Ensure the modal is closed
await expect(tabs.first()).toBeHidden({ timeout: 2000 });
});
});