Updates go through the collection cell: collid- and version_id-exact
The last unverified flow failed on its guess — the collection row has no link named "own"; the edit affordances are icon anchors with no text. The site offers something far better, now verified: the row's VERSION CELL carries its own collid in an onclick, and the inline editor it opens is a radio list whose values ARE version ids. So an update addresses the copy by collid and the edition by version id — no name matching, no pagination, no dialog, and structurally incapable of creating a duplicate entry (it sets one field on one collid). Clicking the radio fires CE_SaveData itself; there is no Save button, and the save has landed when the cell stops reading "Editing". A version id the editor doesn't offer aborts with the entry untouched. The class docstring's UNVERIFIED list is now empty but for the second-copy add, which --verify already reports as a copy-count shortfall. 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
74ecd5059b
commit
0af9ae86c5
@@ -803,3 +803,61 @@ def test_failure_badge_ignores_jobs_the_human_retired():
|
||||
]
|
||||
assert outstanding_failures(log) == 2 # log-only view: both look pending
|
||||
assert outstanding_failures(log, queue, matches) == 1 # only the live one
|
||||
|
||||
|
||||
def test_update_targets_collid_and_version_id_exactly():
|
||||
"""The collection row's version cell carries its collid; the editor's
|
||||
radios carry version ids. Both are addressed by value, so neither the
|
||||
copy nor the edition can be picked by resemblance."""
|
||||
from bggpipe.upload import PlaywrightUploader, UploadJob
|
||||
|
||||
seen = {"clicked": [], "text": "Editing"}
|
||||
|
||||
class _Loc:
|
||||
def __init__(self, selector):
|
||||
self.selector = selector
|
||||
|
||||
@property
|
||||
def first(self):
|
||||
return self
|
||||
|
||||
def count(self):
|
||||
return 1
|
||||
|
||||
def wait_for(self, **kw):
|
||||
return None
|
||||
|
||||
def click(self):
|
||||
seen["clicked"].append(self.selector)
|
||||
if "radio" in self.selector:
|
||||
seen["text"] = "Avalon Hill second edition" # CE_SaveData ran
|
||||
|
||||
def text_content(self):
|
||||
return seen["text"]
|
||||
|
||||
class _Page:
|
||||
def goto(self, url, **kw):
|
||||
seen["url"] = url
|
||||
|
||||
def locator(self, selector):
|
||||
return _Loc(selector)
|
||||
|
||||
def wait_for_timeout(self, ms):
|
||||
pass
|
||||
|
||||
up = PlaywrightUploader("someone")
|
||||
up._page = _Page()
|
||||
up._authed = True
|
||||
job = UploadJob(
|
||||
action="update",
|
||||
bgg_id=240,
|
||||
name="Britannia",
|
||||
collid="53429559",
|
||||
version_id="24621",
|
||||
version_name="Avalon Hill second edition",
|
||||
)
|
||||
status, note = up.update_entry(job)
|
||||
assert status == "updated" and note == ""
|
||||
assert "objectid=240" in seen["url"]
|
||||
assert any('onclick*="53429559"' in s for s in seen["clicked"]) # the copy
|
||||
assert any('value="24621"' in s for s in seen["clicked"]) # the edition
|
||||
|
||||
Reference in New Issue
Block a user