- Integrated GhostCursorEngine into CamoufoxManager.navigate() - Implemented random viewport targeting and micro-movements post-load - Added integration tests verifying call sequence - Fixed manual TLS verification script - Verified Scaling Limits (2.0 CPU)
55 lines
2.3 KiB
Python
55 lines
2.3 KiB
Python
import pytest
|
|
from unittest.mock import AsyncMock, patch
|
|
from src.browser.manager import CamoufoxManager
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_manager_integration_ghost_cursor():
|
|
"""
|
|
Verify that CamoufoxManager.navigate calls GhostCursor methods.
|
|
"""
|
|
# Mock GhostCursorEngine within the manager module context if possible,
|
|
# or better, mock it via patch on the class instance after init if easier,
|
|
# but since it's instantiated in __init__, we patch the class in the module.
|
|
|
|
with patch('src.browser.manager.GhostCursorEngine') as MockGhostEngine, \
|
|
patch('src.browser.manager.async_playwright') as MockPlaywright:
|
|
|
|
# Setup Mocks
|
|
mock_engine_instance = MockGhostEngine.return_value
|
|
mock_engine_instance.move_to = AsyncMock()
|
|
mock_engine_instance.random_micro_movement = AsyncMock()
|
|
|
|
mock_pw_context = AsyncMock()
|
|
MockPlaywright.return_value.start.return_value = mock_pw_context
|
|
# Mock browser, context, page chain...
|
|
# CamoufoxManager.initialize is complex to mock fully without heavy boilerplate.
|
|
# We can try to rely on the fact that navigate checks self.page.
|
|
|
|
# Let's instantiate manager
|
|
manager = CamoufoxManager()
|
|
|
|
# Manually set the mock page to bypass initialize() complexity if we just want to test navigate logic
|
|
mock_page = AsyncMock()
|
|
manager.page = mock_page
|
|
|
|
# We also need to inject our mock engine instance if the init already ran?
|
|
# Yes, line `self.ghost_cursor = GhostCursorEngine()` ran during init.
|
|
# So manager.ghost_cursor is the mock_engine_instance provided by patch.
|
|
|
|
# EXECUTE
|
|
await manager.navigate("http://example.com")
|
|
|
|
# VERIFY
|
|
# 1. Page goto called
|
|
mock_page.goto.assert_awaited_once_with("http://example.com", wait_until='domcontentloaded')
|
|
|
|
# 2. GhostCursor move_to called
|
|
assert mock_engine_instance.move_to.called
|
|
args = mock_engine_instance.move_to.call_args[0]
|
|
# args: (page, x, y)
|
|
assert args[0] == mock_page
|
|
assert 100 <= args[1] <= 1800 # x check
|
|
assert 100 <= args[2] <= 900 # y check
|
|
|
|
# 3. Random micro movement called
|
|
mock_engine_instance.random_micro_movement.assert_awaited_once_with(mock_page)
|