Skip to content

Basic Example

This page provides a complete, working example that demonstrates all the essential features of the Clio SDK.

complete_example.py
import asyncio
import os
import logging
from pathlib import Path
from dotenv import load_dotenv
from clio import ClioMonitor
from clio.exceptions import ClioError, ClioAuthError, ClioUploadError
from playwright.async_api import async_playwright
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
async def example_automation():
"""Complete example showing Clio SDK integration with error handling"""
# Load environment variables
load_dotenv()
# Get API key
api_key = os.getenv("CLIO_API_KEY")
if not api_key:
logger.error("❌ CLIO_API_KEY environment variable not set")
logger.info("💡 Get your API key from https://cliomonitoring.com and set it:")
logger.info(" export CLIO_API_KEY='your_api_key_here'")
return False
try:
# Initialize monitor with error handling enabled for development
monitor = ClioMonitor(
api_key=api_key,
base_url=os.getenv("CLIO_BASE_URL", "https://api.cliomonitoring.com"),
retry_attempts=3,
raise_on_error=True, # Get detailed errors during development
timeout=60,
verify_ssl=True
)
logger.info("✅ ClioMonitor initialized successfully")
except ValueError as e:
logger.error(f"❌ Configuration error: {e}")
return False
# Ensure videos directory exists
videos_dir = Path("./videos")
videos_dir.mkdir(exist_ok=True)
try:
async with async_playwright() as p:
# Launch browser
browser = await p.chromium.launch(
headless=True, # Set to False to see the browser
args=["--no-sandbox"] # May be needed in some environments
)
logger.info("🌐 Browser launched")
# Create context with video recording
context = await browser.new_context(
record_video_dir=str(videos_dir),
record_video_size={"width": 1280, "height": 720},
viewport={"width": 1280, "height": 720}
)
logger.info("📹 Context created with video recording enabled")
try:
# Start monitoring - this is where the magic happens
await monitor.start_run(
context=context,
automation_name="Complete Example - Website Navigation",
success_criteria="Successfully navigate to example.com, verify title, and interact with page elements",
playwright_instructions="""
1. Navigate to https://example.com
2. Wait for page to fully load
3. Verify the page title contains 'Example Domain'
4. Take a screenshot for documentation
5. Interact with page elements (hover, click)
6. Scroll to demonstrate page interaction
"""
)
logger.info("🎬 Monitoring started successfully")
# Create a new page
page = await context.new_page()
logger.info("📄 New page created")
# Navigate to the target website
logger.info("🌐 Navigating to example.com...")
await page.goto("https://example.com", wait_until="networkidle")
# Verify we're on the right page
title = await page.title()
logger.info(f"📄 Page title: '{title}'")
if "Example Domain" not in title:
logger.warning(f"⚠️ Unexpected page title: {title}")
else:
logger.info("✅ Page title verification passed")
# Demonstrate mouse interactions for better video recording
logger.info("🖱️ Demonstrating mouse interactions...")
# Move mouse to different areas
await page.mouse.move(200, 200)
await page.wait_for_timeout(500)
await page.mouse.move(600, 300)
await page.wait_for_timeout(500)
# Find and hover over the main heading
heading = page.locator("h1")
if await heading.is_visible():
logger.info("🎯 Hovering over main heading...")
await heading.hover()
await page.wait_for_timeout(1000)
# Take a screenshot
screenshot_path = "example_screenshot.png"
await page.screenshot(path=screenshot_path)
logger.info(f"📸 Screenshot saved to {screenshot_path}")
# Look for the "More information..." link and interact with it
more_info_link = page.locator("text=More information")
if await more_info_link.is_visible(timeout=5000):
logger.info("🔗 Found 'More information...' link")
# Hover before clicking for better visual feedback
await more_info_link.hover()
await page.wait_for_timeout(1000)
# Click the link
await more_info_link.click()
await page.wait_for_load_state("networkidle")
logger.info("✅ Successfully clicked 'More information...' link")
# Demonstrate scrolling on the new page
logger.info("📜 Demonstrating page scrolling...")
await page.evaluate("window.scrollTo(0, document.body.scrollHeight / 2)")
await page.wait_for_timeout(1000)
await page.evaluate("window.scrollTo(0, 0)")
await page.wait_for_timeout(1000)
else:
logger.info("ℹ️ 'More information...' link not found, skipping click interaction")
# Final mouse position for clean video ending
await page.mouse.move(640, 360) # Center of screen
await page.wait_for_timeout(500)
logger.info("✅ All automation steps completed successfully!")
except Exception as automation_error:
logger.error(f"❌ Automation error: {automation_error}")
# Take screenshot of error state
try:
page = context.pages[0] if context.pages else await context.new_page()
await page.screenshot(path="error_screenshot.png")
logger.info("📸 Error screenshot saved")
except:
pass
raise
finally:
# Close context - this triggers automatic upload
logger.info("📤 Closing context and uploading files...")
await context.close() # Upload happens automatically here
await browser.close()
logger.info("🎉 Browser closed, upload process initiated")
except ClioAuthError as e:
logger.error(f"❌ Authentication failed: {e}")
logger.info("💡 Check your API key and try again")
return False
except ClioUploadError as e:
logger.error(f"❌ Upload failed: {e}")
logger.info("💡 Check your network connection and retry")
return False
except ClioError as e:
logger.error(f"❌ Clio SDK error: {e}")
logger.info("💡 Check the error message above for details")
return False
except Exception as e:
logger.error(f"💥 Unexpected error: {e}", exc_info=True)
return False
logger.info("🎉 Example completed successfully!")
logger.info("📊 Check your Clio dashboard to view the recorded automation")
return True
async def main():
"""Main entry point"""
print("🚀 Starting Clio SDK Complete Example")
print("=" * 60)
success = await example_automation()
print("=" * 60)
if success:
print("✅ Example completed successfully!")
print("🔗 Visit your Clio dashboard to view the results")
else:
print("❌ Example failed - check the logs above")
return 1
return 0
if __name__ == "__main__":
exit_code = asyncio.run(main())
exit(exit_code)

Create a .env file in the same directory:

.env
# Your Clio API key (get this from https://cliomonitoring.com)
CLIO_API_KEY=clio_your_actual_api_key_here
# Optional: Custom server URL (defaults to https://api.cliomonitoring.com)
# CLIO_BASE_URL=http://localhost:8000
# Optional: Enable debug logging
# CLIO_DEBUG=true

Create a requirements.txt file:

requirements.txt
clio>=0.1.0
playwright>=1.40.0
python-dotenv>=1.0.0
  1. Install dependencies:

    Terminal window
    pip install -r requirements.txt
    playwright install
  2. Set up your API key:

    Terminal window
    export CLIO_API_KEY="your_actual_api_key"
    # Or create a .env file as shown above
  3. Run the example:

    Terminal window
    python complete_example.py

When you run the example, you should see output like this:

🚀 Starting Clio SDK Complete Example
============================================================
2024-01-01 10:00:00 - __main__ - INFO - ✅ ClioMonitor initialized successfully
2024-01-01 10:00:01 - __main__ - INFO - 🌐 Browser launched
2024-01-01 10:00:02 - __main__ - INFO - 📹 Context created with video recording enabled
2024-01-01 10:00:03 - __main__ - INFO - 🎬 Monitoring started successfully
2024-01-01 10:00:04 - __main__ - INFO - 📄 New page created
2024-01-01 10:00:05 - __main__ - INFO - 🌐 Navigating to example.com...
2024-01-01 10:00:06 - __main__ - INFO - 📄 Page title: 'Example Domain'
2024-01-01 10:00:07 - __main__ - INFO - ✅ Page title verification passed
2024-01-01 10:00:08 - __main__ - INFO - 🖱️ Demonstrating mouse interactions...
2024-01-01 10:00:09 - __main__ - INFO - 🎯 Hovering over main heading...
2024-01-01 10:00:10 - __main__ - INFO - 📸 Screenshot saved to example_screenshot.png
2024-01-01 10:00:11 - __main__ - INFO - 🔗 Found 'More information...' link
2024-01-01 10:00:12 - __main__ - INFO - ✅ Successfully clicked 'More information...' link
2024-01-01 10:00:13 - __main__ - INFO - 📜 Demonstrating page scrolling...
2024-01-01 10:00:14 - __main__ - INFO - ✅ All automation steps completed successfully!
2024-01-01 10:00:15 - __main__ - INFO - 📤 Closing context and uploading files...
2024-01-01 10:00:16 - clio.client - INFO - 🚀 close_with_upload called for context
2024-01-01 10:00:17 - clio.client - INFO - 📊 Stopping trace and saving trace file...
2024-01-01 10:00:18 - clio.uploader - INFO - ✅ Successfully uploaded video.webm
2024-01-01 10:00:19 - clio.uploader - INFO - ✅ Successfully uploaded trace.zip
2024-01-01 10:00:20 - __main__ - INFO - 🎉 Browser closed, upload process initiated
2024-01-01 10:00:21 - __main__ - INFO - 🎉 Example completed successfully!
============================================================
✅ Example completed successfully!
🔗 Visit your Clio dashboard to view the results
  • Proper initialization with error handling
  • Environment variable configuration
  • Comprehensive logging
  • Video recording setup
  • Proper page navigation and waiting
  • Element interaction patterns
  • Screenshot capture
  • Specific exception types
  • Graceful degradation
  • Helpful error messages
  • Error state documentation
  • Mouse movements for visibility
  • Hover states before clicks
  • Page scrolling demonstrations
  • Strategic delays for clear video
  • Environment-based configuration
  • Proper resource cleanup
  • Comprehensive logging
  • Exit code handling
# Instead of example.com, test your own application
await page.goto("https://your-app.com/login")
# Update the success criteria accordingly
automation_name="Login Flow Test"
success_criteria="User successfully logs in and reaches dashboard"
# Form filling
await page.fill("#username", "testuser")
await page.fill("#password", "testpass")
await page.click("#login-button")
# File uploads
await page.set_input_files("#file-upload", "test-file.txt")
# Multiple pages
await page.click("text=Open New Tab")
new_page = await context.wait_for_event("page")
await new_page.goto("https://another-site.com")
# Different config for CI/CD
if os.getenv("CI"):
monitor = ClioMonitor(
api_key=api_key,
retry_attempts=5, # More retries in CI
timeout=120, # Longer timeout
raise_on_error=False # Don't fail builds
)
  1. Missing API Key: Set CLIO_API_KEY environment variable
  2. Browser Issues: Run playwright install to download browsers
  3. Permission Errors: Ensure videos directory is writable
  4. Network Timeouts: Increase timeout value or check network connectivity

Enable detailed logging:

import logging
logging.basicConfig(level=logging.DEBUG)
# Or set environment variable
os.environ["CLIO_DEBUG"] = "true"
# Check if video was created
videos_dir = Path("./videos")
video_files = list(videos_dir.glob("*.webm"))
print(f"Video files found: {video_files}")

This complete example provides a solid foundation for integrating Clio SDK into your own automation workflows!