Pruebas de aplicaciones web
Manual de habilidades del agente para pruebas de aplicaciones web basadas en Playwright con ayudas de orquestación de servidores y sugerencias para la resolución de problemas.
Fuente: Contenido adaptado de anthropics/skills (MIT).
Para probar aplicaciones web locales, escriba scripts nativos de Python Playwright.
Secuencias de comandos auxiliares disponibles:
scripts/with_server.py: gestiona el ciclo de vida del servidor (admite varios servidores)
Siempre ejecute los scripts con--helpprimero para ver el uso. NO lea la fuente hasta que intente ejecutar el script primero y descubra que es absolutamente necesaria una solución personalizada. Estos scripts pueden ser muy grandes y, por lo tanto, contaminar su ventana contextual. Existen para ser llamados directamente como scripts de caja negra en lugar de ser ingeridos en su ventana contextual.
Árbol de decisiones: elegir su enfoque
User task -> Is it static HTML?
Yes -> Read HTML file directly to identify selectors
Success -> Write Playwright script using selectors
Fails/Incomplete -> Treat as dynamic (below)
No (dynamic webapp) -> Is the server already running?
No -> Run: python scripts/with_server.py --help
Then use the helper + write simplified Playwright script
Yes -> Reconnaissance-then-action:
1. Navigate and wait for networkidle
2. Take screenshot or inspect DOM
3. Identify selectors from rendered state
4. Execute actions with discovered selectorsEjemplo: usar with_server.py
Para iniciar un servidor, primero ejecute--helpy luego use el asistente:
Servidor único:
python scripts/with_server.py --server "npm run dev" --port 5173 -- python your_automation.pyMúltiples servidores (por ejemplo, backend + frontend):
python scripts/with_server.py \
--server "cd backend && python server.py" --port 3000 \
--server "cd frontend && npm run dev" --port 5173 \
-- python your_automation.pyPara crear un script de automatización, incluya solo la lógica de Playwright (los servidores se administran automáticamente):
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True) # Always launch chromium in headless mode
page = browser.new_page()
page.goto('http://localhost:5173') # Server already running and ready
page.wait_for_load_state('networkidle') # CRITICAL: Wait for JS to execute
# ... your automation logic
browser.close()Patrón de reconocimiento-luego-acción
-
Inspeccionar DOM renderizado:
page.screenshot(path='/tmp/inspect.png', full_page=True) content = page.content() page.locator('button').all() -
Identificar selectores a partir de los resultados de la inspección
-
Ejecutar acciones usando selectores descubiertos
Error común
No inspeccionar el DOM antes de esperar anetworkidleen aplicaciones dinámicas
Espere a que lleguepage.wait_for_load_state('networkidle')antes de la inspección.
Mejores prácticas
- Utilice scripts incluidos como cuadros negros: para realizar una tarea, considere si uno de los scripts disponibles en
scripts/puede ayudar. Estos scripts manejan flujos de trabajo complejos y comunes de manera confiable sin saturar la ventana contextual. Utilice--helppara ver el uso y luego invoque directamente. - Utilice
sync_playwright()para scripts sincrónicos - Cierra siempre el navegador cuando hayas terminado
- Utilice selectores descriptivos:
text=,role=, selectores CSS o ID - Agregue esperas apropiadas:
page.wait_for_selector()opage.wait_for_timeout()
Archivos de referencia
- examples/ - Ejemplos que muestran patrones comunes:
element_discovery.py: descubrir botones, enlaces y entradas en una páginastatic_html_automation.py: uso de URL file:// para HTML localconsole_logging.py: captura de registros de la consola durante la automatización
Archivos de recursos
LICENCIA.txt
Recurso binario
ejemplos/console_logging.py
Descargar ejemplos/console_logging.py
from playwright.sync_api import sync_playwright
# Example: Capturing console logs during browser automation
url = 'http://localhost:5173' # Replace with your URL
console_logs = []
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page(viewport={'width': 1920, 'height': 1080})
# Set up console log capture
def handle_console_message(msg):
console_logs.append(f"[{msg.type}] {msg.text}")
print(f"Console: [{msg.type}] {msg.text}")
page.on("console", handle_console_message)
# Navigate to page
page.goto(url)
page.wait_for_load_state('networkidle')
# Interact with the page (triggers console logs)
page.click('text=Dashboard')
page.wait_for_timeout(1000)
browser.close()
# Save console logs to file
with open('/mnt/user-data/outputs/console.log', 'w') as f:
f.write('\n'.join(console_logs))
print(f"\nCaptured {len(console_logs)} console messages")
print(f"Logs saved to: /mnt/user-data/outputs/console.log")ejemplos/element_discovery.py
Descargar ejemplos/element_discovery.py
from playwright.sync_api import sync_playwright
# Example: Discovering buttons and other elements on a page
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
# Navigate to page and wait for it to fully load
page.goto('http://localhost:5173')
page.wait_for_load_state('networkidle')
# Discover all buttons on the page
buttons = page.locator('button').all()
print(f"Found {len(buttons)} buttons:")
for i, button in enumerate(buttons):
text = button.inner_text() if button.is_visible() else "[hidden]"
print(f" [{i}] {text}")
# Discover links
links = page.locator('a[href]').all()
print(f"\nFound {len(links)} links:")
for link in links[:5]: # Show first 5
text = link.inner_text().strip()
href = link.get_attribute('href')
print(f" - {text} -> {href}")
# Discover input fields
inputs = page.locator('input, textarea, select').all()
print(f"\nFound {len(inputs)} input fields:")
for input_elem in inputs:
name = input_elem.get_attribute('name') or input_elem.get_attribute('id') or "[unnamed]"
input_type = input_elem.get_attribute('type') or 'text'
print(f" - {name} ({input_type})")
# Take screenshot for visual reference
page.screenshot(path='/tmp/page_discovery.png', full_page=True)
print("\nScreenshot saved to /tmp/page_discovery.png")
browser.close()ejemplos/static_html_automation.py
Descargar ejemplos/static_html_automation.py
from playwright.sync_api import sync_playwright
import os
# Example: Automating interaction with static HTML files using file:// URLs
html_file_path = os.path.abspath('path/to/your/file.html')
file_url = f'file://{html_file_path}'
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page(viewport={'width': 1920, 'height': 1080})
# Navigate to local HTML file
page.goto(file_url)
# Take screenshot
page.screenshot(path='/mnt/user-data/outputs/static_page.png', full_page=True)
# Interact with elements
page.click('text=Click Me')
page.fill('#name', 'John Doe')
page.fill('#email', '[email protected]')
# Submit form
page.click('button[type="submit"]')
page.wait_for_timeout(500)
# Take final screenshot
page.screenshot(path='/mnt/user-data/outputs/after_submit.png', full_page=True)
browser.close()
print("Static HTML automation completed!")scripts/with_server.py
Descargar scripts/with_server.py
#!/usr/bin/env python3
"""
Start one or more servers, wait for them to be ready, run a command, then clean up.
Usage:
# Single server
python scripts/with_server.py --server "npm run dev" --port 5173 -- python automation.py
python scripts/with_server.py --server "npm start" --port 3000 -- python test.py
# Multiple servers
python scripts/with_server.py \
--server "cd backend && python server.py" --port 3000 \
--server "cd frontend && npm run dev" --port 5173 \
-- python test.py
"""
import subprocess
import socket
import time
import sys
import argparse
def is_server_ready(port, timeout=30):
"""Wait for server to be ready by polling the port."""
start_time = time.time()
while time.time() - start_time < timeout:
try:
with socket.create_connection(('localhost', port), timeout=1):
return True
except (socket.error, ConnectionRefusedError):
time.sleep(0.5)
return False
def main():
parser = argparse.ArgumentParser(description='Run command with one or more servers')
parser.add_argument('--server', action='append', dest='servers', required=True, help='Server command (can be repeated)')
parser.add_argument('--port', action='append', dest='ports', type=int, required=True, help='Port for each server (must match --server count)')
parser.add_argument('--timeout', type=int, default=30, help='Timeout in seconds per server (default: 30)')
parser.add_argument('command', nargs=argparse.REMAINDER, help='Command to run after server(s) ready')
args = parser.parse_args()
# Remove the '--' separator if present
if args.command and args.command[0] == '--':
args.command = args.command[1:]
if not args.command:
print("Error: No command specified to run")
sys.exit(1)
# Parse server configurations
if len(args.servers) != len(args.ports):
print("Error: Number of --server and --port arguments must match")
sys.exit(1)
servers = []
for cmd, port in zip(args.servers, args.ports):
servers.append({'cmd': cmd, 'port': port})
server_processes = []
try:
# Start all servers
for i, server in enumerate(servers):
print(f"Starting server {i+1}/{len(servers)}: {server['cmd']}")
# Use shell=True to support commands with cd and &&
process = subprocess.Popen(
server['cmd'],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
server_processes.append(process)
# Wait for this server to be ready
print(f"Waiting for server on port {server['port']}...")
if not is_server_ready(server['port'], timeout=args.timeout):
raise RuntimeError(f"Server failed to start on port {server['port']} within {args.timeout}s")
print(f"Server ready on port {server['port']}")
print(f"\nAll {len(servers)} server(s) ready")
# Run the command
print(f"Running: {' '.join(args.command)}\n")
result = subprocess.run(args.command)
sys.exit(result.returncode)
finally:
# Clean up all servers
print(f"\nStopping {len(server_processes)} server(s)...")
for i, process in enumerate(server_processes):
try:
process.terminate()
process.wait(timeout=5)
except subprocess.TimeoutExpired:
process.kill()
process.wait()
print(f"Server {i+1} stopped")
print("All servers stopped")
if __name__ == '__main__':
main()Ver en GitHub
Constructor Mcp
Manual de habilidades del agente para construir servidores Model Context Protocol, definir herramientas y escribir conjuntos de evaluación en los que Claude Skills puede confiar.
Coautoría de documentos
Guíe a los usuarios a través de un flujo de trabajo estructurado para la documentación de coautoría. Úselo cuando el usuario quiera escribir documentación, propuestas, especificaciones técnicas, documentos de decisiones o contenido estructurado similar. Este flujo de trabajo ayuda a los usuarios a transferir contexto de manera eficiente, refinar el contenido mediante iteración y verificar que el documento funcione para los lectores. Se activa cuando el usuario menciona escribir documentos, crear propuestas, redactar especificaciones o tareas de documentación similares.
claudeskills Docs