- Início
- Contêiner de desenvolvimento
- Tests
- Teste de Gravação de Tela
Teste de Gravação de Tela
Este teste verifica toda a pilha VNC/navegador gravando uma sessão de navegador com interface gráfica em um arquivo MP4. Ele comprova que:
- O Xvfb está em execução e aceitando conexões em
:99 - O Chromium pode ser iniciado em modo com interface gráfica no display virtual
- O ffmpeg pode capturar o display via x11grab
- O MP4 resultante é um vídeo válido e reproduzível
Como Funciona
Seção intitulada “Como Funciona”- Consulta
xdpyinfo -display :99até que o display X esteja pronto (mesmo padrão do entrypoint) - Inicia a gravação do display com ffmpeg a 10 fps
- Inicia o Chromium com interface gráfica via
sync_apido Playwright - Navega para
https://example.com(pausa de 3 s), depoishttps://httpbin.org(pausa de 3 s) - Envia SIGTERM ao ffmpeg para finalização limpa do MP4
- Reporta o caminho de saída e o tamanho do arquivo
Salve o seguinte como vnc-browser-test.py dentro do container, ou copie-o do diretório docs/tests/ deste repositório:
#!/usr/bin/env python3"""VNC/browser stack integration test.
Proves that Xvfb, headed Chromium (via Playwright), and ffmpeg screenrecording all work together inside the devcontainer by recording abrowser navigating to two websites and producing an MP4 video.
Usage: python3 vnc-browser-test.py [output_path]Default output: /tmp/recording.mp4"""
import osimport signalimport subprocessimport sysimport time
DISPLAY = os.environ.get("DISPLAY", ":99")DEFAULT_OUTPUT = "/tmp/recording.mp4"RESOLUTION = "1280x1024"FRAMERATE = "10"XVFB_TIMEOUT = 50 # iterations (~5 s at 0.1 s each)SITES = [ ("https://example.com", 3), ("https://httpbin.org", 3),]
def wait_for_xvfb(): """Poll xdpyinfo until the X display is ready (mirrors entrypoint.sh).""" print(f"Waiting for Xvfb on {DISPLAY} ...") for i in range(XVFB_TIMEOUT): result = subprocess.run( ["xdpyinfo", "-display", DISPLAY], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) if result.returncode == 0: print(f" Display ready after {i * 0.1:.1f}s") return time.sleep(0.1) sys.exit(f"ERROR: Xvfb display {DISPLAY} not ready after {XVFB_TIMEOUT * 0.1:.1f}s")
def start_recording(output_path): """Start ffmpeg x11grab recording and return the process.""" cmd = [ "ffmpeg", "-y", "-f", "x11grab", "-video_size", RESOLUTION, "-framerate", FRAMERATE, "-i", f"{DISPLAY}.0", "-c:v", "libx264", "-preset", "ultrafast", "-pix_fmt", "yuv420p", output_path, ] print(f"Starting ffmpeg recording -> {output_path}") return subprocess.Popen( cmd, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, )
def stop_recording(proc): """Send SIGTERM and wait for ffmpeg to finalize the MP4.""" print("Stopping ffmpeg ...") proc.send_signal(signal.SIGTERM) try: proc.wait(timeout=10) except subprocess.TimeoutExpired: proc.kill() proc.wait()
def browse_sites(): """Launch headed Chromium via Playwright and visit each site.""" from playwright.sync_api import sync_playwright # noqa: PLC0415
with sync_playwright() as pw: browser = pw.chromium.launch( headless=False, args=[ "--no-sandbox", "--disable-gpu", f"--display={DISPLAY}", ], ) page = browser.new_page(viewport={"width": 1280, "height": 1024})
for url, pause in SITES: print(f" Navigating to {url} ...") try: page.goto(url, timeout=15000) except Exception as exc: # noqa: BLE001 print(f" Warning: navigation error ({exc}), continuing") time.sleep(pause)
browser.close()
def main(): output_path = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_OUTPUT
wait_for_xvfb()
ffmpeg = start_recording(output_path) # Give ffmpeg a moment to initialize before browser activity time.sleep(1)
try: browse_sites() finally: stop_recording(ffmpeg)
if os.path.isfile(output_path): size = os.path.getsize(output_path) print(f"\nSUCCESS: {output_path} ({size:,} bytes)") else: sys.exit(f"ERROR: output file not created: {output_path}")
if __name__ == "__main__": main()Executando o Teste
Seção intitulada “Executando o Teste”python3 vnc-browser-test.py /tmp/recording.mp4podman run --rm \ -v $(pwd)/output:/output \ ghcr.io/f5-sales-demo/devcontainer:latest \ python3 vnc-browser-test.py /output/recording.mp4Saída Esperada
Seção intitulada “Saída Esperada”Waiting for Xvfb on :99 ... Display ready after 0.3sStarting ffmpeg recording -> /tmp/recording.mp4 Navigating to https://example.com ... Navigating to https://httpbin.org ...Stopping ffmpeg ...
SUCCESS: /tmp/recording.mp4 (1,234,567 bytes)O MP4 deve mostrar a janela do Chromium renderizando ambos os sites no desktop do fluxbox. Reproduza-o com ffplay, vlc, ou faça o download do container para verificar.
O Que uma Falha Significa
Seção intitulada “O Que uma Falha Significa”| Sintoma | Causa provável |
|---|---|
Xvfb display :99 not ready | Xvfb não iniciado — verifique se o entrypoint executou a pilha VNC |
ffmpeg: x11grab error | Incompatibilidade de display ou ffmpeg sem suporte a x11grab |
Playwright launch error | Chromium não instalado ou faltando --no-sandbox |
| MP4 com 0 bytes | ffmpeg foi encerrado antes de gravar — verifique o tratamento do SIGTERM |