diff --git a/.claude/skills/web-test/SKILL.md b/.claude/skills/web-test/SKILL.md index a7b43fcd..cd864d55 100644 --- a/.claude/skills/web-test/SKILL.md +++ b/.claude/skills/web-test/SKILL.md @@ -284,6 +284,7 @@ Clear filters. Without arguments clears all, with `{ field }` clears specific ba #### `getPage()` → Playwright Page (raw, for advanced scripting) #### `startRecording(path, opts?)` / `stopRecording()` → MP4 video recording #### `showCaption(text, opts?)` / `hideCaption()` → text overlay on page +#### `showTitleSlide(text, opts?)` / `hideTitleSlide()` → full-screen title card (intro/outro) #### `isRecording()` → boolean See [recording.md](recording.md) for setup (ffmpeg), API details, and examples. diff --git a/.claude/skills/web-test/recording.md b/.claude/skills/web-test/recording.md index 5bfb58cb..f52cf1e3 100644 --- a/.claude/skills/web-test/recording.md +++ b/.claude/skills/web-test/recording.md @@ -94,24 +94,48 @@ The overlay uses `pointer-events: none` — does not interfere with clicking. Remove the caption overlay. -## Example: Record a workflow with captions +### `showTitleSlide(text, opts?)` + +Display a full-screen title slide overlay (gradient background, centered text). Useful for intro/outro frames in video recordings. Calling again updates the content. + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `text` | string | required | Title text (`\n` → line break) | +| `opts.subtitle` | string | `''` | Smaller text below the title | +| `opts.background` | string | dark gradient | CSS background | +| `opts.color` | string | `'#fff'` | Text color | +| `opts.fontSize` | number | 36 | Title font size in px | + +The overlay covers the entire viewport with `z-index: 999999` and `pointer-events: none`. + +### `hideTitleSlide()` + +Remove the title slide overlay. + +## Example: Record a workflow with title slide and captions ```js await startRecording('recordings/create-order.mp4'); -await showCaption('Step 1: Navigate to Sales'); +// Title slide — 4 seconds +await showTitleSlide('Создание заказа клиента', { subtitle: 'Демонстрация' }); +await wait(4); +await hideTitleSlide(); + +// Steps with captions +await showCaption('Шаг 1. Переходим в раздел «Продажи»'); await navigateSection('Продажи'); await wait(1); -await showCaption('Step 2: Open Customer Orders'); +await showCaption('Шаг 2. Открываем заказы клиентов'); await openCommand('Заказы клиентов'); await wait(1); -await showCaption('Step 3: Create new order'); +await showCaption('Шаг 3. Создаём новый заказ'); await clickElement('Создать'); await wait(2); -await showCaption('Step 4: Fill header fields'); +await showCaption('Шаг 4. Заполняем шапку'); await fillFields({ 'Организация': 'Конфетпром', 'Контрагент': 'Альфа' }); await wait(2); diff --git a/.claude/skills/web-test/scripts/browser.mjs b/.claude/skills/web-test/scripts/browser.mjs index 304d6586..179e374b 100644 --- a/.claude/skills/web-test/scripts/browser.mjs +++ b/.claude/skills/web-test/scripts/browser.mjs @@ -2570,6 +2570,55 @@ export async function hideCaption() { }); } +/** + * Show a full-screen title slide overlay (for video recordings). + * Repeated calls update the content. Use hideTitleSlide() to remove. + * @param {string} text Title text (\n → line break) + * @param {object} [opts] + * @param {string} [opts.subtitle] Smaller text below the title + * @param {string} [opts.background] CSS background (default: dark gradient) + * @param {string} [opts.color] Text color (default: '#fff') + * @param {number} [opts.fontSize] Title font size in px (default: 36) + */ +export async function showTitleSlide(text, opts = {}) { + ensureConnected(); + const { + subtitle = '', + background = 'linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%)', + color = '#fff', + fontSize = 36, + } = opts; + await page.evaluate(({ text, subtitle, background, color, fontSize }) => { + let div = document.getElementById('__web_test_title'); + if (!div) { + div = document.createElement('div'); + div.id = '__web_test_title'; + document.body.appendChild(div); + } + div.style.cssText = [ + 'position:fixed', 'top:0', 'left:0', 'width:100%', 'height:100%', + `background:${background}`, + 'display:flex', 'align-items:center', 'justify-content:center', + 'z-index:999999', 'pointer-events:none' + ].join(';'); + const esc = s => s.replace(/&/g, '&').replace(/'); + let html = `