fix tests

This commit is contained in:
Nick Sweeting
2025-03-27 23:00:25 -07:00
parent 3ea376e5a2
commit cc98598fb9
2 changed files with 234 additions and 236 deletions

View File

@@ -50,6 +50,7 @@ dev = [
"langchain-aws>=0.2.11",
"langchain-fireworks>=0.2.6",
"langchain-google-genai==2.0.8",
"pytest>=8.3.5",
]
[tool.ruff]

View File

@@ -1,243 +1,240 @@
import pytest
from unittest.mock import MagicMock
from playwright.async_api import Page
from browser_use.controller.registry.views import ActionRegistry, RegisteredAction
import pytest
from playwright.async_api import Page
from pydantic import BaseModel
from browser_use.controller.registry.service import Registry
from browser_use.controller.registry.views import ActionRegistry, RegisteredAction
class EmptyParamModel(BaseModel):
pass
class TestActionFilters:
def test_get_prompt_description_no_filters(self):
"""Test that system prompt only includes actions with no filters"""
registry = ActionRegistry()
# Add actions with and without filters
no_filter_action = RegisteredAction(
name="no_filter_action",
description="Action with no filters",
function=lambda: None,
param_model=MagicMock(),
domains=None,
page_filter=None
)
page_filter_action = RegisteredAction(
name="page_filter_action",
description="Action with page filter",
function=lambda: None,
param_model=MagicMock(),
domains=None,
page_filter=lambda page: True
)
domain_filter_action = RegisteredAction(
name="domain_filter_action",
description="Action with domain filter",
function=lambda: None,
param_model=MagicMock(),
domains=["example.com"],
page_filter=None
)
registry.actions = {
"no_filter_action": no_filter_action,
"page_filter_action": page_filter_action,
"domain_filter_action": domain_filter_action
}
# System prompt (no page) should only include actions with no filters
system_description = registry.get_prompt_description()
assert "no_filter_action" in system_description
assert "page_filter_action" not in system_description
assert "domain_filter_action" not in system_description
def test_page_filter_matching(self):
"""Test that page filters work correctly"""
registry = ActionRegistry()
# Create a mock page
mock_page = MagicMock(spec=Page)
mock_page.url = "https://example.com/page"
# Create actions with different page filters
matching_action = RegisteredAction(
name="matching_action",
description="Action with matching page filter",
function=lambda: None,
param_model=MagicMock(),
domains=None,
page_filter=lambda page: "example.com" in page.url
)
non_matching_action = RegisteredAction(
name="non_matching_action",
description="Action with non-matching page filter",
function=lambda: None,
param_model=MagicMock(),
domains=None,
page_filter=lambda page: "other.com" in page.url
)
registry.actions = {
"matching_action": matching_action,
"non_matching_action": non_matching_action
}
# Page-specific description should only include matching actions
page_description = registry.get_prompt_description(mock_page)
assert "matching_action" in page_description
assert "non_matching_action" not in page_description
def test_domain_filter_matching(self):
"""Test that domain filters work correctly with glob patterns"""
registry = ActionRegistry()
# Create actions with different domain patterns
actions = {
"exact_match": RegisteredAction(
name="exact_match",
description="Exact domain match",
function=lambda: None,
param_model=MagicMock(),
domains=["example.com"],
page_filter=None
),
"subdomain_match": RegisteredAction(
name="subdomain_match",
description="Subdomain wildcard match",
function=lambda: None,
param_model=MagicMock(),
domains=["*.example.com"],
page_filter=None
),
"prefix_match": RegisteredAction(
name="prefix_match",
description="Prefix wildcard match",
function=lambda: None,
param_model=MagicMock(),
domains=["example*"],
page_filter=None
),
"non_matching": RegisteredAction(
name="non_matching",
description="Non-matching domain",
function=lambda: None,
param_model=MagicMock(),
domains=["other.com"],
page_filter=None
)
}
registry.actions = actions
# Test exact domain match
mock_page = MagicMock(spec=Page)
mock_page.url = "https://example.com/page"
exact_match_description = registry.get_prompt_description(mock_page)
assert "exact_match" in exact_match_description
assert "non_matching" not in exact_match_description
# Test subdomain match
mock_page.url = "https://sub.example.com/page"
subdomain_match_description = registry.get_prompt_description(mock_page)
assert "subdomain_match" in subdomain_match_description
assert "exact_match" not in subdomain_match_description
# Test prefix match
mock_page.url = "https://example123.org/page"
prefix_match_description = registry.get_prompt_description(mock_page)
assert "prefix_match" in prefix_match_description
def test_domain_and_page_filter_together(self):
"""Test that actions can be filtered by both domain and page filter"""
registry = ActionRegistry()
# Create a mock page
mock_page = MagicMock(spec=Page)
mock_page.url = "https://example.com/admin"
# Actions with different combinations of filters
actions = {
"domain_only": RegisteredAction(
name="domain_only",
description="Domain filter only",
function=lambda: None,
param_model=MagicMock(),
domains=["example.com"],
page_filter=None
),
"page_only": RegisteredAction(
name="page_only",
description="Page filter only",
function=lambda: None,
param_model=MagicMock(),
domains=None,
page_filter=lambda page: "admin" in page.url
),
"both_matching": RegisteredAction(
name="both_matching",
description="Both filters matching",
function=lambda: None,
param_model=MagicMock(),
domains=["example.com"],
page_filter=lambda page: "admin" in page.url
),
"both_one_fail": RegisteredAction(
name="both_one_fail",
description="One filter fails",
function=lambda: None,
param_model=MagicMock(),
domains=["other.com"],
page_filter=lambda page: "admin" in page.url
),
}
registry.actions = actions
# Check that all matching filters are included
description = registry.get_prompt_description(mock_page)
assert "domain_only" in description
assert "page_only" in description
assert "both_matching" in description
assert "both_one_fail" in description # Should match because page_filter matches
def test_get_prompt_description_no_filters(self):
"""Test that system prompt only includes actions with no filters"""
registry = ActionRegistry()
@pytest.mark.asyncio
async def test_registry_action_decorator(self):
"""Test the action decorator with filters"""
registry = Registry()
# Define actions with different filters
@registry.action(
description="No filter action",
)
def no_filter_action():
pass
@registry.action(
description="Domain filter action",
domains=["example.com"]
)
def domain_filter_action():
pass
@registry.action(
description="Page filter action",
page_filter=lambda page: "admin" in page.url
)
def page_filter_action():
pass
# Check that system prompt only includes the no_filter_action
system_description = registry.get_prompt_description()
assert "No filter action" in system_description
assert "Domain filter action" not in system_description
assert "Page filter action" not in system_description
# Check that page-specific prompt includes the right actions
mock_page = MagicMock(spec=Page)
mock_page.url = "https://example.com/admin"
page_description = registry.get_prompt_description(mock_page)
assert "Domain filter action" in page_description
assert "Page filter action" in page_description
# Add actions with and without filters
no_filter_action = RegisteredAction(
name='no_filter_action',
description='Action with no filters',
function=lambda: None,
param_model=EmptyParamModel,
domains=None,
page_filter=None,
)
page_filter_action = RegisteredAction(
name='page_filter_action',
description='Action with page filter',
function=lambda: None,
param_model=EmptyParamModel,
domains=None,
page_filter=lambda page: True,
)
domain_filter_action = RegisteredAction(
name='domain_filter_action',
description='Action with domain filter',
function=lambda: None,
param_model=EmptyParamModel,
domains=['example.com'],
page_filter=None,
)
registry.actions = {
'no_filter_action': no_filter_action,
'page_filter_action': page_filter_action,
'domain_filter_action': domain_filter_action,
}
# System prompt (no page) should only include actions with no filters
system_description = registry.get_prompt_description()
assert 'no_filter_action' in system_description
assert 'page_filter_action' not in system_description
assert 'domain_filter_action' not in system_description
def test_page_filter_matching(self):
"""Test that page filters work correctly"""
registry = ActionRegistry()
# Create a mock page
mock_page = MagicMock(spec=Page)
mock_page.url = 'https://example.com/page'
# Create actions with different page filters
matching_action = RegisteredAction(
name='matching_action',
description='Action with matching page filter',
function=lambda: None,
param_model=EmptyParamModel,
domains=None,
page_filter=lambda page: 'example.com' in page.url,
)
non_matching_action = RegisteredAction(
name='non_matching_action',
description='Action with non-matching page filter',
function=lambda: None,
param_model=EmptyParamModel,
domains=None,
page_filter=lambda page: 'other.com' in page.url,
)
registry.actions = {'matching_action': matching_action, 'non_matching_action': non_matching_action}
# Page-specific description should only include matching actions
page_description = registry.get_prompt_description(mock_page)
assert 'matching_action' in page_description
assert 'non_matching_action' not in page_description
def test_domain_filter_matching(self):
"""Test that domain filters work correctly with glob patterns"""
registry = ActionRegistry()
# Create actions with different domain patterns
actions = {
'exact_match': RegisteredAction(
name='exact_match',
description='Exact domain match',
function=lambda: None,
param_model=EmptyParamModel,
domains=['example.com'],
page_filter=None,
),
'subdomain_match': RegisteredAction(
name='subdomain_match',
description='Subdomain wildcard match',
function=lambda: None,
param_model=EmptyParamModel,
domains=['*.example.com'],
page_filter=None,
),
'prefix_match': RegisteredAction(
name='prefix_match',
description='Prefix wildcard match',
function=lambda: None,
param_model=EmptyParamModel,
domains=['example*'],
page_filter=None,
),
'non_matching': RegisteredAction(
name='non_matching',
description='Non-matching domain',
function=lambda: None,
param_model=EmptyParamModel,
domains=['other.com'],
page_filter=None,
),
}
registry.actions = actions
# Test exact domain match
mock_page = MagicMock(spec=Page)
mock_page.url = 'https://example.com/page'
exact_match_description = registry.get_prompt_description(mock_page)
assert 'exact_match' in exact_match_description
assert 'non_matching' not in exact_match_description
# Test subdomain match
mock_page.url = 'https://sub.example.com/page'
subdomain_match_description = registry.get_prompt_description(mock_page)
assert 'subdomain_match' in subdomain_match_description
assert 'exact_match' not in subdomain_match_description
# Test prefix match
mock_page.url = 'https://example123.org/page'
prefix_match_description = registry.get_prompt_description(mock_page)
assert 'prefix_match' in prefix_match_description
def test_domain_and_page_filter_together(self):
"""Test that actions can be filtered by both domain and page filter"""
registry = ActionRegistry()
# Create a mock page
mock_page = MagicMock(spec=Page)
mock_page.url = 'https://example.com/admin'
# Actions with different combinations of filters
actions = {
'domain_only': RegisteredAction(
name='domain_only',
description='Domain filter only',
function=lambda: None,
param_model=EmptyParamModel,
domains=['example.com'],
page_filter=None,
),
'page_only': RegisteredAction(
name='page_only',
description='Page filter only',
function=lambda: None,
param_model=EmptyParamModel,
domains=None,
page_filter=lambda page: 'admin' in page.url,
),
'both_matching': RegisteredAction(
name='both_matching',
description='Both filters matching',
function=lambda: None,
param_model=EmptyParamModel,
domains=['example.com'],
page_filter=lambda page: 'admin' in page.url,
),
'both_one_fail': RegisteredAction(
name='both_one_fail',
description='One filter fails',
function=lambda: None,
param_model=EmptyParamModel,
domains=['other.com'],
page_filter=lambda page: 'admin' in page.url,
),
}
registry.actions = actions
# Check that all matching filters are included
description = registry.get_prompt_description(mock_page)
assert 'domain_only' in description
assert 'page_only' in description
assert 'both_matching' in description
assert 'both_one_fail' in description # Should match because page_filter matches
@pytest.mark.asyncio
async def test_registry_action_decorator(self):
"""Test the action decorator with filters"""
registry = Registry()
# Define actions with different filters
@registry.action(
description='No filter action',
)
def no_filter_action():
pass
@registry.action(description='Domain filter action', domains=['example.com'])
def domain_filter_action():
pass
@registry.action(description='Page filter action', page_filter=lambda page: 'admin' in page.url)
def page_filter_action():
pass
# Check that system prompt only includes the no_filter_action
system_description = registry.get_prompt_description()
assert 'No filter action' in system_description
assert 'Domain filter action' not in system_description
assert 'Page filter action' not in system_description
# Check that page-specific prompt includes the right actions
mock_page = MagicMock(spec=Page)
mock_page.url = 'https://example.com/admin'
page_description = registry.get_prompt_description(mock_page)
assert 'Domain filter action' in page_description
assert 'Page filter action' in page_description