T9.4 - S7: one sample-data affordance, confirmed, and fenced off the project
Four affordances under three names became ONE: "Load sample data", on the creator's toolbar, at the far end of two separators from the live actions (New / Duplicate), pushed right with its own gap. It confirms through the T7.9 dialog, naming exactly what it does - and what it does not: "This page only: nothing is written to the project unless you then save." The probe verifies the fence the way the done-when demands - against a REAL project, reading the server's SOP and work-package list before and after and asserting byte-identical. Gone: the wizard's header "Load sample" (the dangerous one: it filled the state completeSOP() pushes to the LIVE project, one click, no confirm, no undo - reconciled with D1 exactly as the task records: the creator's control is the survivor, the wizard copy goes), the creator's split Sample SOP / Load example pair (now internals behind the one entry point), and the empty-state context bar's third button (its text now points at the toolbar control). The location/material "Load sample values" buttons stay: they fill a PASTE BOX that acts only through an explicit, dry-runnable import - a different thing, stated in the code. Probes re-pointed with reasons in place: frame_check's D1 toolbar list names the consolidated control; validation_check's sample-driven toast checks became the-affordance-is-gone checks (and its stale showAnalytics drive, orphaned by T7.10, became a the-duplicate-stays-gone check). Verification (each probe run alone): NEW tests/sample_check.py 10/10. Regressions: validation_check 77/77, frame_check 38/38, kitting_check 26/26, export_check 20/20, sections_check 95/95. Items: S7 (D1 reconciliation honored) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -231,48 +231,19 @@ def run(page, base, tok):
|
||||
".filter(e => (e.textContent||'').trim()).map(e => e.id))"))
|
||||
chk("no error is shown on a step nobody has tried to leave", not marks, marks)
|
||||
|
||||
print("\n5. the wizard opens no native dialog at all")
|
||||
print("\n5. the wizard opens no native dialog, and its sample affordance is gone")
|
||||
open_wizard(page, base, tok)
|
||||
# Drive every path that used to raise one.
|
||||
page.eval("loadSampleData()")
|
||||
settle(1.6)
|
||||
chk("loading the sample announces instead of interrupting",
|
||||
page.eval("!document.getElementById('wp-toast').hidden"))
|
||||
chk("...politely, because it is a confirmation not an error",
|
||||
page.eval("document.getElementById('wp-toast').getAttribute('role')") == "status")
|
||||
chk("...and says what happened",
|
||||
"Sample data loaded" in (page.eval(
|
||||
"(document.getElementById('wp-toast')||{}).textContent||''")),
|
||||
ascii_(page.eval("(document.getElementById('wp-toast')||{}).textContent||''")))
|
||||
chk("...and can be dismissed from the keyboard", page.eval("""(() => {
|
||||
const b = document.querySelector('#wp-toast .wp-toast-close');
|
||||
if (!b) return false;
|
||||
b.focus();
|
||||
const focused = document.activeElement === b;
|
||||
b.click();
|
||||
return focused && document.getElementById('wp-toast').hidden;
|
||||
})()"""))
|
||||
# T9.4 (S7) removed this page's Load sample - it filled the state that
|
||||
# completeSOP() pushes to the LIVE project, one click, no confirm. The
|
||||
# suite's one sample control is on the creator. What this section still
|
||||
# owns: the wizard must not regrow the affordance, and must stay dialog-free.
|
||||
chk("the wizard's Load sample control is gone (S7/T9.4)",
|
||||
page.eval("!document.getElementById('load-sample-btn')")
|
||||
and page.eval("typeof loadSampleData === 'undefined'"))
|
||||
chk("...and no native dialog fired anywhere so far",
|
||||
not json.loads(page.eval("JSON.stringify(window.__dialogs||[])")),
|
||||
page.eval("JSON.stringify(window.__dialogs||[])"))
|
||||
|
||||
# This used to be "loading the sample on the wrong tab interrupts", because the
|
||||
# wizard's Load sample was context-aware: on the WP tab it reached into the
|
||||
# iframe and called the creator's own loadExample(), and complained when the
|
||||
# frame was not there. B7/T7.1 made the creator a page, so there is no wrong
|
||||
# tab to be on and nothing to reach into - this page's sample is the SOP
|
||||
# sample, always. What is left to check is that the one remaining edge, the
|
||||
# SOP gate, still says something rather than nothing.
|
||||
page.eval("showCreatorGate(); loadSampleData()")
|
||||
settle(1.2)
|
||||
chk("from the gate, loading the sample announces rather than failing silently",
|
||||
page.eval("!document.getElementById('wp-toast').hidden"))
|
||||
chk("...politely, because being on the gate is not an error",
|
||||
page.eval("document.getElementById('wp-toast').getAttribute('role')") == "status",
|
||||
ascii_(page.eval("(document.getElementById('wp-toast')||{}).textContent||''")))
|
||||
chk("...and says where the work package sample actually is",
|
||||
"Work Package Creation" in (page.eval(
|
||||
"(document.getElementById('wp-toast')||{}).textContent||''")),
|
||||
ascii_(page.eval("(document.getElementById('wp-toast')||{}).textContent||''")))
|
||||
page.eval("switchTool('sop')")
|
||||
settle(0.6)
|
||||
|
||||
# Through the control a person uses — the modal's text input — not through the
|
||||
# library helper, which has no duplicate message to give.
|
||||
@@ -304,16 +275,12 @@ def run(page, base, tok):
|
||||
"no feedback to export" in (page.eval(
|
||||
"(document.getElementById('wp-toast')||{}).textContent||''")).lower(),
|
||||
ascii_(page.eval("(document.getElementById('wp-toast')||{}).textContent||''")))
|
||||
page.eval("showAnalytics()")
|
||||
settle(0.5)
|
||||
chk("the usage summary is shown rather than crammed into a confirmation",
|
||||
"Step 1:" in (page.eval("(document.getElementById('wp-toast')||{}).textContent||''")),
|
||||
ascii_(page.eval("(document.getElementById('wp-toast')||{}).textContent||''"))[:100])
|
||||
chk("...with the download offered as an action beside it",
|
||||
page.eval("""(() => {
|
||||
const b = document.querySelector('#wp-toast .wp-toast-action');
|
||||
return !!b && /download/i.test(b.textContent);
|
||||
})()"""))
|
||||
# showAnalytics() left this page at T7.10 (D5): the usage report lives on
|
||||
# the admin console now, one implementation for the whole suite. What this
|
||||
# section keeps: the duplicate must not regrow here.
|
||||
chk("the wizard's usage-summary duplicate is gone (D5/T7.10)",
|
||||
page.eval("typeof showAnalytics === 'undefined'")
|
||||
and page.eval("typeof analyticsLoad === 'undefined'"))
|
||||
|
||||
fired = json.loads(page.eval("JSON.stringify(window.__dialogs||[])"))
|
||||
chk("nothing anywhere in that opened alert / confirm / prompt", not fired, fired[:4])
|
||||
|
||||
Reference in New Issue
Block a user