|
| 1 | +""" |
| 2 | +Example: Semantic wait_for using query DSL |
| 3 | +Demonstrates waiting for elements using semantic selectors |
| 4 | +""" |
| 5 | + |
| 6 | +from sentience import SentienceBrowser, wait_for, click |
| 7 | +import os |
| 8 | + |
| 9 | + |
| 10 | +def main(): |
| 11 | + # Get API key from environment variable (optional - uses free tier if not set) |
| 12 | + api_key = os.environ.get("SENTIENCE_API_KEY") |
| 13 | + |
| 14 | + with SentienceBrowser(api_key=api_key, headless=False) as browser: |
| 15 | + # Navigate to example.com |
| 16 | + browser.page.goto("https://example.com", wait_until="domcontentloaded") |
| 17 | + |
| 18 | + print("=== Semantic wait_for Demo ===\n") |
| 19 | + |
| 20 | + # Example 1: Wait for element by role |
| 21 | + print("1. Waiting for link element (role=link)") |
| 22 | + wait_result = wait_for(browser, "role=link", timeout=5.0) |
| 23 | + if wait_result.found: |
| 24 | + print(f" ✅ Found after {wait_result.duration_ms}ms") |
| 25 | + print(f" Element: '{wait_result.element.text}' (id: {wait_result.element.id})") |
| 26 | + else: |
| 27 | + print(f" ❌ Not found (timeout: {wait_result.timeout})") |
| 28 | + print() |
| 29 | + |
| 30 | + # Example 2: Wait for element by role and text |
| 31 | + print("2. Waiting for link with specific text") |
| 32 | + wait_result = wait_for(browser, "role=link text~'Example'", timeout=5.0) |
| 33 | + if wait_result.found: |
| 34 | + print(f" ✅ Found after {wait_result.duration_ms}ms") |
| 35 | + print(f" Element text: '{wait_result.element.text}'") |
| 36 | + else: |
| 37 | + print(" ❌ Not found") |
| 38 | + print() |
| 39 | + |
| 40 | + # Example 3: Wait for clickable element |
| 41 | + print("3. Waiting for clickable element") |
| 42 | + wait_result = wait_for(browser, "clickable=true", timeout=5.0) |
| 43 | + if wait_result.found: |
| 44 | + print(f" ✅ Found clickable element after {wait_result.duration_ms}ms") |
| 45 | + print(f" Role: {wait_result.element.role}") |
| 46 | + print(f" Text: '{wait_result.element.text}'") |
| 47 | + print(f" Is clickable: {wait_result.element.visual_cues.is_clickable}") |
| 48 | + else: |
| 49 | + print(" ❌ Not found") |
| 50 | + print() |
| 51 | + |
| 52 | + # Example 4: Wait for element with importance threshold |
| 53 | + print("4. Waiting for important element (importance > 100)") |
| 54 | + wait_result = wait_for(browser, "importance>100", timeout=5.0) |
| 55 | + if wait_result.found: |
| 56 | + print(f" ✅ Found important element after {wait_result.duration_ms}ms") |
| 57 | + print(f" Importance: {wait_result.element.importance}") |
| 58 | + print(f" Role: {wait_result.element.role}") |
| 59 | + else: |
| 60 | + print(" ❌ Not found") |
| 61 | + print() |
| 62 | + |
| 63 | + # Example 5: Wait and then click |
| 64 | + print("5. Wait for element, then click it") |
| 65 | + wait_result = wait_for(browser, "role=link", timeout=5.0) |
| 66 | + if wait_result.found: |
| 67 | + print(" ✅ Found element, clicking...") |
| 68 | + click_result = click(browser, wait_result.element.id) |
| 69 | + print(f" Click result: success={click_result.success}, outcome={click_result.outcome}") |
| 70 | + if click_result.url_changed: |
| 71 | + print(f" ✅ Navigation occurred: {browser.page.url}") |
| 72 | + else: |
| 73 | + print(" ❌ Element not found, cannot click") |
| 74 | + print() |
| 75 | + |
| 76 | + # Example 6: Using local extension (fast polling) |
| 77 | + print("6. Using local extension with auto-optimized interval") |
| 78 | + print(" When use_api=False, interval auto-adjusts to 0.25s (fast)") |
| 79 | + wait_result = wait_for(browser, "role=link", timeout=5.0, use_api=False) |
| 80 | + if wait_result.found: |
| 81 | + print(f" ✅ Found after {wait_result.duration_ms}ms") |
| 82 | + print(" (Used local extension, polled every 0.25 seconds)") |
| 83 | + print() |
| 84 | + |
| 85 | + # Example 7: Using remote API (slower polling) |
| 86 | + print("7. Using remote API with auto-optimized interval") |
| 87 | + print(" When use_api=True, interval auto-adjusts to 1.5s (network-friendly)") |
| 88 | + if api_key: |
| 89 | + wait_result = wait_for(browser, "role=link", timeout=5.0, use_api=True) |
| 90 | + if wait_result.found: |
| 91 | + print(f" ✅ Found after {wait_result.duration_ms}ms") |
| 92 | + print(" (Used remote API, polled every 1.5 seconds)") |
| 93 | + else: |
| 94 | + print(" ⚠️ Skipped (no API key set)") |
| 95 | + print() |
| 96 | + |
| 97 | + # Example 8: Custom interval override |
| 98 | + print("8. Custom interval override (manual control)") |
| 99 | + print(" You can still specify custom interval if needed") |
| 100 | + wait_result = wait_for(browser, "role=link", timeout=5.0, interval=0.5, use_api=False) |
| 101 | + if wait_result.found: |
| 102 | + print(f" ✅ Found after {wait_result.duration_ms}ms") |
| 103 | + print(" (Custom interval: 0.5 seconds)") |
| 104 | + print() |
| 105 | + |
| 106 | + print("✅ Semantic wait_for demo complete!") |
| 107 | + print("\nNote: wait_for uses the semantic query DSL to find elements.") |
| 108 | + print("This is more robust than CSS selectors because it understands") |
| 109 | + print("the semantic meaning of elements (role, text, clickability, etc.).") |
| 110 | + |
| 111 | + |
| 112 | +if __name__ == "__main__": |
| 113 | + main() |
| 114 | + |
0 commit comments