Vídeos de demonstração com bueno-demo
bueno-demo grava uma caminhada scriptada por uma página web e a renderiza em um clipe no estilo Screen Studio. Existem duas etapas: captura dirige uma janela real do Chromium e a grava, e renderização adiciona câmera, cursor e títulos.
Configuração, uma vez por máquina
npm i -D bueno-demo # ou execute tudo com npx bueno-demo
npx playwright install chromium
brew install ffmpeg # necessário; adicione imagemagick para posters WebP
O ciclo
- Escreva um script, um arquivo JSON (veja abaixo). Mantenha uma ideia por clipe, 10 a 15 segundos.
- Capture:
npx bueno-demo capture demos/<nome>.json out/<nome> - Corte opcional de um carregamento lento:
npx bueno-demo cut out/<nome> <de-s> <ate-s> - Renderize:
npx bueno-demo render out/<nome> out/<nome>/<nome> --gif - Observe antes de usar. Crie uma folha de contato e verifique cada quadro:
ffmpeg -i out/<nome>/<nome>.mp4 -vf "fps=1,scale=640:-1,tile=3x4" -frames:v 1 sheet.pngSe um bug ou dado privado aparecer na câmera, corrija o script ou corte-o e re-renderize.
Scripts
{
"url": "http://localhost:3000/configuracoes",
"viewport": [1440, 900],
"storage": "auth.json",
"keep": "document.querySelectorAll('[data-user-email]').forEach(e => e.textContent = '[email protected]')",
"steps": [
{ "scroll": "[data-testid=faturamento]" },
{ "click": "[data-testid=alternar-plano]", "after": 1200 },
{ "type": "[data-testid=nome-equipe]", "text": "Northwind", "clear": true },
{ "hover": "[data-testid=salvar]", "zoom": true },
{ "click": "[data-testid=salvar]", "zoom": false },
{ "wait": 800 }
]
}
Passos, cada um opcionalmente com after (ms para pausar depois):
click: deslize até o elemento e clique.zoom: falsepula o zoom da câmera; use-o em um clique que navega.type: clique, então digitetext(delayms por tecla, padrão 55;clear: truesubstitui o valor).fill: clique, então definatextde uma vez, para entradas que a digitação não consegue controlar (seletores de data).hover: deslize até lá.zoom: trueaponta a câmera também.upload: deslize até uma zona de soltar e anexefile(relativo ao script) ainput.press: uma tecla, como"Escape".scroll: role suavemente o elemento até a vista.wait: pausa, em ms.eval: execute JS na página, na câmera.
Opções:
- Fazer login:
storageaponta para um arquivo de estado de armazenamento do Playwright (salve um comnpx playwright codegen --save-storage=auth.json <url>). Ou"cookiesFrom": "agent-browser"pega emprestado uma sessão de agente-navegador logada. Cookies nunca são impressos. - Privacidade:
keepé JS executado antes da gravação e a cada 250ms durante ela, para substituir nomes reais e emails por substitutos, de modo que uma re-renderização nunca os traga de volta.hideadiciona seletores CSS para ocultar (sobreposições de desenvolvimento do Next.js e Vercel já estão ocultas;"hide": falseas mostra). - Fora da câmera:
setupé JS executado uma vez antes da gravação (fechar um banner, por exemplo). - Sensação:
travelMs(tempo de viagem do cursor, padrão 700),settle(espera após carregamento, padrão 1500),tail(segurar no final, padrão 1200),cursorStart([x, y]),reducedMotion: true. - Carregamento:
waitUntil(padrãonetworkidle). Uma página que transmite vídeo ou faz polling nunca fica ociosa, então a captura expira; defina"load"e deixesettlecobrir o resto. - Outro servidor:
--base http://localhost:3001na captura grava o mesmo caminho em outro lugar.
Seletores: prefira data-testid ou estrutura (#title, input[name=amount]) em vez de texto visível, para que mudanças de texto não quebrem o script.
Flags de renderização
--zoom 1.6quão longe um clique amplia (1.3 quando duas coisas importam ao mesmo tempo).--speed 0.9reproduz 10% mais devagar;--speed 2.5para uma montagem rápida.--end 9.8corta naquele segundo;--hold 1.2congela o último quadro.--matte '#fdfaf1'emoldura a página como uma janela arredondada nessa cor (padrão é borda a borda).--title 'Movendo um evento' --kicker 'Eventos'adiciona um título de abertura;--end-capadiciona um cartão de fechamento.--brand brand.jsondefine a aparência do título e do cartão:ink,paper,accent,displayFont/monoFont({ "family", "file", "weight" }),logo,footer,kicker. Caminhos são relativos ao arquivo de marca.--fitrenderiza na forma própria da página (retrato para um viewport de celular).--giftambém escreve um GIF de 960px, 15fps.
Regras
- Nunca grave dados reais de clientes. Use contas de teste e um hook
keeppara qualquer coisa pessoal; verifique a folha de contato antes de compartilhar. - Curto e com propósito único. Um recurdo por clipe; corte esperas com
cut. - Hospede vídeo fora do repositório. Comprometa o script (e um poster se sua documentação precisar de um); coloque MP4s e GIFs em seu armazenamento ou CDN.