feat(masters): add direct masters archive (#633) - #645
Conversation
Live recon (issue #633) confirmed Мастер кампаний has no separate "delete" action in Yandex's UI — neither the campaigns grid's row menu nor the overview page's own menu has "Удалить", only "Архивировать". archive_master clicks the overview page's "⋮" menu then the archive item, using confirmed-live data-testid selectors (CampaignHeader.MenuTrigger/CampaignHeader.Menu.archive) rather than text-matched candidates, and verifies success via the campaigns grid's primaryStatus before reporting the mutation as done. Idempotent, and irreversible from this CLI (no masters unarchive) — classified DANGEROUS in smoke_matrix.py like suspend/resume. Closes #633 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QvEdRCGSbLnCgtkypCXd5X
Codex review of PR #645 found that `masters archive`'s per-ID loop was a fail-fast list comprehension: if campaign N raised, `results` was never assigned and format_output never ran, so already-archived (and irreversible -- no `masters unarchive`) earlier IDs were silently dropped from the report, leaving only the last error visible. _archive_all now archives every ID in a loop, catching BrowserSessionError/PlaywrightError per ID and recording either the archived row or the error, then reports all outcomes before raising a ClickException if any ID failed -- never losing the audit trail of what was actually mutated in production. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QvEdRCGSbLnCgtkypCXd5X
🔍 Local review (cycle 1)Reviewed locally (
FIX applied in a11d4ee: SKIP rationale: confirmed this is a documented architectural constraint, not a bug — there is no confirmed status-text marker for "archived" on the overview page (unlike suspend/resume's "Кампания остановлена"/"активна"), so |
📋 Review summary — all cycles
Totals: 1 FIX (resolved), 1 SKIP (architectural), 0 UNVERIFIED. Local review cycle complete (2 rounds: |
Summary
direct masters archive <ids>— the closest thing to "delete" Мастер кампаний has.claude-in-chromeagainst a real account that Yandex's UI has no separate delete action for Мастер кампаний — neither the campaigns grid's row menu (Перейти/Редактировать/Статистика/Запустить-Остановить/Архивировать) nor the overview page's own "⋮" menu (Клонировать/Архивировать) has a "Удалить" item.archive_masterclicks the overview page's "⋮" menu then the "Архивировать" item, using confirmed-livedata-testidselectors (CampaignHeader.MenuTrigger/CampaignHeader.Menu.archive) rather than text-matched candidates likesuspend/resumeuse — these were read directly off the live DOM, not guessed.fetch_masters_list) and confirmingStatus == "ARCHIVED", rather than trusting the click alone — mirrors thesuspend/resume"click + verify" convention from direct masters suspend/resume — остановка и возобновление Мастера кампаний #630.masters unarchive. ClassifiedDANGEROUSinsmoke_matrix.py, same category assuspend/resume(no API ⇒ no--sandboxisolation).Closes #633
Test plan
pytest -q— 2672 passed, 0 failed (62 pre-existing cassette-fixture errors unrelated to this change, confirmed present onmaintoo)pytest tests/test_masters.py -n0— 101 passed (newTestArchiveMaster/TestMastersArchiveCommandclasses: click+verify, idempotency, not-found, menu-trigger-missing, archive-item-missing, status-never-changes)black --check/flake8clean on all changed filesclaude-in-chrome) — no live mutation was exercised;masters archiveitself is untested against a real account (no disposable test campaign yet, see direct masters add — создание Мастера кампаний #632 dependency noted in the original issue)