Files
wehub-resource-sync 1b8708893a
Security Scan / tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:12:26 +08:00

277 lines
10 KiB
JavaScript

import { test, expect } from './coverage-fixtures.js'
function mockCapabilities(page, capabilities) {
return page.route('**/api/models/capabilities', (route) => {
route.fulfill({
contentType: 'application/json',
body: JSON.stringify({ data: capabilities }),
})
})
}
function mockImageGeneration(page, images) {
return page.route('**/v1/images/generations', (route) => {
route.fulfill({
contentType: 'application/json',
body: JSON.stringify({
created: Math.floor(Date.now() / 1000),
data: images,
}),
})
})
}
function mockVideoGeneration(page, videos, onRequest) {
return page.route('**/video', (route) => {
if (route.request().method() !== 'POST') return route.continue()
onRequest?.(route.request().postDataJSON())
route.fulfill({
contentType: 'application/json',
body: JSON.stringify({
created: Math.floor(Date.now() / 1000),
data: videos,
}),
})
})
}
function mockTTSGeneration(page, filename) {
return page.route('**/tts', (route) => {
if (route.request().method() !== 'POST') return route.continue()
const wavHeader = new Uint8Array(44) // minimal WAV header
route.fulfill({
status: 200,
headers: {
'Content-Type': 'audio/wav',
'Content-Disposition': `attachment; filename="${filename}"`,
},
body: Buffer.from(wavHeader),
})
})
}
function mockSoundGeneration(page, filename) {
return page.route('**/v1/sound-generation', (route) => {
if (route.request().method() !== 'POST') return route.continue()
const wavHeader = new Uint8Array(44)
route.fulfill({
status: 200,
headers: {
'Content-Type': 'audio/wav',
'Content-Disposition': `attachment; filename="${filename}"`,
},
body: Buffer.from(wavHeader),
})
})
}
test.describe('Media History - Image Generation', () => {
test.beforeEach(async ({ page }) => {
await mockCapabilities(page, [{ id: 'test-image-model', capabilities: ['FLAG_IMAGE'] }])
})
test('history entry appears after image generation', async ({ page }) => {
await mockImageGeneration(page, [{ url: '/generated-images/test.png' }])
await page.goto('/app/image')
await expect(page.getByRole('button', { name: 'test-image-model' })).toBeVisible({ timeout: 10_000 })
await page.locator('.textarea').first().fill('a beautiful sunset')
await page.locator('button[type="submit"]').click()
// Image should appear in preview
await expect(page.locator('.media-result-grid img')).toBeVisible({ timeout: 10_000 })
// History entry should appear
await expect(page.getByTestId('media-history-item')).toHaveCount(1)
await expect(page.getByTestId('media-history-item')).toContainText('a beautiful sunset')
})
test('clicking history entry loads image in preview', async ({ page }) => {
let callCount = 0
await page.route('**/v1/images/generations', (route) => {
callCount++
route.fulfill({
contentType: 'application/json',
body: JSON.stringify({
created: Math.floor(Date.now() / 1000),
data: [{ url: `/generated-images/img${callCount}.png` }],
}),
})
})
await page.goto('/app/image')
await expect(page.getByRole('button', { name: 'test-image-model' })).toBeVisible({ timeout: 10_000 })
// Generate first image
await page.locator('.textarea').first().fill('first prompt')
await page.locator('button[type="submit"]').click()
await expect(page.locator('.media-result-grid img')).toBeVisible({ timeout: 10_000 })
// Generate second image
await page.locator('.textarea').first().fill('second prompt')
await page.locator('button[type="submit"]').click()
await expect(page.locator('.media-result-grid img[src="/generated-images/img2.png"]')).toBeVisible({ timeout: 10_000 })
// Click first history entry (second in list since newest first)
const items = page.getByTestId('media-history-item')
await expect(items).toHaveCount(2)
await items.last().click()
// Preview should show the first image
await expect(page.locator('.media-result-grid img[src="/generated-images/img1.png"]')).toBeVisible()
})
test('history persists across navigation', async ({ page }) => {
await mockImageGeneration(page, [{ url: '/generated-images/persist.png' }])
await page.goto('/app/image')
await expect(page.getByRole('button', { name: 'test-image-model' })).toBeVisible({ timeout: 10_000 })
await page.locator('.textarea').first().fill('persist test')
await page.locator('button[type="submit"]').click()
await expect(page.getByTestId('media-history-item')).toHaveCount(1, { timeout: 10_000 })
// Wait for debounced save
await page.waitForTimeout(600)
// Navigate away and back
await page.goto('/app')
await page.goto('/app/image')
// Re-register the mock for capabilities after navigation
await expect(page.getByTestId('media-history')).toBeVisible({ timeout: 10_000 })
await expect(page.getByTestId('media-history-item')).toHaveCount(1)
await expect(page.getByTestId('media-history-item')).toContainText('persist test')
})
test('delete removes a history entry', async ({ page }) => {
await mockImageGeneration(page, [{ url: '/generated-images/del.png' }])
await page.goto('/app/image')
await expect(page.getByRole('button', { name: 'test-image-model' })).toBeVisible({ timeout: 10_000 })
await page.locator('.textarea').first().fill('delete me')
await page.locator('button[type="submit"]').click()
await expect(page.getByTestId('media-history-item')).toHaveCount(1, { timeout: 10_000 })
// Hover and click delete
await page.getByTestId('media-history-item').hover()
await page.getByTestId('media-history-delete').click()
await expect(page.getByTestId('media-history-item')).toHaveCount(0)
})
test('clear all removes all entries', async ({ page }) => {
let callCount = 0
await page.route('**/v1/images/generations', (route) => {
callCount++
route.fulfill({
contentType: 'application/json',
body: JSON.stringify({
created: Math.floor(Date.now() / 1000),
data: [{ url: `/generated-images/img${callCount}.png` }],
}),
})
})
await page.goto('/app/image')
await expect(page.getByRole('button', { name: 'test-image-model' })).toBeVisible({ timeout: 10_000 })
// Generate two images
await page.locator('.textarea').first().fill('first')
await page.locator('button[type="submit"]').click()
await expect(page.getByTestId('media-history-item')).toHaveCount(1, { timeout: 10_000 })
await page.locator('.textarea').first().fill('second')
await page.locator('button[type="submit"]').click()
await expect(page.getByTestId('media-history-item')).toHaveCount(2, { timeout: 10_000 })
// Click clear all
await page.locator('.media-history-clear-btn').click()
await expect(page.getByTestId('media-history-item')).toHaveCount(0)
})
})
test.describe('Media History - TTS', () => {
test.beforeEach(async ({ page }) => {
await mockCapabilities(page, [{ id: 'test-tts-model', capabilities: ['FLAG_TTS'] }])
})
test('TTS history entry appears with server URL from Content-Disposition', async ({ page }) => {
await mockTTSGeneration(page, 'tts.wav')
await page.goto('/app/tts')
await expect(page.getByRole('button', { name: 'test-tts-model' })).toBeVisible({ timeout: 10_000 })
await page.locator('.textarea').fill('hello world')
await page.locator('button[type="submit"]').click()
// History entry should appear
await expect(page.getByTestId('media-history-item')).toHaveCount(1, { timeout: 10_000 })
await expect(page.getByTestId('media-history-item')).toContainText('hello world')
// Click the history entry to load it
await page.getByTestId('media-history-item').click()
// Audio element should use server URL
await expect(page.getByTestId('history-audio')).toHaveAttribute('src', '/generated-audio/tts.wav')
})
})
test.describe('Media History - Sound Generation', () => {
test.beforeEach(async ({ page }) => {
await mockCapabilities(page, [{ id: 'test-sound-model', capabilities: ['FLAG_SOUND_GENERATION'] }])
})
test('Sound generation history entry appears', async ({ page }) => {
await mockSoundGeneration(page, 'sound.wav')
await page.goto('/app/sound')
await expect(page.getByRole('button', { name: 'test-sound-model' })).toBeVisible({ timeout: 10_000 })
await page.locator('.textarea').first().fill('upbeat jazz')
await page.locator('button[type="submit"]').click()
await expect(page.getByTestId('media-history-item')).toHaveCount(1, { timeout: 10_000 })
await expect(page.getByTestId('media-history-item')).toContainText('upbeat jazz')
})
})
test.describe('Media History - Video Generation', () => {
test.beforeEach(async ({ page }) => {
await mockCapabilities(page, [{ id: 'test-video-model', capabilities: ['FLAG_VIDEO'] }])
})
test('Video history entry appears after generation', async ({ page }) => {
await mockVideoGeneration(page, [{ url: '/generated-videos/test.mp4' }])
await page.goto('/app/video')
await expect(page.getByRole('button', { name: 'test-video-model' })).toBeVisible({ timeout: 10_000 })
await page.locator('.textarea').first().fill('a running cat')
await page.locator('button[type="submit"]').click()
await expect(page.getByTestId('media-history-item')).toHaveCount(1, { timeout: 10_000 })
await expect(page.getByTestId('media-history-item')).toContainText('a running cat')
})
test('Avatar audio is forwarded to the video API', async ({ page }) => {
let requestBody
await mockVideoGeneration(page, [{ url: '/generated-videos/avatar.mp4' }], (body) => { requestBody = body })
await page.goto('/app/video')
await expect(page.getByRole('button', { name: 'test-video-model' })).toBeVisible({ timeout: 10_000 })
await page.getByRole('button', { name: 'Reference media' }).click()
await page.getByLabel('Avatar audio', { exact: true }).setInputFiles({
name: 'speech.wav',
mimeType: 'audio/wav',
buffer: Buffer.from('avatar speech'),
})
await page.locator('.textarea').first().fill('a presenter speaking to camera')
await page.locator('button[type="submit"]').click()
await expect.poll(() => requestBody?.audio).toBe(Buffer.from('avatar speech').toString('base64'))
})
})