2cab53bc94
Test Vector Database Adaptors / Test MCP Vector DB Tools (push) Has been cancelled
Tests / Code Quality (Ruff & Mypy) (push) Has been cancelled
Tests / Fast Unit Tests (parallel) (macos-latest, 3.11) (push) Has been cancelled
Tests / Fast Unit Tests (parallel) (macos-latest, 3.12) (push) Has been cancelled
Tests / Tests (push) Has been cancelled
Docker Publish / Build and Push Docker Images (map[description:Skill Seekers CLI - Convert documentation to AI skills dockerfile:Dockerfile name:skill-seekers]) (push) Has been cancelled
Docker Publish / Build and Push Docker Images (map[description:Skill Seekers MCP Server - 25 tools for AI assistants dockerfile:Dockerfile.mcp name:skill-seekers-mcp]) (push) Has been cancelled
Docker Publish / Test Docker Images (push) Has been cancelled
Tests / Fast Unit Tests (parallel) (ubuntu-latest, 3.10) (push) Has been cancelled
Tests / Fast Unit Tests (parallel) (ubuntu-latest, 3.11) (push) Has been cancelled
Tests / Fast Unit Tests (parallel) (ubuntu-latest, 3.12) (push) Has been cancelled
Tests / Serial / Integration / E2E Tests (push) Has been cancelled
Tests / MCP Server Tests (push) Has been cancelled
Test Vector Database Adaptors / Test chroma Adaptor (push) Has been cancelled
Test Vector Database Adaptors / Test faiss Adaptor (push) Has been cancelled
Test Vector Database Adaptors / Test qdrant Adaptor (push) Has been cancelled
Test Vector Database Adaptors / Test weaviate Adaptor (push) Has been cancelled
180 lines
5.9 KiB
Python
180 lines
5.9 KiB
Python
"""Tests for browser_renderer.py (#321).
|
|
|
|
Real end-to-end tests using actual Playwright + Chromium.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from skill_seekers.cli.browser_renderer import (
|
|
BrowserRenderer,
|
|
_auto_install_chromium,
|
|
_check_playwright_available,
|
|
)
|
|
|
|
pytestmark = [pytest.mark.integration, pytest.mark.network]
|
|
|
|
# Skip all real browser tests when Playwright is not installed
|
|
_has_playwright = _check_playwright_available()
|
|
requires_playwright = pytest.mark.skipif(
|
|
not _has_playwright,
|
|
reason="Playwright not installed (pip install 'skill-seekers[browser]')",
|
|
)
|
|
|
|
|
|
@requires_playwright
|
|
class TestPlaywrightAvailability:
|
|
"""Test that playwright is properly detected."""
|
|
|
|
def test_playwright_is_available(self):
|
|
assert _check_playwright_available() is True
|
|
|
|
def test_auto_install_succeeds(self):
|
|
# Chromium is already installed, so this should be a no-op success
|
|
assert _auto_install_chromium() is True
|
|
|
|
|
|
@requires_playwright
|
|
class TestBrowserRendererReal:
|
|
"""Real end-to-end tests with actual Chromium."""
|
|
|
|
def test_render_simple_page(self):
|
|
"""Render a real page and get HTML back."""
|
|
with BrowserRenderer() as renderer:
|
|
html = renderer.render_page("https://example.com")
|
|
|
|
assert "<html" in html.lower()
|
|
assert "Example Domain" in html
|
|
|
|
def test_render_returns_js_content(self):
|
|
"""Verify that JS-generated content is captured (not just the shell)."""
|
|
with BrowserRenderer() as renderer:
|
|
html = renderer.render_page("https://example.com")
|
|
|
|
# example.com has static content, but the point is we get real HTML
|
|
assert len(html) > 500
|
|
assert "<body" in html.lower()
|
|
|
|
def test_multiple_pages_reuse_browser(self):
|
|
"""Rendering multiple pages should reuse the same browser instance."""
|
|
with BrowserRenderer() as renderer:
|
|
html1 = renderer.render_page("https://example.com")
|
|
html2 = renderer.render_page("https://example.com")
|
|
|
|
assert "Example Domain" in html1
|
|
assert "Example Domain" in html2
|
|
|
|
def test_close_cleans_up(self):
|
|
"""After close(), internal state is None."""
|
|
renderer = BrowserRenderer()
|
|
renderer.render_page("https://example.com")
|
|
assert renderer._browser is not None
|
|
|
|
renderer.close()
|
|
assert renderer._browser is None
|
|
assert renderer._context is None
|
|
assert renderer._playwright is None
|
|
|
|
def test_context_manager_cleans_up(self):
|
|
"""Context manager calls close on exit."""
|
|
with BrowserRenderer() as renderer:
|
|
renderer.render_page("https://example.com")
|
|
assert renderer._browser is not None
|
|
|
|
assert renderer._browser is None
|
|
|
|
def test_timeout_parameter(self):
|
|
"""Custom timeout is respected."""
|
|
renderer = BrowserRenderer(timeout=5000)
|
|
assert renderer._timeout == 5000
|
|
renderer.close()
|
|
|
|
def test_wait_until_parameter(self):
|
|
"""Custom wait_until is respected."""
|
|
renderer = BrowserRenderer(wait_until="domcontentloaded")
|
|
assert renderer._wait_until == "domcontentloaded"
|
|
renderer.close()
|
|
|
|
|
|
class TestDocScraperBrowserIntegration:
|
|
"""Test that doc_scraper correctly accepts browser config."""
|
|
|
|
def test_browser_mode_config_sets_attribute(self):
|
|
from skill_seekers.cli.doc_scraper import DocToSkillConverter
|
|
|
|
config = {
|
|
"name": "test",
|
|
"base_url": "https://example.com",
|
|
"browser": True,
|
|
"selectors": {},
|
|
"url_patterns": {"include": [], "exclude": []},
|
|
}
|
|
scraper = DocToSkillConverter(config)
|
|
assert scraper.browser_mode is True
|
|
assert scraper._browser_renderer is None
|
|
|
|
def test_browser_mode_default_false(self):
|
|
from skill_seekers.cli.doc_scraper import DocToSkillConverter
|
|
|
|
config = {
|
|
"name": "test",
|
|
"base_url": "https://example.com",
|
|
"selectors": {},
|
|
"url_patterns": {"include": [], "exclude": []},
|
|
}
|
|
scraper = DocToSkillConverter(config)
|
|
assert scraper.browser_mode is False
|
|
|
|
@requires_playwright
|
|
def test_render_with_browser_returns_html(self):
|
|
"""Test the _render_with_browser helper directly."""
|
|
from skill_seekers.cli.doc_scraper import DocToSkillConverter
|
|
|
|
config = {
|
|
"name": "test",
|
|
"base_url": "https://example.com",
|
|
"browser": True,
|
|
"selectors": {},
|
|
"url_patterns": {"include": [], "exclude": []},
|
|
}
|
|
scraper = DocToSkillConverter(config)
|
|
|
|
html = scraper._render_with_browser("https://example.com")
|
|
assert "Example Domain" in html
|
|
assert scraper._browser_renderer is not None
|
|
|
|
# Clean up
|
|
scraper._browser_renderer.close()
|
|
|
|
|
|
class TestBrowserArgument:
|
|
"""Test --browser argument is accepted by DocToSkillConverter config."""
|
|
|
|
def test_browser_config_true(self):
|
|
"""Test that DocToSkillConverter accepts browser=True in config."""
|
|
from skill_seekers.cli.doc_scraper import DocToSkillConverter
|
|
|
|
config = {
|
|
"name": "test",
|
|
"base_url": "https://example.com",
|
|
"browser": True,
|
|
"selectors": {},
|
|
"url_patterns": {"include": [], "exclude": []},
|
|
}
|
|
scraper = DocToSkillConverter(config)
|
|
assert scraper.browser_mode is True
|
|
|
|
def test_browser_config_default_false(self):
|
|
"""Test that DocToSkillConverter defaults browser to False."""
|
|
from skill_seekers.cli.doc_scraper import DocToSkillConverter
|
|
|
|
config = {
|
|
"name": "test",
|
|
"base_url": "https://example.com",
|
|
"selectors": {},
|
|
"url_patterns": {"include": [], "exclude": []},
|
|
}
|
|
scraper = DocToSkillConverter(config)
|
|
assert scraper.browser_mode is False
|