fix: commit verified semantic repair changes
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
# [DEF:backend.src.plugins.llm_analysis.__tests__.test_screenshot_service:Module]
|
||||
# [DEF:TestScreenshotService:Module]
|
||||
# @RELATION: VERIFIES ->[src.plugins.llm_analysis.service.ScreenshotService]
|
||||
# @COMPLEXITY: 3
|
||||
# @SEMANTICS: tests, screenshot-service, navigation, timeout-regression
|
||||
# @PURPOSE: Protect dashboard screenshot navigation from brittle networkidle waits.
|
||||
@@ -9,6 +10,7 @@ from src.plugins.llm_analysis.service import ScreenshotService
|
||||
|
||||
|
||||
# [DEF:test_iter_login_roots_includes_child_frames:Function]
|
||||
# @RELATION: BINDS_TO ->[TestScreenshotService]
|
||||
# @PURPOSE: Login discovery must search embedded auth frames, not only the main page.
|
||||
# @PRE: Page exposes child frames list.
|
||||
# @POST: Returned roots include page plus child frames in order.
|
||||
@@ -21,10 +23,13 @@ def test_iter_login_roots_includes_child_frames():
|
||||
roots = service._iter_login_roots(fake_page)
|
||||
|
||||
assert roots == [fake_page, frame_a, frame_b]
|
||||
|
||||
|
||||
# [/DEF:test_iter_login_roots_includes_child_frames:Function]
|
||||
|
||||
|
||||
# [DEF:test_response_looks_like_login_page_detects_login_markup:Function]
|
||||
# @RELATION: BINDS_TO ->[TestScreenshotService]
|
||||
# @PURPOSE: Direct login fallback must reject responses that render the login screen again.
|
||||
# @PRE: Response body contains stable login-page markers.
|
||||
# @POST: Helper returns True so caller treats fallback as failed authentication.
|
||||
@@ -45,10 +50,13 @@ def test_response_looks_like_login_page_detects_login_markup():
|
||||
)
|
||||
|
||||
assert result is True
|
||||
|
||||
|
||||
# [/DEF:test_response_looks_like_login_page_detects_login_markup:Function]
|
||||
|
||||
|
||||
# [DEF:test_find_first_visible_locator_skips_hidden_first_match:Function]
|
||||
# @RELATION: BINDS_TO ->[TestScreenshotService]
|
||||
# @PURPOSE: Locator helper must not reject a selector collection just because its first element is hidden.
|
||||
# @PRE: First matched element is hidden and second matched element is visible.
|
||||
# @POST: Helper returns the second visible candidate.
|
||||
@@ -73,18 +81,23 @@ async def test_find_first_visible_locator_skips_hidden_first_match():
|
||||
return self._elements[index]
|
||||
|
||||
service = ScreenshotService(env=type("Env", (), {})())
|
||||
hidden_then_visible = _FakeLocator([
|
||||
_FakeElement(False, "hidden"),
|
||||
_FakeElement(True, "visible"),
|
||||
])
|
||||
hidden_then_visible = _FakeLocator(
|
||||
[
|
||||
_FakeElement(False, "hidden"),
|
||||
_FakeElement(True, "visible"),
|
||||
]
|
||||
)
|
||||
|
||||
result = await service._find_first_visible_locator([hidden_then_visible])
|
||||
|
||||
assert result.label == "visible"
|
||||
|
||||
|
||||
# [/DEF:test_find_first_visible_locator_skips_hidden_first_match:Function]
|
||||
|
||||
|
||||
# [DEF:test_submit_login_via_form_post_uses_browser_context_request:Function]
|
||||
# @RELATION: BINDS_TO ->[TestScreenshotService]
|
||||
# @PURPOSE: Fallback login must submit hidden fields and credentials through the context request cookie jar.
|
||||
# @PRE: Login DOM exposes csrf hidden field and request context returns authenticated HTML.
|
||||
# @POST: Helper returns True and request payload contains csrf_token plus credentials plus request options.
|
||||
@@ -122,15 +135,25 @@ async def test_submit_login_via_form_post_uses_browser_context_request():
|
||||
def __init__(self):
|
||||
self.calls = []
|
||||
|
||||
async def post(self, url, form=None, headers=None, timeout=None, fail_on_status_code=None, max_redirects=None):
|
||||
self.calls.append({
|
||||
"url": url,
|
||||
"form": dict(form or {}),
|
||||
"headers": dict(headers or {}),
|
||||
"timeout": timeout,
|
||||
"fail_on_status_code": fail_on_status_code,
|
||||
"max_redirects": max_redirects,
|
||||
})
|
||||
async def post(
|
||||
self,
|
||||
url,
|
||||
form=None,
|
||||
headers=None,
|
||||
timeout=None,
|
||||
fail_on_status_code=None,
|
||||
max_redirects=None,
|
||||
):
|
||||
self.calls.append(
|
||||
{
|
||||
"url": url,
|
||||
"form": dict(form or {}),
|
||||
"headers": dict(headers or {}),
|
||||
"timeout": timeout,
|
||||
"fail_on_status_code": fail_on_status_code,
|
||||
"max_redirects": max_redirects,
|
||||
}
|
||||
)
|
||||
return _FakeResponse()
|
||||
|
||||
class _FakeContext:
|
||||
@@ -144,39 +167,48 @@ async def test_submit_login_via_form_post_uses_browser_context_request():
|
||||
|
||||
def locator(self, selector):
|
||||
if selector == "input[type='hidden'][name]":
|
||||
return _FakeLocator([
|
||||
_FakeInput("csrf_token", "csrf-123"),
|
||||
_FakeInput("next", "/superset/welcome/"),
|
||||
])
|
||||
return _FakeLocator(
|
||||
[
|
||||
_FakeInput("csrf_token", "csrf-123"),
|
||||
_FakeInput("next", "/superset/welcome/"),
|
||||
]
|
||||
)
|
||||
return _FakeLocator([])
|
||||
|
||||
env = type("Env", (), {"username": "admin", "password": "secret"})()
|
||||
service = ScreenshotService(env=env)
|
||||
page = _FakePage()
|
||||
|
||||
result = await service._submit_login_via_form_post(page, "https://example.test/login/")
|
||||
result = await service._submit_login_via_form_post(
|
||||
page, "https://example.test/login/"
|
||||
)
|
||||
|
||||
assert result is True
|
||||
assert page.context.request.calls == [{
|
||||
"url": "https://example.test/login/",
|
||||
"form": {
|
||||
"csrf_token": "csrf-123",
|
||||
"next": "/superset/welcome/",
|
||||
"username": "admin",
|
||||
"password": "secret",
|
||||
},
|
||||
"headers": {
|
||||
"Origin": "https://example.test",
|
||||
"Referer": "https://example.test/login/",
|
||||
},
|
||||
"timeout": 10000,
|
||||
"fail_on_status_code": False,
|
||||
"max_redirects": 0,
|
||||
}]
|
||||
assert page.context.request.calls == [
|
||||
{
|
||||
"url": "https://example.test/login/",
|
||||
"form": {
|
||||
"csrf_token": "csrf-123",
|
||||
"next": "/superset/welcome/",
|
||||
"username": "admin",
|
||||
"password": "secret",
|
||||
},
|
||||
"headers": {
|
||||
"Origin": "https://example.test",
|
||||
"Referer": "https://example.test/login/",
|
||||
},
|
||||
"timeout": 10000,
|
||||
"fail_on_status_code": False,
|
||||
"max_redirects": 0,
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
# [/DEF:test_submit_login_via_form_post_uses_browser_context_request:Function]
|
||||
|
||||
|
||||
# [DEF:test_submit_login_via_form_post_accepts_authenticated_redirect:Function]
|
||||
# @RELATION: BINDS_TO ->[TestScreenshotService]
|
||||
# @PURPOSE: Fallback login must treat non-login 302 redirect as success without waiting for redirect target.
|
||||
# @PRE: Request response is 302 with Location outside login path.
|
||||
# @POST: Helper returns True.
|
||||
@@ -212,7 +244,15 @@ async def test_submit_login_via_form_post_accepts_authenticated_redirect():
|
||||
return ""
|
||||
|
||||
class _FakeRequest:
|
||||
async def post(self, url, form=None, headers=None, timeout=None, fail_on_status_code=None, max_redirects=None):
|
||||
async def post(
|
||||
self,
|
||||
url,
|
||||
form=None,
|
||||
headers=None,
|
||||
timeout=None,
|
||||
fail_on_status_code=None,
|
||||
max_redirects=None,
|
||||
):
|
||||
return _FakeResponse()
|
||||
|
||||
class _FakeContext:
|
||||
@@ -232,13 +272,18 @@ async def test_submit_login_via_form_post_accepts_authenticated_redirect():
|
||||
env = type("Env", (), {"username": "admin", "password": "secret"})()
|
||||
service = ScreenshotService(env=env)
|
||||
|
||||
result = await service._submit_login_via_form_post(_FakePage(), "https://example.test/login/")
|
||||
result = await service._submit_login_via_form_post(
|
||||
_FakePage(), "https://example.test/login/"
|
||||
)
|
||||
|
||||
assert result is True
|
||||
|
||||
|
||||
# [/DEF:test_submit_login_via_form_post_accepts_authenticated_redirect:Function]
|
||||
|
||||
|
||||
# [DEF:test_submit_login_via_form_post_rejects_login_markup_response:Function]
|
||||
# @RELATION: BINDS_TO ->[TestScreenshotService]
|
||||
# @PURPOSE: Fallback login must fail when POST response still contains login form content.
|
||||
# @PRE: Login DOM exposes csrf hidden field and request response renders login markup.
|
||||
# @POST: Helper returns False.
|
||||
@@ -282,7 +327,15 @@ async def test_submit_login_via_form_post_rejects_login_markup_response():
|
||||
"""
|
||||
|
||||
class _FakeRequest:
|
||||
async def post(self, url, form=None, headers=None, timeout=None, fail_on_status_code=None, max_redirects=None):
|
||||
async def post(
|
||||
self,
|
||||
url,
|
||||
form=None,
|
||||
headers=None,
|
||||
timeout=None,
|
||||
fail_on_status_code=None,
|
||||
max_redirects=None,
|
||||
):
|
||||
return _FakeResponse()
|
||||
|
||||
class _FakeContext:
|
||||
@@ -302,13 +355,18 @@ async def test_submit_login_via_form_post_rejects_login_markup_response():
|
||||
env = type("Env", (), {"username": "admin", "password": "secret"})()
|
||||
service = ScreenshotService(env=env)
|
||||
|
||||
result = await service._submit_login_via_form_post(_FakePage(), "https://example.test/login/")
|
||||
result = await service._submit_login_via_form_post(
|
||||
_FakePage(), "https://example.test/login/"
|
||||
)
|
||||
|
||||
assert result is False
|
||||
|
||||
|
||||
# [/DEF:test_submit_login_via_form_post_rejects_login_markup_response:Function]
|
||||
|
||||
|
||||
# [DEF:test_goto_resilient_falls_back_from_domcontentloaded_to_load:Function]
|
||||
# @RELATION: BINDS_TO ->[TestScreenshotService]
|
||||
# @PURPOSE: Pages with unstable primary wait must retry with fallback wait strategy.
|
||||
# @PRE: First page.goto call raises; second succeeds.
|
||||
# @POST: Helper returns second response and attempts both wait modes in order.
|
||||
@@ -340,5 +398,7 @@ async def test_goto_resilient_falls_back_from_domcontentloaded_to_load():
|
||||
("https://example.test/dashboard", "domcontentloaded", 1234),
|
||||
("https://example.test/dashboard", "load", 1234),
|
||||
]
|
||||
|
||||
|
||||
# [/DEF:test_goto_resilient_falls_back_from_domcontentloaded_to_load:Function]
|
||||
# [/DEF:backend.src.plugins.llm_analysis.__tests__.test_screenshot_service:Module]
|
||||
# [/DEF:TestScreenshotService:Module]
|
||||
|
||||
Reference in New Issue
Block a user