feat: publish av-tools 0.1.0

This commit is contained in:
2026-07-24 14:58:03 +02:00
commit fcc537b024
254 changed files with 63270 additions and 0 deletions

View File

@@ -0,0 +1,256 @@
import { expect, test } from '@playwright/test';
import {
observeRuntime,
startNestedStaticServer,
type NestedStaticServer,
} from './browser-helpers';
test.describe('static application and Toolbox shell', () => {
test('runs standalone, stays lazy and supports keyboard-operated shell controls', async ({
page,
}) => {
const runtime = observeRuntime(page);
await page.goto('/');
await expect(page).toHaveTitle('Audio & Video Tools');
await expect(
page.getByRole('heading', {
level: 1,
name: 'Audio & Video Tools',
})
).toBeVisible();
await expect(page.locator('[data-toolbox-context]')).toHaveAttribute(
'data-toolbox-context',
'standalone'
);
await expect(page.getByRole('main')).toBeVisible();
await expect(
page.getByRole('tab', { name: 'Quick Convert' })
).toHaveAttribute('aria-selected', 'true');
await expect(
page.getByRole('button', { name: 'Choose files' })
).toBeEnabled();
expect(
runtime.requests.some((url) => url.includes('/vendor/ffmpeg/'))
).toBe(false);
expect(
runtime.requests.some((url) => /\/assets\/worker-[^/]+\.js$/u.test(url))
).toBe(false);
const helpButton = page.getByRole('button', { name: 'Help' });
await helpButton.focus();
await page.keyboard.press('Enter');
const helpDialog = page.getByRole('dialog', {
name: 'Audio & Video Tools',
});
await expect(helpDialog).toBeVisible();
await expect(
helpDialog.getByRole('heading', {
level: 2,
name: 'Audio & Video Tools',
})
).toBeVisible();
await page.keyboard.press('Escape');
await expect(helpDialog).toBeHidden();
const personalizeButton = page.getByRole('button', {
name: 'Personalize',
});
await personalizeButton.focus();
await page.keyboard.press('Enter');
await expect(
page.getByRole('heading', {
level: 2,
name: 'Personalize your toolbox',
})
).toBeVisible();
await page.getByRole('button', { name: 'Dark' }).click();
await expect(page.locator('.toolbox-shell').first()).toHaveAttribute(
'data-toolbox-theme',
'dark'
);
await page.keyboard.press('Escape');
await expect(personalizeButton).toBeFocused();
const networkUrls = runtime.requests.filter((url) => /^https?:/u.test(url));
expect(
networkUrls.every(
(url) => new URL(url).origin === 'http://127.0.0.1:4173'
)
).toBe(true);
expect(runtime.failedRequests).toEqual([]);
expect(runtime.pageErrors).toEqual([]);
expect(runtime.consoleErrors).toEqual([]);
});
test('keeps preview primary and exposes accessible Edit drawers on narrow screens', async ({
page,
}) => {
await page.setViewportSize({ width: 390, height: 844 });
await page.goto('/');
await page.getByRole('tab', { name: 'Edit' }).click();
await expect(page.getByRole('heading', { name: 'Preview' })).toBeVisible();
const mediaDrawer = page.locator('#edit-media-drawer');
const inspectorDrawer = page.locator('#edit-inspector-drawer');
await expect(mediaDrawer).toBeHidden();
await expect(inspectorDrawer).toBeHidden();
const sources = page.getByRole('button', { name: 'Sources' });
await sources.click();
await expect(mediaDrawer).toBeVisible();
await expect(
mediaDrawer.getByRole('button', { name: 'Close media bin' })
).toBeFocused();
await page.keyboard.press('Escape');
await expect(mediaDrawer).toBeHidden();
await expect(sources).toBeFocused();
const inspector = page.getByRole('button', { name: 'Inspector' });
await inspector.click();
await expect(inspectorDrawer).toBeVisible();
const closeInspector = inspectorDrawer.getByRole('button', {
name: 'Close inspector',
});
await expect(closeInspector).toBeFocused();
await closeInspector.click();
await expect(inspectorDrawer).toBeHidden();
await expect(inspector).toBeFocused();
});
});
test.describe('nested static deployment and Toolbox context', () => {
let nestedServer: NestedStaticServer;
test.beforeAll(async () => {
nestedServer = await startNestedStaticServer();
});
test.afterAll(async () => {
await nestedServer.close();
});
test('loads a valid same-origin catalog and all runtime assets below the nested path', async ({
page,
}) => {
const runtime = observeRuntime(page);
await page.goto(`${nestedServer.appUrl}?toolbox=../toolbox.catalog.json`);
await expect(page.locator('[data-toolbox-context]')).toHaveAttribute(
'data-toolbox-context',
'connected'
);
await expect(
page.getByRole('link', { name: 'add·ideas Toolbox' })
).toHaveAttribute('href', `${nestedServer.origin}/deep/nested/`);
await page.getByRole('button', { name: 'Apps' }).click();
const appSwitcher = page.getByRole('navigation', {
name: 'Toolbox applications',
});
await expect(
appSwitcher.getByRole('link', { name: 'Browser Test Tool' })
).toBeVisible();
await expect(
appSwitcher.getByRole('link', { name: 'Audio & Video Tools' })
).toBeVisible();
await page.keyboard.press('Escape');
expect(
runtime.requests.some((url) =>
/\/deep\/nested\/av\/assets\/index-[^/]+\.js$/u.test(url)
)
).toBe(true);
expect(
runtime.requests.some((url) =>
/\/deep\/nested\/av\/assets\/index-[^/]+\.css$/u.test(url)
)
).toBe(true);
expect(
runtime.requests.some((url) => url.includes('/vendor/ffmpeg/'))
).toBe(false);
await page.getByText('Engine & browser').click();
await page.getByLabel('Engine mode').selectOption('force-single-thread');
await page.getByRole('button', { name: 'Initialize engine' }).click();
await expect(
page
.locator('.engine-pill')
.filter({ hasText: 'Single-threaded compatibility mode' })
).toBeVisible({ timeout: 120_000 });
await expect(page.getByText('0.12.15 / 0.12.10')).toBeVisible();
await expect(
page.getByText('Encoders').locator('..').locator('dd')
).not.toHaveText('0');
await expect(
page.getByText('Filters').locator('..').locator('dd')
).not.toHaveText('0');
const coreScript = runtime.responses.find((response) =>
response.url.endsWith(
'/deep/nested/av/vendor/ffmpeg/0.12.10/st/ffmpeg-core.js'
)
);
const coreWasm = runtime.responses.find((response) =>
response.url.endsWith(
'/deep/nested/av/vendor/ffmpeg/0.12.10/st/ffmpeg-core.wasm'
)
);
expect(coreScript).toMatchObject({
status: 200,
contentType: 'text/javascript; charset=utf-8',
});
expect(coreWasm).toMatchObject({
status: 200,
contentType: 'application/wasm',
});
expect(
runtime.responses.some((response) =>
/\/deep\/nested\/av\/assets\/worker-[^/]+\.js$/u.test(response.url)
)
).toBe(true);
const networkUrls = runtime.requests.filter((url) => /^https?:/u.test(url));
expect(
networkUrls.every((url) => new URL(url).origin === nestedServer.origin)
).toBe(true);
expect(runtime.failedRequests).toEqual([]);
expect(runtime.pageErrors).toEqual([]);
expect(runtime.consoleErrors).toEqual([]);
});
test('rejects an invalid same-origin catalog and remains usable standalone', async ({
page,
}) => {
const runtime = observeRuntime(page);
await page.goto(`${nestedServer.appUrl}?toolbox=../invalid-catalog.json`);
await expect
.poll(() => runtime.consoleWarnings.length, { timeout: 10_000 })
.toBeGreaterThan(0);
await expect(page.locator('[data-toolbox-context]')).toHaveAttribute(
'data-toolbox-context',
'standalone'
);
await expect(
page.getByRole('button', { name: 'Choose files' })
).toBeEnabled();
expect(
runtime.consoleWarnings.some((warning) =>
warning.includes('Toolbox context unavailable; continuing standalone.')
)
).toBe(true);
expect(
runtime.requests.some(
(url) =>
url === `${nestedServer.origin}/deep/nested/invalid-catalog.json`
)
).toBe(true);
expect(runtime.failedRequests).toEqual([]);
expect(runtime.pageErrors).toEqual([]);
expect(runtime.consoleErrors).toEqual([]);
});
});