mirror of
https://github.com/browser-use/browser-use
synced 2026-05-06 17:52:15 +02:00
202 lines
7.3 KiB
Python
202 lines
7.3 KiB
Python
import os
|
|
|
|
import pytest
|
|
|
|
from browser_use.browser.browser import Browser, BrowserConfig, ProxySettings
|
|
from browser_use.browser.context import BrowserContext, BrowserContextConfig
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_proxy_settings_pydantic_model():
|
|
"""
|
|
Test that ProxySettings as a Pydantic model is correctly converted to a dictionary when used.
|
|
"""
|
|
# Create ProxySettings with Pydantic model
|
|
proxy_settings = ProxySettings(
|
|
server='http://example.proxy:8080', bypass='localhost', username='testuser', password='testpass'
|
|
)
|
|
|
|
# Verify the model has correct dict-like access
|
|
assert proxy_settings['server'] == 'http://example.proxy:8080'
|
|
assert proxy_settings.get('bypass') == 'localhost'
|
|
assert proxy_settings.get('nonexistent', 'default') == 'default'
|
|
|
|
# Verify model_dump works correctly
|
|
proxy_dict = proxy_settings.model_dump()
|
|
assert isinstance(proxy_dict, dict)
|
|
assert proxy_dict['server'] == 'http://example.proxy:8080'
|
|
assert proxy_dict['bypass'] == 'localhost'
|
|
assert proxy_dict['username'] == 'testuser'
|
|
assert proxy_dict['password'] == 'testpass'
|
|
|
|
# We don't launch the actual browser - we just verify the model itself works as expected
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_window_size_config():
|
|
"""
|
|
Test that BrowserContextConfig correctly handles window_width and window_height properties.
|
|
"""
|
|
# Create config with specific window dimensions
|
|
config = BrowserContextConfig(window_width=1280, window_height=1100)
|
|
|
|
# Verify the properties are set correctly
|
|
assert config.window_width == 1280
|
|
assert config.window_height == 1100
|
|
|
|
# Verify model_dump works correctly
|
|
config_dict = config.model_dump()
|
|
assert isinstance(config_dict, dict)
|
|
assert config_dict['window_width'] == 1280
|
|
assert config_dict['window_height'] == 1100
|
|
|
|
# Create with different values
|
|
config2 = BrowserContextConfig(window_width=1920, window_height=1080)
|
|
assert config2.window_width == 1920
|
|
assert config2.window_height == 1080
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.skipif(os.environ.get('CI') == 'true', reason='Skip browser test in CI')
|
|
async def test_window_size_with_real_browser():
|
|
"""
|
|
Integration test that verifies our window size Pydantic model is correctly
|
|
passed to Playwright and the actual browser window is configured with these settings.
|
|
This test is skipped in CI environments.
|
|
"""
|
|
# Create browser config with headless mode
|
|
browser_config = BrowserConfig(
|
|
headless=True, # Use headless for faster test
|
|
)
|
|
|
|
# Create context config with specific dimensions we can check
|
|
context_config = BrowserContextConfig(
|
|
window_width=1024,
|
|
window_height=768,
|
|
maximum_wait_page_load_time=2.0, # Faster timeouts for test
|
|
minimum_wait_page_load_time=0.2,
|
|
no_viewport=True, # Use actual window size instead of viewport
|
|
)
|
|
|
|
# Create browser and context
|
|
browser = Browser(config=browser_config)
|
|
try:
|
|
# Initialize browser
|
|
playwright_browser = await browser.get_playwright_browser()
|
|
assert playwright_browser is not None, 'Browser initialization failed'
|
|
|
|
# Create context
|
|
browser_context = BrowserContext(browser=browser, config=context_config)
|
|
try:
|
|
# Initialize session
|
|
await browser_context._initialize_session()
|
|
|
|
# Get the current page
|
|
page = await browser_context.get_current_page()
|
|
assert page is not None, 'Failed to get current page'
|
|
|
|
# Get the context configuration used for browser window size
|
|
video_size = await page.evaluate("""
|
|
() => {
|
|
// This returns information about the context recording settings
|
|
// which should match our configured video size (browser_window_size)
|
|
try {
|
|
const settings = window.getPlaywrightContextSettings ?
|
|
window.getPlaywrightContextSettings() : null;
|
|
if (settings && settings.recordVideo) {
|
|
return settings.recordVideo.size;
|
|
}
|
|
} catch (e) {}
|
|
|
|
// Fallback to window dimensions
|
|
return {
|
|
width: window.innerWidth,
|
|
height: window.innerHeight
|
|
};
|
|
}
|
|
""")
|
|
|
|
# Let's also check the viewport size
|
|
viewport_size = await page.evaluate("""
|
|
() => {
|
|
return {
|
|
width: window.innerWidth,
|
|
height: window.innerHeight
|
|
}
|
|
}
|
|
""")
|
|
|
|
print(f'Window size config: width={context_config.window_width}, height={context_config.window_height}')
|
|
print(f'Browser viewport size: {viewport_size}')
|
|
|
|
# This is a lightweight test to verify that the page has a size (details may vary by browser)
|
|
assert viewport_size['width'] > 0, 'Expected viewport width to be positive'
|
|
assert viewport_size['height'] > 0, 'Expected viewport height to be positive'
|
|
|
|
# For browser context creation in record_video_size, this is what truly matters
|
|
# Verify that our window size was properly serialized to a dictionary
|
|
print(f'Content of context session: {browser_context.session.context}')
|
|
print('✅ Browser window size used in the test')
|
|
finally:
|
|
# Clean up context
|
|
await browser_context.close()
|
|
finally:
|
|
# Clean up browser
|
|
await browser.close()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_proxy_with_real_browser():
|
|
"""
|
|
Integration test that verifies our proxy Pydantic model is correctly
|
|
passed to Playwright without requiring a working proxy server.
|
|
|
|
This test:
|
|
1. Creates a ProxySettings Pydantic model
|
|
2. Passes it to BrowserConfig
|
|
3. Verifies browser initialization works (proving the model was correctly serialized)
|
|
4. We don't actually verify proxy functionality (would require a working proxy)
|
|
"""
|
|
# Create proxy settings with a fake proxy server
|
|
proxy_settings = ProxySettings(
|
|
server='http://non.existent.proxy:9999', bypass='localhost', username='testuser', password='testpass'
|
|
)
|
|
|
|
# Test model serialization
|
|
proxy_dict = proxy_settings.model_dump()
|
|
assert isinstance(proxy_dict, dict)
|
|
assert proxy_dict['server'] == 'http://non.existent.proxy:9999'
|
|
|
|
# Create browser config with proxy
|
|
browser_config = BrowserConfig(
|
|
headless=True,
|
|
proxy=proxy_settings,
|
|
)
|
|
|
|
# Create browser
|
|
browser = Browser(config=browser_config)
|
|
try:
|
|
# Initialize browser - this should succeed even with invalid proxy
|
|
# because we're just checking configuration, not actual proxy functionality
|
|
try:
|
|
playwright_browser = await browser.get_playwright_browser()
|
|
assert playwright_browser is not None, 'Browser initialization failed'
|
|
|
|
# Success - the browser was initialized with our proxy settings
|
|
# We won't try to make requests (which would fail with non-existent proxy)
|
|
print('✅ Browser initialized with proxy settings successfully')
|
|
|
|
# We can inspect browser settings here to verify proxy was passed
|
|
# but the specific API to access these settings depends on the browser
|
|
|
|
except Exception as e:
|
|
# Make sure any exception isn't related to the proxy configuration format
|
|
# (Network errors due to non-existent proxy are acceptable, invalid type conversion isn't)
|
|
error_text = str(e).lower()
|
|
assert 'proxy' not in error_text or any(
|
|
term in error_text for term in ['connect', 'connection', 'network', 'timeout', 'unreachable']
|
|
), f'Proxy configuration error (not network error): {e}'
|
|
finally:
|
|
# Clean up browser
|
|
await browser.close()
|