自动录制精美的网页应用演示视频,用于教程、走查与产品展示
复制安装指令,让 AI 自动完成配置 · 推荐新手
请帮我安装 askskill 上的 "ui-demo" 技能: 1. 下载 https://raw.githubusercontent.com/affaan-m/ECC/main/docs/ja-JP/skills/ui-demo/SKILL.md 2. 保存为 ~/.claude/skills/ui-demo/SKILL.md 3. 装好后重载技能,告诉我可以用了
请为我们的 Web 应用录制一段 60 秒的 UI 演示视频,展示登录、进入仪表盘、创建项目和查看结果的完整流程。要求有可视鼠标光标、自然停顿,并输出专业感强的 WebM 视频。
一段节奏自然、带可视光标的 WebM 产品功能演示视频。
请录制一个面向新用户的网页操作教程,依次演示注册账号、完成初始设置、上传第一个文件并查看处理结果。视频风格简洁清晰,适合作为帮助中心教程。
一段适合帮助中心或教学页面使用的新手引导视频。
请录制一个用于反馈问题的 UI 走查视频,展示进入设置页、修改筛选条件、点击保存后界面异常的全过程。要求步骤清楚,便于开发和测试团队复现问题。
一段清晰展示复现步骤的界面录屏视频,便于排查问题。
Playwrightの動画録画機能を使用して、注入されたカーソルオーバーレイ、自然なリズム、ナラティブフローを備えた美しいWebアプリのデモ動画を録画する。
すべてのデモは 探索 -> リハーサル -> 録画 の3つのフェーズを経る。録画フェーズに直接ジャンプしない。
スクリプトを書く前に、ターゲットページを探索して実際の内容を把握する。
見たことのない内容のスクリプトは書けない。フィールドが <textarea> ではなく <input> の場合、ドロップダウンが <select> ではなくカスタムコンポーネントの場合、コメントボックスが @mentions や #tags をサポートしている場合があある。仮定は録画を静かに壊す。
フローの各ページに移動し、インタラクティブな要素をダンプする:
// Run this for each page in the flow BEFORE writing the demo script
const fields = await page.evaluate(() => {
const els = [];
document.querySelectorAll('input, select, textarea, button, [contenteditable]').forEach(el => {
if (el.offsetParent !== null) {
els.push({
tag: el.tagName,
type: el.type || '',
name: el.name || '',
placeholder: el.placeholder || '',
text: el.textContent?.trim().substring(0, 40) || '',
contentEditable: el.contentEditable === 'true',
role: el.getAttribute('role') || '',
});
}
});
return els;
});
console.log(JSON.stringify(fields, null, 2));
<select>、<input>、カスタムドロップダウン、コンボボックスのどれか?value="0" または value="" が含まれることがあり、非空に見える。Array.from(el.options).map(o => ({ value: o.value, text: o.text })) を使用する。テキストに「選択」が含まれるオプションや値が "0" のオプションをスキップする。@mentions、#tags、Markdown、絵文字をサポートしているか?プレースホルダーテキストを確認する。required、* を確認し、空のフォームを送信してバリデーションエラーを確認する。"Submit"、"Submit Request"、"Send" など)。input[type="number"] をその列ヘッダーにマッピングする。すべての数値入力が同じ意味を持つと仮定しない。スクリプトに正しいセレクターを書くために使用する、ページごとのフィールドマッピング。例:
/purchase-requests/new:
- 予算コード: <select>(ページの最初のドロップダウン、4オプション)
- 希望納期: <input type="date">
- 背景説明: <textarea>(inputではない)
- BOMテーブル: インライン編集可能なセル、span.cursor-pointer -> inputパターン
- 送信: <button> テキスト="送信"
/purchase-requests/N(詳細):
- コメント: <input placeholder="メッセージを入力...">、@ユーザーと#PRタグに対応
- 送信: <button> テキスト="送信"(入力前は無効)
録画せずにすべてのステップを実行する。各セレクターが解決されることを確認する。
セレクターの失敗は、デモ録画が壊れる最大の原因。リハーサルは録画を無駄にする前に問題を発見する。
ensureVisible を使用する——ログを記録して大きくエラーを報告するラッパー:
async function ensureVisible(page, locator, label) {
const el = typeof locator === 'string' ? page.locator(locator).first() : locator;
const visible = await el.isVisible().catch(() => false);
if (!visible) {
const msg = `REHEARSAL FAIL: "${label}" not found - selector: ${typeof locator === 'string' ? locator : '(locator object)'}`;
console.error(msg);
const found = await page.evaluate(() => {
return Array.from(document.querySelectorAll('button, input, select, textarea, a'))
.filter(el => el.offsetParent !== null)
.map(el => `${el.tagName}[${el.type || ''}] "${el.textContent?.trim().substring(0, 30)}"`)
.join('\n ');
});
console.error(' Visible elements:\n ' + found);
return false;
}
console.log(`REHEARSAL OK: "${label}"`);
return true;
}
const steps = [
{ label: 'Login email field', selector: '#email' },
{ label: 'Login submit', selector: 'button[type="submit"]' },
{ label: 'New Request button', selector: 'button:has-text("New Request")' },
{ label: 'Budget Code select', selector: 'select' },
{ label: 'Delivery date', selector: 'input[type="date"]:visible' },
{ label: 'Description field', selector: 'textarea:visible' },
{ label: 'Add Item button', selector: 'button:has-text("Add Item")' },
{ label: 'Submit button', selector: 'button:has-text("Submit")' },
];
let allOk = true;
for (const step of steps) {
…
通过双评审智能体对结果进行对抗式校验,提升输出发布前的可靠性
用于操作并测试本地 Web 应用,辅助排查前端问题、查看日志与截图取证。