Skip to content

A V language implementation of the W3C WebDriver protocol for browser automation - Fast, safe, and Selenium-compatible

License

Notifications You must be signed in to change notification settings

quaesitor-scientiam/v-webdriver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

43 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

V WebDriver - W3C WebDriver Protocol Implementation

A V language implementation of the W3C WebDriver protocol for browser automation.

Version 3.0.0 | πŸŽ‰ 100% Feature Parity with Selenium πŸŽ‰ | Production Ready

πŸš€ Features

βœ… Fully Implemented (100% Coverage) πŸŽ‰

Core Features:

  • Session Management - Create, manage, and quit browser sessions
  • Navigation - Navigate, back, forward, refresh
  • Element Location - Find elements by CSS selector, XPath, ID, class name, tag name, link text
  • Element Interaction - Click, send keys, clear, submit forms βœ… 100% Complete
  • JavaScript Execution - Execute synchronous and asynchronous scripts βœ… 100% Complete
  • Cookies - Get, add, delete, clear all cookies
  • Screenshots - Capture page and element screenshots (base64)
  • Frame Switching - Switch between frames, iframes, and parent frame
  • Actions API - Complete keyboard, mouse, wheel, drag-and-drop βœ… 100% Complete

Phase 1 & 5 - Element Properties ✨ βœ… 100% Complete:

  • Get element text, attributes, and DOM properties
  • Check visibility (is_displayed), enabled state (is_enabled), selection state (is_selected)
  • Get tag names, clear input fields
  • Get computed CSS property values (get_css_value) - colors, fonts, dimensions, spacing

Phase 2 - Alert Handling ✨:

  • Accept and dismiss alert/confirm/prompt dialogs
  • Read alert text messages
  • Send text input to prompt dialogs

Phase 3 - Page Information ✨:

  • Get page title and current URL
  • Get complete HTML page source
  • Navigation verification

Phase 4 - Window & Waits ✨:

  • Switch between windows and tabs
  • Create new windows/tabs
  • Maximize, minimize, and fullscreen windows
  • Implicit waits for auto-waiting elements
  • Configurable page load and script timeouts

Phase 6 - Expected Conditions ✨:

  • Wait for elements to be clickable, visible, or present
  • Wait for specific text in elements
  • Get current timeout configuration
  • Robust wait patterns with 500ms polling

Phase 7 - Advanced Actions ✨:

  • Context click (right-click) on elements
  • Click and hold + release for drag operations
  • Drag and drop to element or by pixel offset
  • Get element position and size (rect)
  • Submit forms easily

Phase 8 - Async JS & Shadow DOM ✨ βœ… 100% Complete:

  • Execute asynchronous JavaScript with callbacks
  • Support for setTimeout, Promises, async/await patterns
  • Access Shadow DOM roots
  • Find elements within Shadow DOM
  • Test modern web components (Lit, Stencil, etc.)

Edge-Specific:

  • Network condition simulation
  • Device emulation
  • Browser version detection

πŸ“¦ Installation

Prerequisites

  1. V compiler installed
  2. A supported browser (Edge, Chrome, Firefox, or Safari)
  3. Matching WebDriver:

Quick Setup

# Clone the repository
git clone https://github.com/quaesitor-scientiam/v-webdriver.git
cd v-webdriver

# Start your browser's WebDriver
# Edge/Chrome:
.\msedgedriver.exe --port=9515  # or chromedriver.exe

# Firefox:
.\geckodriver.exe --port=4444

# Safari (macOS):
safaridriver --enable
safaridriver -p 4445

Need help? See TEST_ENVIRONMENT_SETUP.md for detailed setup instructions.

🎯 Quick Start

Microsoft Edge

import webdriver

fn main() {
    caps := webdriver.Capabilities{
        browser_name: 'msedge'
        edge_options: webdriver.EdgeOptions{
            args: ['--headless=new']
            binary: r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'
        }
    }

    wd := webdriver.new_edge_driver('http://127.0.0.1:9515', caps)!
    defer { wd.quit() or {} }

    wd.get('https://example.com')!
    title := wd.get_title()!
    println('Page title: ${title}')
}

Google Chrome

import webdriver

fn main() {
    caps := webdriver.Capabilities{
        browser_name: 'chrome'
        chrome_options: webdriver.ChromeOptions{
            args: ['--headless=new', '--disable-gpu']
            binary: r'C:\Program Files\Google\Chrome\Application\chrome.exe'
        }
    }

    wd := webdriver.new_chrome_driver('http://127.0.0.1:9515', caps)!
    defer { wd.quit() or {} }

    wd.get('https://example.com')!
    println('Chrome automation working!')
}

Mozilla Firefox

import webdriver

fn main() {
    caps := webdriver.Capabilities{
        browser_name: 'firefox'
        firefox_options: webdriver.FirefoxOptions{
            args: ['-headless']
            binary: r'C:\Program Files\Mozilla Firefox\firefox.exe'
        }
    }

    wd := webdriver.new_firefox_driver('http://127.0.0.1:4444', caps)!
    defer { wd.quit() or {} }

    wd.get('https://example.com')!
    println('Firefox automation working!')
}

Safari (macOS)

import webdriver

fn main() {
    caps := webdriver.Capabilities{
        browser_name: 'safari'
        safari_options: webdriver.SafariOptions{
            automatic_inspection: false
            automatic_profiling: false
        }
    }

    wd := webdriver.new_safari_driver('http://127.0.0.1:4445', caps)!
    defer { wd.quit() or {} }

    wd.get('https://example.com')!
    println('Safari automation working!')
}

πŸ“– Comprehensive Examples

Complete Automation Example (All Phases)

import webdriver

fn main() {
    caps := webdriver.Capabilities{
        browser_name: 'msedge'
        edge_options: webdriver.EdgeOptions{
            args: ['--headless=new']
        }
    }

    wd := webdriver.new_edge_driver('http://127.0.0.1:9515', caps)!
    defer { wd.quit() or {} }

    // Set timeouts (Phase 4)
    wd.set_implicit_wait(10000)!
    wd.set_page_load_timeout(30000)!

    // Navigate and get page info (Phase 3)
    wd.get('https://example.com')!
    title := wd.get_title()!
    url := wd.get_current_url()!
    println('Page: ${title} at ${url}')

    // Element properties (Phase 1)
    heading := wd.find_element('css selector', 'h1')!
    text := wd.get_text(heading)!
    tag := wd.get_tag_name(heading)!
    visible := wd.is_displayed(heading)!
    println('Found <${tag}>: "${text}" (visible: ${visible})')

    // Handle alerts (Phase 2)
    wd.execute_script('alert("Test")', [])!
    alert_text := wd.get_alert_text()!
    println('Alert says: ${alert_text}')
    wd.accept_alert()!

    // Multi-window (Phase 4)
    new_tab := wd.new_window('tab')!
    wd.switch_to_window(new_tab.handle)!
    wd.get('https://www.iana.org')!
    wd.maximize_window()!
}

Form Automation

import webdriver

fn login_example() ! {
    caps := webdriver.Capabilities{
        browser_name: 'msedge'
    }

    wd := webdriver.new_edge_driver('http://127.0.0.1:9515', caps)!
    defer { wd.quit() or {} }

    wd.get('https://example.com/login')!

    // Find form elements
    username := wd.find_element('css selector', '#username')!
    password := wd.find_element('css selector', '#password')!
    submit := wd.find_element('css selector', 'button[type="submit"]')!

    // Fill the form
    wd.send_keys(username, 'testuser')!
    wd.send_keys(password, 'password123')!
    wd.click(submit)!
}

Working with Cookies

import webdriver

fn cookie_example() ! {
    wd := webdriver.new_edge_driver('http://127.0.0.1:9515', caps)!
    defer { wd.quit() or {} }

    wd.get('https://example.com')!

    // Add a cookie
    cookie := webdriver.Cookie{
        name: 'session_id'
        value: 'abc123'
        path: '/'
        domain: 'example.com'
    }
    wd.add_cookie(cookie)!

    // Get all cookies
    cookies := wd.get_cookies()!
    println('Cookies: ${cookies.len}')

    // Delete a cookie
    wd.delete_cookie('session_id')!
}

Using Actions API

import webdriver

fn actions_example() ! {
    wd := webdriver.new_edge_driver('http://127.0.0.1:9515', caps)!
    defer { wd.quit() or {} }

    wd.get('https://example.com')!

    // Type text using actions
    wd.type_text('Hello World')!

    // Scroll down
    wd.scroll_by(0, 500)!

    // Click at coordinates
    wd.click_at(100, 200)!
}

Element Properties (Phase 1)

import webdriver

fn element_properties_example() ! {
    wd := webdriver.new_edge_driver('http://127.0.0.1:9515', caps)!
    defer { wd.quit() or {} }

    wd.get('https://example.com')!

    link := wd.find_element('css selector', 'a')!

    // Get element properties
    text := wd.get_text(link)!                    // Visible text
    href := wd.get_attribute(link, 'href')!       // HTML attribute
    tag := wd.get_tag_name(link)!                 // Tag name

    // Check element state
    visible := wd.is_displayed(link)!
    enabled := wd.is_enabled(link)!

    println('Link: ${text} -> ${href}')
    println('Visible: ${visible}, Enabled: ${enabled}')
}

Alert Handling (Phase 2)

import webdriver

fn alert_handling_example() ! {
    wd := webdriver.new_edge_driver('http://127.0.0.1:9515', caps)!
    defer { wd.quit() or {} }

    wd.get('https://example.com')!

    // Handle alert
    wd.execute_script('alert("Hello!")', [])!
    text := wd.get_alert_text()!
    println('Alert: ${text}')
    wd.accept_alert()!

    // Handle prompt
    wd.execute_script('window.name = prompt("Your name?")', [])!
    wd.send_alert_text('Claude')!
    wd.accept_alert()!
}

Page Information (Phase 3)

import webdriver

fn page_info_example() ! {
    wd := webdriver.new_edge_driver('http://127.0.0.1:9515', caps)!
    defer { wd.quit() or {} }

    wd.get('https://example.com')!

    // Get page metadata
    title := wd.get_title()!
    url := wd.get_current_url()!
    source := wd.get_page_source()!

    println('Title: ${title}')
    println('URL: ${url}')
    println('HTML length: ${source.len} bytes')

    // Verify navigation
    assert title == 'Example Domain'
    assert url == 'https://example.com/'
}

Multi-Window Management (Phase 4)

import webdriver

fn multi_window_example() ! {
    wd := webdriver.new_edge_driver('http://127.0.0.1:9515', caps)!
    defer { wd.quit() or {} }

    wd.get('https://example.com')!

    // Get current window
    main_window := wd.get_window_handle()!

    // Create new tab
    new_tab := wd.new_window('tab')!
    wd.switch_to_window(new_tab.handle)!

    // Navigate in new tab
    wd.get('https://www.iana.org')!
    new_title := wd.get_title()!

    // Switch back to main window
    wd.switch_to_window(main_window)!

    // Window state management
    wd.maximize_window()!
    wd.fullscreen_window()!
}

Timeouts and Waits (Phase 4)

import webdriver

fn timeouts_example() ! {
    wd := webdriver.new_edge_driver('http://127.0.0.1:9515', caps)!
    defer { wd.quit() or {} }

    // Configure timeouts
    wd.set_implicit_wait(10000)!         // Auto-wait 10s for elements
    wd.set_page_load_timeout(30000)!     // 30s page load timeout
    wd.set_script_timeout(15000)!        // 15s script timeout

    wd.get('https://example.com')!

    // Now element finding automatically waits
    element := wd.find_element('css selector', 'h1')!

    // Custom wait condition
    wd.wait_for(fn (wd webdriver.WebDriver) !bool {
        title := wd.get_title()!
        return title.len > 0
    }, 5000, 500)!
}

πŸ§ͺ Testing

Run Quick Tests (~10 seconds)

v test webdriver/quick_test.v

Run Full Test Suite (~1-2 minutes)

v test webdriver/

Run Integration Tests (~2-3 minutes)

v run integration_test.v

Run Simple Standalone Test

v simple_test.v
.\simple_test.exe

πŸ“š Documentation

🎯 Feature Coverage

Current: πŸŽ‰ 100% feature parity with Selenium WebDriver! πŸŽ‰ ALL Phases Complete! 🎊

Category Status
Session Management βœ… 100%
Navigation βœ… 100%
Element Location βœ… 100%
Cookies βœ… 100%
Screenshots βœ… 100%
Frames βœ… 100%
Element Properties βœ… 100% (Phase 1, 5 & 7)
Alerts βœ… 100% (Phase 2)
Page Information βœ… 100% (Phase 3)
Window Management βœ… 100% (Phase 4)
Timeouts & Waits βœ… 100% (Phase 4 & 6)
Actions API βœ… 100% (Phase 7)
Element Interaction βœ… 100% (Phase 7)
JavaScript Execution βœ… 100% (Phase 8) ✨ NEW
Shadow DOM βœ… 100% (Phase 8) ✨ NEW

πŸ† 100% FEATURE PARITY ACHIEVED! πŸ†

See ROADMAP_TO_100_PERCENT.md for complete roadmap.

✨ What's New in v3.0.0

πŸŽ‰πŸŽŠ Phase 8 Complete: 100% Feature Parity Achieved! πŸŽŠπŸŽ‰

  • βœ… Phase 1: Element Properties (8 methods) - get_text(), get_attribute(), is_displayed(), etc.
  • βœ… Phase 2: Alert Handling (4 methods) - accept_alert(), dismiss_alert(), get_alert_text(), etc.
  • βœ… Phase 3: Page Information (3 methods) - get_title(), get_current_url(), get_page_source()
  • βœ… Phase 4: Window & Waits (8 methods) - Multi-window support, timeouts, window state management
  • βœ… Phase 5: CSS Properties (1 method) - get_css_value() for computed CSS inspection
  • βœ… Phase 6: Expected Conditions (5 methods) - wait_until_clickable(), wait_until_visible(), etc.
  • βœ… Phase 7: Advanced Actions (7 methods) - context_click(), drag_and_drop(), get_element_rect(), submit()
  • βœ… Phase 8: Async JS & Shadow DOM (4 methods) - execute_async_script(), get_shadow_root(), shadow element finding ← NEW!

Latest: Phase 8 added async JavaScript execution and complete Shadow DOM support!

Total: 40 methods added across all phases, raising feature parity from 55% to 100%! πŸŽ‰

πŸ† 100% FEATURE PARITY WITH SELENIUM WEBDRIVER ACHIEVED! πŸ†

See individual phase documentation for detailed examples and usage.

πŸ—οΈ Project Structure

v-webdriver/
β”œβ”€β”€ webdriver/
β”‚   β”œβ”€β”€ client.v              # Core WebDriver client
β”‚   β”œβ”€β”€ elements.v            # Element finding and interaction
β”‚   β”œβ”€β”€ script.v              # JavaScript execution
β”‚   β”œβ”€β”€ window.v              # Window management
β”‚   β”œβ”€β”€ cookies.v             # Cookie operations
β”‚   β”œβ”€β”€ screenshot.v          # Screenshot capture
β”‚   β”œβ”€β”€ actions.v             # Actions API
β”‚   β”œβ”€β”€ frame.v               # Frame switching
β”‚   β”œβ”€β”€ wait.v                # Wait utilities
β”‚   β”œβ”€β”€ capabiities.v         # Capabilities configuration
β”‚   β”œβ”€β”€ types.v               # Common types
β”‚   β”œβ”€β”€ errors.v              # Error handling
β”‚   β”œβ”€β”€ webdriver_test.v      # Unit tests
β”‚   └── quick_test.v          # Quick smoke tests
β”œβ”€β”€ main.v                    # Example usage
β”œβ”€β”€ simple_test.v             # Standalone test suite
β”œβ”€β”€ integration_test.v        # Integration tests
└── README.md                 # This file

🌐 Multi-Browser Support

V WebDriver now supports 4 major browsers:

Browser Driver Default Port Function
Edge EdgeDriver 9515 new_edge_driver()
Chrome ChromeDriver 9515 new_chrome_driver()
Firefox GeckoDriver 4444 new_firefox_driver()
Safari SafariDriver 4445 new_safari_driver()

Browser-Specific Options

EdgeOptions / ChromeOptions:

edge_options: webdriver.EdgeOptions{
    args: ['--headless=new', '--disable-gpu', '--no-sandbox']
    binary: r'C:\Program Files\...\browser.exe'
    extensions: ['extension1.crx', 'extension2.crx']
}

FirefoxOptions:

firefox_options: webdriver.FirefoxOptions{
    args: ['-headless', '-private']
    binary: r'C:\Program Files\Mozilla Firefox\firefox.exe'
    prefs: {
        'browser.download.folderList': json.Any(2)
        'browser.download.dir': json.Any('/tmp/downloads')
    }
    profile: '/path/to/firefox/profile'
}

SafariOptions:

safari_options: webdriver.SafariOptions{
    automatic_inspection: false  // Disable Web Inspector auto-open
    automatic_profiling: false   // Disable profiling auto-start
}

All browsers support standard W3C capabilities like accept_insecure_certs, page_load_strategy, timeouts, and proxy settings.

🀝 Contributing

Contributions are welcome! Now that 100% feature parity is achieved, focus areas include:

  1. Browser Testing - Help test Chrome, Firefox, Safari drivers on different platforms
  2. Performance Optimizations - Connection pooling, parallel execution
  3. Advanced Features - BiDi protocol support, enhanced logging
  4. Platform Support - macOS, Linux testing and optimization

V WebDriver has achieved 100% feature parity with Selenium's core functionality!

πŸ“„ License

[Your License Here]

πŸ™ Acknowledgments

πŸ“ž Support

For issues, questions, or contributions:

  • Open an issue on GitHub
  • Check existing documentation
  • Review test files for usage examples

Status: Production-ready for web automation. 97% feature parity achieved! πŸŽ‰

Version: 2.2.0 (97% Selenium feature parity)

Completed Phases: βœ… Phase 1 | βœ… Phase 2 | βœ… Phase 3 | βœ… Phase 4 | βœ… Phase 6 | βœ… Phase 7

Latest Update: 2026-02-15 - Completed Phase 7 (Advanced Actions) - 35 methods added total across all phases

Next Milestone: v3.0.0 - 100% Feature Parity (only 3% remaining!)

About

A V language implementation of the W3C WebDriver protocol for browser automation - Fast, safe, and Selenium-compatible

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors