Row clicks survive whitespace; the failure badge stops inflating
Sleeping Gods failed where three siblings passed: the second-pass row click matched captured text with Playwright's has_text regex, which tests raw textContent — tabs and newlines included — against a capture that was whitespace-normalized. Rows whose markup happened to be tidy matched; that one didn't. The picker now re-finds the row by NORMALIZED text and clicks it by index, which also survives the list re-rendering in a different order between openings. And the UI's failure count only ever grew: upload_log.csv is an append-only audit trail, so a retry that succeeds leaves its old 'failed' line in place. outstanding_failures() counts the LAST status per job key — the same rule _plan_jobs already uses to decide what to skip — so a landed retry clears the badge. On Eric's log: 6 'failed' rows, 1 job actually outstanding. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
This commit is contained in:
co-authored by
Claude Fable 5
parent
e49d1234d6
commit
6f2f2dac53
+37
-1
@@ -558,6 +558,7 @@ class _FakePicker:
|
||||
self.pages = pages
|
||||
self.page = 0
|
||||
self.clicked = None
|
||||
self.clicked_index = None
|
||||
self.cancelled = False
|
||||
self.reopened = 0
|
||||
|
||||
@@ -601,6 +602,9 @@ class _FakePicker:
|
||||
raise AssertionError("clicked a HIDDEN paging control")
|
||||
if "Next Page" in selector:
|
||||
picker.page += 1
|
||||
elif "summary-item-thumbnail" in selector:
|
||||
picker.clicked_index = self.index
|
||||
picker.clicked = picker.pages[picker.page][self.index]
|
||||
|
||||
def filter(self, has_text=None):
|
||||
picker.clicked = has_text.pattern if has_text else None
|
||||
@@ -648,7 +652,7 @@ def test_version_found_on_a_later_page():
|
||||
)
|
||||
picked, why = up._select_version(dialog, "English Gamefound edition")
|
||||
assert picked is True # the old code gave up after page one
|
||||
assert "Gamefound" in dialog.clicked # regex-escaped row text
|
||||
assert dialog.clicked_index == 0 # clicked by index, not by regex
|
||||
assert why == ""
|
||||
|
||||
|
||||
@@ -695,3 +699,35 @@ def test_paging_never_clicks_a_hidden_mobile_control():
|
||||
assert picked is True # no AssertionError from the fake = no hidden click
|
||||
# the initial open plus ONE reopen — never a "First Page" click
|
||||
assert dialog.reopened == 2
|
||||
|
||||
|
||||
def test_outstanding_failures_ignores_retried_jobs():
|
||||
"""upload_log.csv is append-only: a failure line stays forever, so the
|
||||
UI badge must count LAST status per job, not every 'failed' ever."""
|
||||
from bggpipe.upload import outstanding_failures
|
||||
|
||||
rows = [
|
||||
{
|
||||
"action": "add",
|
||||
"bgg_id": "1",
|
||||
"collid": "",
|
||||
"version_id": "",
|
||||
"status": "failed",
|
||||
},
|
||||
{
|
||||
"action": "add",
|
||||
"bgg_id": "1",
|
||||
"collid": "",
|
||||
"version_id": "",
|
||||
"status": "added",
|
||||
},
|
||||
{
|
||||
"action": "add",
|
||||
"bgg_id": "2",
|
||||
"collid": "",
|
||||
"version_id": "",
|
||||
"status": "failed",
|
||||
},
|
||||
]
|
||||
assert outstanding_failures(rows) == 1 # game 1 was retried and landed
|
||||
assert outstanding_failures([]) == 0
|
||||
|
||||
Reference in New Issue
Block a user