feat: finish mobile checklists and continue Today (Closes #911)
CI / lint (pull_request) Successful in 2m1s
CI / build-release (pull_request) Successful in 6s
CI / browser-journey (pull_request) Successful in 58s
CI / release-candidate (pull_request) Has been skipped

This commit is contained in:
timmy committed 2026-08-15 19:27:54 +00:00
1 parent dbadc73a57
commit 2aad1a9bef
5 files changed
+125 -2

No files matched your search

+78
View File
@@ -2224,6 +2224,84 @@ async def test_mobile_issue_detail_toggles_checklist_with_touch_safe_recovery():
assert '.checklist-pending .task-list-toggle { opacity:.65;' in html
def test_completed_issue_checklist_offers_close_and_next_during_today():
script = f"""
const createIssueSheet = require({json.dumps(str(ISSUE_SHEET))});
const controller = createIssueSheet({{storage:null}});
const container = {{querySelectorAll:() => [{{checked:true}}, {{checked:true}}]}};
process.stdout.write(JSON.stringify(controller.checklistCompletion(container, {{
interactive:true, today:true, offline:false,
}})));
"""
output = json.loads(subprocess.run(
["node", "-e", script], check=True, capture_output=True, text=True
).stdout)
assert output == {
"visible": True,
"status": "Checklist complete",
"label": "Close & next",
}
def test_checklist_completion_stays_hidden_when_kept_open():
script = f"""
const createIssueSheet = require({json.dumps(str(ISSUE_SHEET))});
const controller = createIssueSheet({{storage:null}});
const container = {{querySelectorAll:() => [{{checked:true}}]}};
process.stdout.write(JSON.stringify(controller.checklistCompletion(container, {{
interactive:true, today:false, offline:false, dismissed:true,
}})));
"""
output = json.loads(subprocess.run(
["node", "-e", script], check=True, capture_output=True, text=True
).stdout)
assert output["visible"] is False
def test_checklist_completion_copy_matches_online_and_offline_close_modes():
script = f"""
const createIssueSheet = require({json.dumps(str(ISSUE_SHEET))});
const controller = createIssueSheet({{storage:null}});
const container = {{querySelectorAll:() => [{{checked:true}}]}};
process.stdout.write(JSON.stringify({{
outside:controller.checklistCompletion(container, {{interactive:true,today:false,offline:false}}),
offlineToday:controller.checklistCompletion(container, {{interactive:true,today:true,offline:true}}),
offlineOutside:controller.checklistCompletion(container, {{interactive:true,today:false,offline:true}}),
}}));
"""
output = json.loads(subprocess.run(
["node", "-e", script], check=True, capture_output=True, text=True
).stdout)
assert output["outside"]["label"] == "Close issue"
assert output["offlineToday"] == {
"visible": True,
"status": "Checklist complete · pending sync",
"label": "Queue close & next",
}
assert output["offlineOutside"]["label"] == "Queue issue closure"
@pytest.mark.anyio
async def test_mobile_checklist_completion_bar_reuses_confirmed_close_flow():
html = await dashboard()
assert 'id="checklist-completion"' in html
assert 'id="checklist-completion-status" role="status"' in html
assert 'id="complete-checklist-issue"' in html
assert 'id="keep-checklist-issue-open"' in html
assert "function renderChecklistCompletion(detail)" in html
assert "issueController.checklistCompletion(qs('#issue-sheet-body')" in html
assert "qs('#complete-checklist-issue').addEventListener('click', () =>" in html
assert "qs('#close-issue').click()" in html
assert "dismissedChecklistBody = selectedIssueDetail?.body" in html
assert ".checklist-completion { position:fixed;" in html
assert ".checklist-completion button { min-height:44px;" in html
assert "padding-bottom:calc(118px + env(safe-area-inset-bottom))" in html
def test_offline_issue_checklist_toggle_waits_for_durable_admission_and_returns_pending_detail():
script = f"""
const createIssueSheet = require({json.dumps(str(ISSUE_SHEET))});