"""Test error handling and edge cases."""

from __future__ import annotations

import pytest

from browser_hybrid import BrowserError, CDPError, TimeoutError
from browser_hybrid.browser import escape_js_string


class TestErrorPaths:
    def test_escape_js_string_basic(self):
        """Test basic escaping logic."""
        assert escape_js_string("") == ""
        assert escape_js_string("\\") == "\\\\"
        assert escape_js_string("'") == "\\'"
        assert escape_js_string('"') == '\\"'
        assert escape_js_string("`") == "\\`"
        assert escape_js_string("\n") == "\\n"
        assert escape_js_string("\r") == "\\r"

    def test_escape_js_string_mixed(self):
        """Test complex mixed strings."""
        original = "a'b\"c`d\ne\\f\rg"
        expected = "a\\'b\\\"c\\`d\\ne\\\\f\\rg"
        assert escape_js_string(original) == expected

    def test_escape_js_string_fuzz_like(self):
        """Fuzz-like test with various characters."""
        # Test with high-unicode characters
        high_uni = "🚀\u2728\U0001f308"
        assert escape_js_string(high_uni) == high_uni

        # Test with script-like strings
        script = "<script>alert('xss');</script>"
        # Note: escape_js_string doesn't escape < > by design as it's for JS string injection
        # only escapes what would break the string literal context
        assert "alert(\\'xss\\')" in escape_js_string(script)

    def test_error_classes(self):
        """Test that error classes can be initialized and formatted."""
        with pytest.raises(BrowserError) as excinfo:
            raise BrowserError("test message", context={"key": "val"})
        assert "test message" in str(excinfo.value)
        assert excinfo.value.context == {"key": "val"}

        with pytest.raises(CDPError) as excinfo:
            raise CDPError("cdp failed", code=-32000, method="Page.navigate")
        assert "cdp failed" in str(excinfo.value)
        assert excinfo.value.code == -32000
        assert excinfo.value.method == "Page.navigate"

        with pytest.raises(TimeoutError) as excinfo:
            raise TimeoutError("timeout", timeout=5.0, operation="wait")
        assert "timeout" in str(excinfo.value)
        assert excinfo.value.timeout == 5.0
        assert excinfo.value.operation == "wait"
