@bongos/core 1.21.114 → 1.21.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.bongos-core.json +20 -20
- package/docs/copy-inventory.md +370 -368
- package/docs/copy-registry.json +459 -441
- package/docs/module-api-changelog.md +2 -0
- package/docs/page-readings.json +496 -928
- package/modules/public-landing/public/projects-hall-live.states.json +0 -5
- package/modules/public-landing/public/projects.html +167 -4
- package/modules/public-landing/public/projects.probes.json +4 -4
- package/modules/public-landing/public/projects.states.json +13 -13
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +6 -0
- package/src/module-api.js +1 -1
- package/tests/projects_hub_pre_uat.mjs +4 -2
- package/tests/wizard_physics.mjs +1 -1
- package/tests/wizard_physics_more.mjs +133 -0
|
@@ -127,6 +127,17 @@ h1[tabindex="-1"]:focus:not(:focus-visible){outline:none;}
|
|
|
127
127
|
.physRow2 select:focus{border-bottom-color:var(--ink);}
|
|
128
128
|
.physRow2 select option{background:var(--bg);color:var(--ink);}
|
|
129
129
|
.physRow2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0 16px;}
|
|
130
|
+
/* "Where are you?" searchable (task 1004671): the page's own field, the list a card
|
|
131
|
+
under it, inside the field's width so a phone never scrolls sideways */
|
|
132
|
+
.cbox{position:relative;}
|
|
133
|
+
.cbox::after{content:"";position:absolute;right:18px;top:19px;width:7px;height:7px;border-right:1.5px solid var(--ink-soft);border-bottom:1.5px solid var(--ink-soft);transform:rotate(45deg);pointer-events:none;}
|
|
134
|
+
#view-new .part .cbox input[type=text]{padding-right:40px;text-overflow:ellipsis;}
|
|
135
|
+
.cboxList{position:absolute;left:0;right:0;top:calc(100% + 6px);z-index:6;margin:0;padding:6px;list-style:none;max-height:min(264px,46vh);overflow-y:auto;overscroll-behavior:contain;border-radius:14px;border:1px solid color-mix(in srgb,var(--ink) 40%,transparent);background:var(--bg-card);}
|
|
136
|
+
.cboxList li{display:flex;align-items:center;gap:12px;min-height:44px;padding:8px 12px;border-radius:10px;font-size:16px;line-height:1.3;color:var(--ink);cursor:pointer;overflow-wrap:anywhere;}
|
|
137
|
+
.cboxList li[data-cur]::after{content:"✓";margin-left:auto;color:var(--ink-soft);}
|
|
138
|
+
.cboxList li[aria-disabled="true"]{cursor:default;color:var(--ink-soft);}
|
|
139
|
+
@media (hover:hover){ .cboxList li[data-code]:hover{background:color-mix(in srgb,var(--ink) 8%,transparent);} }
|
|
140
|
+
.cboxList li[data-code][aria-selected="true"]{background:color-mix(in srgb,var(--accent) 24%,transparent);}
|
|
130
141
|
.physNote{margin:6px 0 14px;padding:14px 0 0;border-top:1px solid var(--rule);max-width:62ch;}
|
|
131
142
|
.physNoteH{font-size:15px;color:var(--ink);margin:0 0 8px;}
|
|
132
143
|
.physTiers{display:grid;grid-template-columns:120px minmax(0,1fr);gap:8px 16px;margin:0 0 10px;font-size:14.5px;line-height:1.45;}
|
|
@@ -1610,7 +1621,16 @@ summary{min-height:24px;padding:3px 0;}
|
|
|
1610
1621
|
<div class="checks" id="checksMain">
|
|
1611
1622
|
<p class="checksHead">A few quick checks. They decide which legal and payout options we can offer.</p>
|
|
1612
1623
|
<div class="physRow2">
|
|
1613
|
-
|
|
1624
|
+
<!-- a searchable list (task 1004671): the select is the one value the page
|
|
1625
|
+
reads, and what a browser without script shows; the script hides it
|
|
1626
|
+
and puts the combobox in front of it -->
|
|
1627
|
+
<div class="wizField" id="physCountryField"><span id="physCountryLbl">Where are you?</span>
|
|
1628
|
+
<select id="physCountry" aria-labelledby="physCountryLbl"><option value="">Choose…</option></select>
|
|
1629
|
+
<div class="cbox" id="physCountryBox" hidden>
|
|
1630
|
+
<input type="text" id="physCountryIn" role="combobox" aria-labelledby="physCountryLbl" aria-autocomplete="list" aria-expanded="false" aria-controls="physCountryList" autocomplete="off" autocapitalize="off" spellcheck="false" placeholder="Type a country">
|
|
1631
|
+
<ul class="cboxList" id="physCountryList" role="listbox" aria-labelledby="physCountryLbl" hidden><li id="physCountryNone" role="option" aria-disabled="true" aria-selected="false" hidden>No country matches that</li></ul>
|
|
1632
|
+
</div>
|
|
1633
|
+
</div>
|
|
1614
1634
|
<label class="wizField" id="physRegionField" hidden><span>State or province</span><select id="physRegion"><option value="">Choose…</option></select></label>
|
|
1615
1635
|
</div>
|
|
1616
1636
|
<div class="wizField"><span id="physAgeLbl">Will anyone under 18 build?</span>
|
|
@@ -5803,6 +5823,9 @@ summary{min-height:24px;padding:3px 0;}
|
|
|
5803
5823
|
var a = phys().answers;
|
|
5804
5824
|
if (!a.project_state) a.project_state = 'new';
|
|
5805
5825
|
if (!a.framing) a.framing = 'managed';
|
|
5826
|
+
/* where the founder is starts at the United States (task 1004671); a country
|
|
5827
|
+
taken back (null) stays taken back, and the last project's answers still win */
|
|
5828
|
+
if (a.home_country === undefined) a.home_country = 'US';
|
|
5806
5829
|
if (!Number.isInteger(a.builders_at_start)) { a.builders_at_start = 1; a.builders_expected = 1; }
|
|
5807
5830
|
if (physSolo()) state.teamShape = 'solo';
|
|
5808
5831
|
else if (!state.teamShape || state.teamShape === 'solo') state.teamShape = 'small-team';
|
|
@@ -5827,7 +5850,146 @@ summary{min-height:24px;padding:3px 0;}
|
|
|
5827
5850
|
});
|
|
5828
5851
|
$('physRegionField').hidden = r.options.length === 1;
|
|
5829
5852
|
r.value = a.home_region || '';
|
|
5853
|
+
cboxPaint();
|
|
5854
|
+
}
|
|
5855
|
+
|
|
5856
|
+
/* "Where are you?" as a searchable list (task 1004671). The select stays the one
|
|
5857
|
+
value everything reads — its change handler, the region, the screen, the draft,
|
|
5858
|
+
the fill from a last project — and the no-script fallback; the combobox only
|
|
5859
|
+
picks for it, from the select's own options (the PHYS_COUNTRIES copy, named by
|
|
5860
|
+
Intl). Matching ignores case and accents; every option is built from nodes. */
|
|
5861
|
+
var cboxItems = [], cboxShown = [], cboxActive = -1;
|
|
5862
|
+
var CBOX_ALSO = { US: 'usa', GB: 'uk' };
|
|
5863
|
+
function cboxFold(s) { return String(s || '').normalize('NFD').replace(/\p{M}/gu, '').toLowerCase().trim(); }
|
|
5864
|
+
function cboxBuild() {
|
|
5865
|
+
if (cboxItems.length) return;
|
|
5866
|
+
var sel = $('physCountry'), list = $('physCountryList');
|
|
5867
|
+
for (var i = 0; i < sel.options.length; i += 1) {
|
|
5868
|
+
var o = sel.options[i];
|
|
5869
|
+
if (!o || !o.value) continue;
|
|
5870
|
+
var li = document.createElement('li');
|
|
5871
|
+
li.setAttribute('id', 'physCountryOpt-' + o.value);
|
|
5872
|
+
li.setAttribute('role', 'option');
|
|
5873
|
+
li.setAttribute('aria-selected', 'false');
|
|
5874
|
+
li.setAttribute('data-code', o.value);
|
|
5875
|
+
li.textContent = o.textContent;
|
|
5876
|
+
list.appendChild(li);
|
|
5877
|
+
cboxItems.push({ code: o.value, name: o.textContent, fold: cboxFold(o.textContent), also: CBOX_ALSO[o.value] || '', li: li });
|
|
5878
|
+
}
|
|
5830
5879
|
}
|
|
5880
|
+
/* the code itself first, then names that start with the words typed, then a word
|
|
5881
|
+
inside a name, then anywhere; ties keep the alphabet */
|
|
5882
|
+
function cboxMatches(q) {
|
|
5883
|
+
var f = cboxFold(q);
|
|
5884
|
+
if (!f) return cboxItems.slice();
|
|
5885
|
+
var ranked = [];
|
|
5886
|
+
cboxItems.forEach(function (it) {
|
|
5887
|
+
var at = it.fold.indexOf(f);
|
|
5888
|
+
var rank = it.code.toLowerCase() === f || it.also === f ? 0 : at === 0 ? 1 : at > 0 && it.fold.charAt(at - 1) === ' ' ? 2 : at > 0 ? 3 : -1;
|
|
5889
|
+
if (rank !== -1) ranked.push({ it: it, rank: rank });
|
|
5890
|
+
});
|
|
5891
|
+
ranked.sort(function (x, y) { return x.rank - y.rank; });
|
|
5892
|
+
return ranked.map(function (r) { return r.it; });
|
|
5893
|
+
}
|
|
5894
|
+
function cboxSetActive(i) {
|
|
5895
|
+
var input = $('physCountryIn'), list = $('physCountryList');
|
|
5896
|
+
cboxActive = i >= 0 && i < cboxShown.length ? i : -1;
|
|
5897
|
+
cboxShown.forEach(function (it, j) { it.li.setAttribute('aria-selected', String(j === cboxActive)); });
|
|
5898
|
+
if (cboxActive === -1) { input.removeAttribute('aria-activedescendant'); return; }
|
|
5899
|
+
var li = cboxShown[cboxActive].li;
|
|
5900
|
+
input.setAttribute('aria-activedescendant', 'physCountryOpt-' + cboxShown[cboxActive].code);
|
|
5901
|
+
if (li.offsetTop < list.scrollTop) list.scrollTop = li.offsetTop;
|
|
5902
|
+
else if (li.offsetTop + li.offsetHeight > list.scrollTop + list.clientHeight) list.scrollTop = li.offsetTop + li.offsetHeight - list.clientHeight;
|
|
5903
|
+
}
|
|
5904
|
+
/* q empty: the whole list, on the country already chosen */
|
|
5905
|
+
function cboxOpen(q) {
|
|
5906
|
+
cboxBuild();
|
|
5907
|
+
var list = $('physCountryList'), cur = phys().answers.home_country || '';
|
|
5908
|
+
var items = cboxMatches(q);
|
|
5909
|
+
cboxItems.forEach(function (it) { it.li.hidden = true; it.li.removeAttribute('data-cur'); it.li.setAttribute('aria-selected', 'false'); });
|
|
5910
|
+
items.forEach(function (it) {
|
|
5911
|
+
it.li.hidden = false;
|
|
5912
|
+
if (it.code === cur) it.li.setAttribute('data-cur', '');
|
|
5913
|
+
list.removeChild(it.li); list.appendChild(it.li);
|
|
5914
|
+
});
|
|
5915
|
+
$('physCountryNone').hidden = items.length > 0;
|
|
5916
|
+
cboxShown = items;
|
|
5917
|
+
list.hidden = false;
|
|
5918
|
+
$('physCountryIn').setAttribute('aria-expanded', 'true');
|
|
5919
|
+
var at = -1;
|
|
5920
|
+
if (q) at = items.length ? 0 : -1;
|
|
5921
|
+
else items.forEach(function (it, j) { if (it.code === cur) at = j; });
|
|
5922
|
+
if (!q) list.scrollTop = 0;
|
|
5923
|
+
cboxSetActive(at);
|
|
5924
|
+
}
|
|
5925
|
+
function cboxClose() {
|
|
5926
|
+
$('physCountryList').hidden = true;
|
|
5927
|
+
$('physCountryIn').setAttribute('aria-expanded', 'false');
|
|
5928
|
+
$('physCountryIn').removeAttribute('aria-activedescendant');
|
|
5929
|
+
cboxActive = -1;
|
|
5930
|
+
}
|
|
5931
|
+
function cboxIsOpen() { return !$('physCountryList').hidden; }
|
|
5932
|
+
/* the field says the chosen country's name, never what was half typed */
|
|
5933
|
+
function cboxPaint() {
|
|
5934
|
+
var code = phys().answers.home_country || '', name = '';
|
|
5935
|
+
if (code) {
|
|
5936
|
+
cboxBuild();
|
|
5937
|
+
cboxItems.forEach(function (it) { if (it.code === code) name = it.name; });
|
|
5938
|
+
}
|
|
5939
|
+
$('physCountryIn').value = name || (code ? physCountryName(code) : '');
|
|
5940
|
+
}
|
|
5941
|
+
function cboxPick(it) {
|
|
5942
|
+
cboxClose();
|
|
5943
|
+
$('physCountry').value = it.code;
|
|
5944
|
+
physCountryChanged();
|
|
5945
|
+
cboxPaint();
|
|
5946
|
+
}
|
|
5947
|
+
$('physCountry').hidden = true;
|
|
5948
|
+
$('physCountryBox').hidden = false;
|
|
5949
|
+
$('physCountryIn').addEventListener('input', function () { cboxOpen($('physCountryIn').value); });
|
|
5950
|
+
$('physCountryIn').addEventListener('focus', function () { if ($('physCountryIn').select) $('physCountryIn').select(); });
|
|
5951
|
+
$('physCountryIn').addEventListener('click', function () {
|
|
5952
|
+
if (cboxIsOpen()) return;
|
|
5953
|
+
if ($('physCountryIn').select) $('physCountryIn').select();
|
|
5954
|
+
cboxOpen('');
|
|
5955
|
+
});
|
|
5956
|
+
$('physCountryIn').addEventListener('keydown', function (ev) {
|
|
5957
|
+
var k = ev.key, open = cboxIsOpen();
|
|
5958
|
+
if (k === 'ArrowDown' || k === 'ArrowUp') {
|
|
5959
|
+
ev.preventDefault();
|
|
5960
|
+
if (!open) { cboxOpen(''); return; }
|
|
5961
|
+
if (!cboxShown.length) return;
|
|
5962
|
+
if (k === 'ArrowDown') cboxSetActive(cboxActive === -1 ? 0 : Math.min(cboxActive + 1, cboxShown.length - 1));
|
|
5963
|
+
else cboxSetActive(cboxActive === -1 ? cboxShown.length - 1 : Math.max(cboxActive - 1, 0));
|
|
5964
|
+
} else if (k === 'Enter') {
|
|
5965
|
+
if (!open) return;
|
|
5966
|
+
ev.preventDefault();
|
|
5967
|
+
if (cboxActive !== -1) cboxPick(cboxShown[cboxActive]);
|
|
5968
|
+
} else if (k === 'Escape') {
|
|
5969
|
+
if (!open) return;
|
|
5970
|
+
ev.preventDefault();
|
|
5971
|
+
if (ev.stopPropagation) ev.stopPropagation();
|
|
5972
|
+
cboxClose();
|
|
5973
|
+
cboxPaint();
|
|
5974
|
+
}
|
|
5975
|
+
});
|
|
5976
|
+
/* leaving the field keeps the chosen country, unless a whole name was typed */
|
|
5977
|
+
$('physCountryIn').addEventListener('blur', function () {
|
|
5978
|
+
if (!cboxIsOpen()) { cboxPaint(); return; }
|
|
5979
|
+
var f = cboxFold($('physCountryIn').value), exact = null;
|
|
5980
|
+
cboxItems.forEach(function (it) { if (f && (it.fold === f || it.code.toLowerCase() === f)) exact = it; });
|
|
5981
|
+
cboxClose();
|
|
5982
|
+
if (exact && exact.code !== (phys().answers.home_country || '')) cboxPick(exact);
|
|
5983
|
+
else cboxPaint();
|
|
5984
|
+
});
|
|
5985
|
+
/* a press on an option keeps the focus in the field; the click picks */
|
|
5986
|
+
$('physCountryList').addEventListener('mousedown', function (ev) { ev.preventDefault(); });
|
|
5987
|
+
$('physCountryList').addEventListener('click', function (ev) {
|
|
5988
|
+
var li = ev.target && ev.target.closest ? ev.target.closest('[data-code]') : null;
|
|
5989
|
+
if (!li) return;
|
|
5990
|
+
var code = li.getAttribute('data-code');
|
|
5991
|
+
cboxItems.forEach(function (it) { if (it.code === code) cboxPick(it); });
|
|
5992
|
+
});
|
|
5831
5993
|
|
|
5832
5994
|
/* The soft-limit table's verdicts (spec D6): an option it hides is hidden and
|
|
5833
5995
|
one it greys is disabled, each with its reason beside it. */
|
|
@@ -5976,7 +6138,7 @@ summary{min-height:24px;padding:3px 0;}
|
|
|
5976
6138
|
$('physStartOver').addEventListener('click', function () {
|
|
5977
6139
|
checksShow('main');
|
|
5978
6140
|
paintChecks();
|
|
5979
|
-
$('
|
|
6141
|
+
$('physCountryIn').focus();
|
|
5980
6142
|
});
|
|
5981
6143
|
root.querySelectorAll('#view-new [data-phys]').forEach(function (b) {
|
|
5982
6144
|
b.addEventListener('click', function () {
|
|
@@ -6058,12 +6220,13 @@ summary{min-height:24px;padding:3px 0;}
|
|
|
6058
6220
|
root.querySelectorAll('#physExisting input[name="physMain"]').forEach(function (r) {
|
|
6059
6221
|
r.addEventListener('change', function () { if (r.checked) { phys().answers.main_work = r.value; saveDraft(); paintSetup(); } });
|
|
6060
6222
|
});
|
|
6061
|
-
|
|
6223
|
+
function physCountryChanged() {
|
|
6062
6224
|
var a = phys().answers;
|
|
6063
6225
|
a.home_country = $('physCountry').value || null;
|
|
6064
6226
|
if (a.home_region && a.home_region.indexOf((a.home_country || '') + '-') !== 0) a.home_region = null;
|
|
6065
6227
|
physHint(''); saveDraft(); paintChecks(); paintCreate(); physRecheck();
|
|
6066
|
-
}
|
|
6228
|
+
}
|
|
6229
|
+
$('physCountry').addEventListener('change', physCountryChanged);
|
|
6067
6230
|
$('physRegion').addEventListener('change', function () { phys().answers.home_region = $('physRegion').value || null; saveDraft(); });
|
|
6068
6231
|
$('physHaveEntity').addEventListener('click', function () { phys().entityForms = true; saveDraft(); paintChecks(); });
|
|
6069
6232
|
$('physNoEntity').addEventListener('click', function () {
|
|
@@ -166,16 +166,16 @@
|
|
|
166
166
|
"steps": [["wait",600],["click","#wizDemo"],["wait",300],["click","#demoCancel"],["wait",300],["fill","#newName","Mercury"],["wait",100]],
|
|
167
167
|
"expect": {"visible":["#part-project","#part-run","#doCreate"],"hidden":["#demoSetup","#demoTag"],"attr":[["#wizDemo","aria-expanded","false"],["#doCreate","disabled",""]],"text":[["#createWhy","Tick the terms to create your project."]]} },
|
|
168
168
|
{ "name": "the quick checks (task 1004648): a country with states asks for one, a yes to under-18s shows the age tiers, and an existing entity opens the full list — in place, in part 01", "auth": true, "width": 1440, "url": "/projects?view=new",
|
|
169
|
-
"steps": [["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
169
|
+
"steps": [["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["select","#physRegion","US-CA"],["click","[data-phys=\"builder_geography\"][data-val=\"us-eu\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"true\"]"],["wait",200],["click","#physHaveEntity"],["wait",100],["click","[data-phys=\"entity\"][data-val=\"for-profit\"]"],["wait",300]],
|
|
170
170
|
"expect": {"visible":["#physRegionField","#physAges","#physForms","#part-run"],"hidden":["#physIntent","#checksStop"]} },
|
|
171
171
|
{ "name": "part 02 (task 1004648): Change opens a row in place and reads Done, opening another closes it, and nothing needs confirming", "auth": true, "width": 1440, "url": "/projects?view=new",
|
|
172
|
-
"steps": [["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
172
|
+
"steps": [["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"team\"] [data-row-chg]"],["wait",200],["click","[data-phys-solo=\"many\"]"],["wait",600],["click","#reviewRows .setRow[data-row=\"run\"] [data-row-chg]"],["wait",300]],
|
|
173
173
|
"expect": {"visible":["#reviewRows .setRow[data-row=\"rewards\"]","#reviewRows .setRow.open[data-row=\"run\"] .opts"],"hidden":["#reviewRows .setRow[data-row=\"team\"] .opts"],"text":[["#reviewRows .setRow[data-row=\"run\"] [data-row-chg]","Done"],["#reviewRows .setRow[data-row=\"team\"] [data-row-chg]","Change"]]} },
|
|
174
174
|
{ "name": "the wizard driver (task 1004648): part 01, the checks, the address row (the dotless stub host takes a domain the founder owns), the tick, then Create — part 03 goes live as Getting <name> ready: one sentence, the checked facts, and the cloud hop behind its link", "auth": true, "width": 1440, "url": "/projects?view=new",
|
|
175
|
-
"steps": [["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
175
|
+
"steps": [["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",200],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",200],["click","#termsAck"],["wait",100],["click","#doCreate"],["wait",1500]],
|
|
176
176
|
"expect": {"visible":["#panel-done","#setupNow","#homeFacts","#ghFacts","#hopLink"],"hidden":["#wizParts","#hop","#doneAlive"],"text":[["#donePartT","Getting Mercury ready"]]} },
|
|
177
177
|
{ "name": "the wizard driver at 320 (narrower than a 375 phone): the page stacks, nothing scrolls sideways, and the walk still reaches part 03", "auth": true, "width": 320, "url": "/projects?view=new",
|
|
178
|
-
"steps": [["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
178
|
+
"steps": [["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",200],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",200],["click","#termsAck"],["wait",100],["click","#doCreate"],["wait",1500]],
|
|
179
179
|
"expect": {"noOverflow":true,"visible":["#panel-done","#homeFacts","#ghFacts"],"hidden":["#wizParts"]} },
|
|
180
180
|
{ "name": "invite a guild (task 1002303, R27): a /g/ address gives one pending line per member on its public page, each a link to the hall", "auth": true, "width": 1440, "url": "/projects?view=manage&id=101",
|
|
181
181
|
"steps": [["wait",900],["fill","#mInviteGuild","/g/forge-crew"],["click","#mInvite [data-invite-guild]"],["wait",400]],
|
|
@@ -43,21 +43,21 @@
|
|
|
43
43
|
"in-new-name-prefilled": {"auth":true,"url":"/projects?view=new&name=Mercury","actions":[["wait",600]],"expect":{"visible":["#panel-page","#newName"]}},
|
|
44
44
|
"in-new-demo": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["click","#wizDemo"],["wait",300]],"expect":{"visible":["#panel-page","#demoSetup","#demoFitVerdict","#demoInvites","#demoStart","#demoCancel"],"attr":[["#wizDemo","aria-expanded","true"]]}},
|
|
45
45
|
"in-new-demo-used": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["click","#wizDemo"],["wait",300],["fill","#demoIdea","A voting app for movie night"],["click","#demoStart"],["wait",400]],"expect":{"visible":["#demoTag","#newName","#part-run"],"hidden":["#demoSetup","#checksMain"],"text":[["#wizEyebrow","New demo"]]}},
|
|
46
|
-
"in-new-checks-filled": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
46
|
+
"in-new-checks-filled": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["select","#physRegion","US-CA"],["click","[data-phys=\"builder_geography\"][data-val=\"us-eu\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"true\"]"],["wait",300]],"expect":{"visible":["#physRegionField","#physAges"],"hidden":["#checksStop"]}},
|
|
47
47
|
"in-new-checks-entity": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#physHaveEntity"],["wait",200],["click","[data-phys=\"entity\"][data-val=\"for-profit\"]"],["wait",100]],"expect":{"visible":["#physForms","#physNoEntity"],"hidden":["#physIntent"]}},
|
|
48
|
-
"in-new-row-code": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
49
|
-
"in-new-row-address": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
50
|
-
"in-new-row-team": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
51
|
-
"in-new-row-extras": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
52
|
-
"in-new-row-rewards": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
53
|
-
"in-new-row-app": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
54
|
-
"in-new-row-run": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
55
|
-
"in-new-row-ship": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
56
|
-
"in-new-look": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
57
|
-
"in-new-look-custom": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
48
|
+
"in-new-row-code": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"code\"] [data-row-chg]"],["wait",400]],"expect":{"visible":["#reviewRows .setRow.open[data-row=\"code\"] .opts","#c-green","#c-adopt"]}},
|
|
49
|
+
"in-new-row-address": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",400]],"expect":{"visible":["#reviewRows .setRow.open[data-row=\"address\"] .opts","#f-slug","#addrConfirm","#f-noaddr"]}},
|
|
50
|
+
"in-new-row-team": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"team\"] [data-row-chg]"],["wait",400],["click","[data-phys-solo=\"many\"]"],["wait",400]],"expect":{"visible":["#reviewRows .setRow.open[data-row=\"team\"] .opts","[data-phys-solo=\"many\"]"]}},
|
|
51
|
+
"in-new-row-extras": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"extras\"] [data-row-chg]"],["wait",400]],"expect":{"visible":["#reviewRows .setRow.open[data-row=\"extras\"] .opts","#modCards"]}},
|
|
52
|
+
"in-new-row-rewards": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"team\"] [data-row-chg]"],["wait",200],["click","[data-phys-solo=\"many\"]"],["wait",600],["click","#reviewRows .setRow[data-row=\"rewards\"] [data-row-chg]"],["wait",400]],"expect":{"visible":["#reviewRows .setRow.open[data-row=\"rewards\"] .opts","[data-phys=\"reward_intents\"][data-val=\"cash\"]"]}},
|
|
53
|
+
"in-new-row-app": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"app\"] [data-row-chg]"],["wait",400]],"expect":{"visible":["#reviewRows .setRow.open[data-row=\"app\"] .opts","#appOpts"]}},
|
|
54
|
+
"in-new-row-run": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"run\"] [data-row-chg]"],["wait",400],["click","[data-phys=\"framing\"][data-val=\"hybrid\"]"],["wait",400]],"expect":{"visible":["#reviewRows .setRow.open[data-row=\"run\"] .opts","#physSuite"]}},
|
|
55
|
+
"in-new-row-ship": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"ship\"] [data-row-chg]"],["wait",400]],"expect":{"visible":["#reviewRows .setRow.open[data-row=\"ship\"] .opts","#shipOpts"]}},
|
|
56
|
+
"in-new-look": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"look\"] [data-row-chg]"],["wait",400]],"expect":{"visible":["#reviewRows .setRow.open[data-row=\"look\"] .opts","#wizLook"]}},
|
|
57
|
+
"in-new-look-custom": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"look\"] [data-row-chg]"],["wait",400],["click","#wizLook-custom"],["wait",200]],"expect":{"visible":["#reviewRows .setRow.open[data-row=\"look\"] .opts","#wizLook","#wizAccent","#wizAccentNote"]}},
|
|
58
58
|
"in-new-create-blocked": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["click","#termsAck"],["wait",100],["click","#doCreate"],["wait",400]],"expect":{"visible":["#reviewRows .setRow.open[data-row=\"address\"] .opts","#h-domain"],"hidden":["#doneBody"],"text":[["#createWhy","Fix the row that’s open, then create."]]}},
|
|
59
|
-
"in-new-done": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
60
|
-
"in-new-resume-offer": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["
|
|
59
|
+
"in-new-done": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",200],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",200],["click","#termsAck"],["wait",100],["click","#doCreate"],["wait",1500]],"expect":{"visible":["#panel-done","#doneBody","#setupNow","#homeFacts","#ghFacts","#hopLink","#wizRecap"],"hidden":["#wizParts","#qWrap","#wizInvite","#hop","#doneAlive"],"attr":[["#doCreate","disabled",""],["#wizRoom","data-screen","done"]],"text":[["#donePartT","Getting Mercury ready"],["#doCreate","Created"]]}},
|
|
60
|
+
"in-new-resume-offer": {"auth":true,"url":"/projects?view=new","actions":[["wait",600],["fill","#newName","Mercury"],["click","#typeCards .tpill[data-type=\"game\"]"],["fill","#f-desc","A co-op farming game where the seasons never repeat."],["wait",100],["click","[data-phys=\"builder_geography\"][data-val=\"global\"]"],["click","[data-phys=\"minors_on_board\"][data-val=\"false\"]"],["click","[data-phys=\"entity\"][data-val=\"intent-solo\"]"],["wait",300],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",200],["fill","#f-slug","mercury"],["wait",900],["fill","#f-domain","mercury.example.com"],["wait",200],["click","#reviewRows .setRow[data-row=\"address\"] [data-row-chg]"],["wait",200],["click","#termsAck"],["wait",100],["click","#doCreate"],["wait",1500],["click","#projTrig"],["wait",350],["click","#menuProjects [data-nav=\"new\"]"],["wait",500]],"expect":{"visible":["#panel-page","#wizResume","#wizResumeGo","#wizParts"],"hidden":["#doneBody"],"text":[["#wizResumeName","Mercury"]]}},
|
|
61
61
|
"out-new": {"auth":false,"url":"/projects?view=new","expect":{"visible":["#panel-gate","#wizSignin"],"hidden":["#qWrap","#panel-page"]}},
|
|
62
62
|
"out-map-projects": { "auth": false, "actions": [["click", "#projTrig"], ["wait", 350]], "expect": { "expanded": true, "hidden": ["#menuProjects [data-nav=\"mine\"]"] } },
|
|
63
63
|
"card": { "auth": true, "actions": [["dispatchClick", "#orbField a.worldOrb[data-origin=\"https://example.com\"]"], ["wait", 900]], "expect": { "dialog": true, "hasClass": [["#projCard", "has-art"]], "visible": ["#cardArt", "#cardFaces", "#cardBuildersFig", "#cardShippedFig", "#cardOpen", "#cardHall"], "text": [["#cardBuilders", "11"], ["#cardShipped", "0"], ["#cardRel", "you build here"], ["#cardRuns", "example.com"], ["#cardFaces .facesMore", "+6"]], "count": [["#cardFaces img", 5]], "href": [["#cardHall", "https://builders.example.com/"]] } },
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.21.
|
|
3
|
+
"version": "1.21.115",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.21.
|
|
9
|
+
"version": "1.21.115",
|
|
10
10
|
"license": "AGPL-3.0-or-later",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"express": "^4.21.2",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.21.
|
|
3
|
+
"version": "1.21.115",
|
|
4
4
|
"description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"main": "src/platform-server.js",
|
package/release-notes.json
CHANGED
|
@@ -9658,5 +9658,11 @@
|
|
|
9658
9658
|
"id": "1004701",
|
|
9659
9659
|
"text": "The living city is now the hall's base: the city, the street with depth, the decision deck, the government inside each building, and My agents. On a real project it shows only what the real data supports: no invented Leads, la"
|
|
9660
9660
|
}
|
|
9661
|
+
],
|
|
9662
|
+
"1.21.115": [
|
|
9663
|
+
{
|
|
9664
|
+
"id": "1004671",
|
|
9665
|
+
"text": "When you start a new project, \"Where are you?\" now starts on United States and is a search box instead of a long dropdown. Type a few letters and the list narrows to matching countries; capitals and accents don't matter, so \"c"
|
|
9666
|
+
}
|
|
9661
9667
|
]
|
|
9662
9668
|
}
|
package/src/module-api.js
CHANGED
|
@@ -75,7 +75,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
|
|
|
75
75
|
// MAJOR (see allowBoxScope below): passes the request through untouched.
|
|
76
76
|
function deprecatedNoopMiddleware(_req, _res, next) { next(); }
|
|
77
77
|
|
|
78
|
-
const CORE_VERSION = '1.21.
|
|
78
|
+
const CORE_VERSION = '1.21.115'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
|
|
79
79
|
|
|
80
80
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
81
81
|
// Usage: const log = api.logger('discord'); log.info('mounted');
|
|
@@ -701,12 +701,14 @@ test('the rail\'s way-back handlers left with it, the repo picker is honest ARIA
|
|
|
701
701
|
// delegated handlers and their CSS must not linger as dead code
|
|
702
702
|
assert.doesNotMatch(SCRIPT, /railEl|data-goto/, 'no delegated rail handler is left');
|
|
703
703
|
assert.doesNotMatch(COSMOS, /\.steps li\[role=button\]/, 'and no rail-button CSS');
|
|
704
|
-
|
|
704
|
+
// the page's one real listbox is the country field's combobox (task 1004671); the repo
|
|
705
|
+
// picker stays a labelled group of rows
|
|
706
|
+
assert.deepEqual([...HUB.matchAll(/<[^>]*role="listbox"[^>]*>/g)].map((m) => (m[0].match(/id="([^"]+)"/) || [])[1]), ['physCountryList']);
|
|
705
707
|
assert.doesNotMatch(SCRIPT, /role="option"/);
|
|
706
708
|
assert.match(HUB, /<div id="ghList" class="ghlist" role="group" aria-label="Your repositories"><\/div>/, 'the label survives the listbox role');
|
|
707
709
|
assert.match(SCRIPT, /class="ghrow" data-full="' \+ esc\(r\.full_name\) \+ '" aria-current="' \+ \(r\.full_name === sel\) \+ '"/, 'the chosen row is aria-current');
|
|
708
710
|
assert.match(HUB, /\.ghrow\[aria-current=true\]\{/, 'and painted through it');
|
|
709
|
-
assert.doesNotMatch(
|
|
711
|
+
assert.doesNotMatch(SCRIPT.match(/[^\n]*class="ghrow"[^\n]*/)[0], /aria-selected/, 'aria-selected went with the repo picker\'s option role');
|
|
710
712
|
assert.match(SCRIPT, /if \(ev\.key !== 'Escape' \|\| \$\('ghList'\)\.hidden\) return;\n\s*ev\.stopPropagation\(\);\n\s*\$\('ghSearch'\)\.focus\(\);\n\s*closeRepoList\(\);/, 'Escape closes the list after handing focus back');
|
|
711
713
|
assert.match(SCRIPT, /if \(ev\.relatedTarget && !\$\('ghAdopt'\)\.contains\(ev\.relatedTarget\)\) closeRepoList\(\);/, 'focus leaving the picker closes it; a null relatedTarget is left alone');
|
|
712
714
|
assert.match(fn('openCard'), /\$\('cardScrim'\)\.hidden = false;\n\s*pageInert\(true\);\n\s*\$\('cardClose'\)\.focus\(\);/);
|
package/tests/wizard_physics.mjs
CHANGED
|
@@ -126,7 +126,7 @@ test('every choice the questions offer is an answer the server accepts', () => {
|
|
|
126
126
|
const checks = HUB.slice(HUB.indexOf('id="checksMain"'), HUB.indexOf('id="checksStop"'));
|
|
127
127
|
assert.deepEqual([...new Set([...checks.matchAll(/data-phys="([a-z_]+)"/g)].map((m) => m[1]))], ['minors_on_board', 'builder_geography', 'entity'],
|
|
128
128
|
'the quick checks ask about under-18s, where builders will be and who is behind it in the mockup’s order');
|
|
129
|
-
assert.match(checks, /<select id="physCountry">/, 'and where you are');
|
|
129
|
+
assert.match(checks, /<select id="physCountry" aria-labelledby="physCountryLbl">/, 'and where you are (the select the searchable list picks for, task 1004671)');
|
|
130
130
|
const seen = [...panel.matchAll(/data-phys="([a-z_]+)" data-val="([^"]+)"/g)];
|
|
131
131
|
assert.ok(seen.length >= 20, 'the questions\' choices');
|
|
132
132
|
for (const [, key, raw] of seen) {
|
|
@@ -608,3 +608,136 @@ test('the address is on every path, the demo\'s too: never a fixed row, always c
|
|
|
608
608
|
assert.equal(w.run('firstInvalidRow()'), null, `${label}: then Create goes on`);
|
|
609
609
|
}
|
|
610
610
|
});
|
|
611
|
+
|
|
612
|
+
// ── "Where are you?" as a searchable list (task 1004671) ─────────────────────
|
|
613
|
+
// The combobox only picks for the hidden select, so everything that reads the select
|
|
614
|
+
// (the region, the screen, the draft, the fill, what Create sends) is the same path.
|
|
615
|
+
const key = (k) => ({ key: k, preventDefault() {}, stopPropagation() {} });
|
|
616
|
+
function typeCountry(w, text) {
|
|
617
|
+
w.$('physCountryIn').value = text;
|
|
618
|
+
w.$('physCountryIn').listeners.input();
|
|
619
|
+
}
|
|
620
|
+
const shownCodes = (w) => plain(w.run('cboxShown.map(function (i) { return i.code; })'));
|
|
621
|
+
|
|
622
|
+
test('the country starts at the United States, in a combobox in front of the select', () => {
|
|
623
|
+
const w = boot();
|
|
624
|
+
w.run('physDefaults(); paintChecks();');
|
|
625
|
+
assert.equal(w.a().home_country, 'US', 'the default answer is the United States');
|
|
626
|
+
assert.equal(w.$('physCountry').value, 'US', 'on the select everything reads');
|
|
627
|
+
assert.equal(w.$('physCountryIn').value, 'United States', 'and said by name in the field');
|
|
628
|
+
assert.equal(w.$('physRegionField').hidden, false, 'so the state field is there from the start');
|
|
629
|
+
assert.equal(w.$('physCountry').hidden, true, 'the script hides the plain select');
|
|
630
|
+
assert.equal(w.$('physCountryBox').hidden, false, 'and shows the searchable field');
|
|
631
|
+
const input = w.$('physCountryIn'), list = w.$('physCountryList');
|
|
632
|
+
assert.equal(input.getAttribute('role'), 'combobox');
|
|
633
|
+
assert.equal(input.getAttribute('aria-controls'), 'physCountryList');
|
|
634
|
+
assert.equal(input.getAttribute('aria-expanded'), 'false');
|
|
635
|
+
assert.equal(list.getAttribute('role'), 'listbox');
|
|
636
|
+
assert.equal(list.hidden, true, 'closed until asked');
|
|
637
|
+
// a choice taken back stays taken back, and the last project's answers still win
|
|
638
|
+
const cleared = boot();
|
|
639
|
+
cleared.run('phys().answers.home_country = null; physDefaults();');
|
|
640
|
+
assert.equal(cleared.a().home_country, null);
|
|
641
|
+
const filled = boot({ draft: {} });
|
|
642
|
+
filled.run('phys(); physDefaults(); physAccountAnswers = { home_country: "NL" };');
|
|
643
|
+
filled.$('physFromAccount').click();
|
|
644
|
+
assert.equal(filled.a().home_country, 'NL', 'the fill replaces the default');
|
|
645
|
+
assert.equal(filled.$('physCountryIn').value, 'Netherlands');
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
test('typing filters the list, ignoring case and accents, the closest names first', () => {
|
|
649
|
+
const w = boot();
|
|
650
|
+
w.run('physDefaults(); paintChecks();');
|
|
651
|
+
w.$('physCountryIn').listeners.click();
|
|
652
|
+
assert.equal(w.$('physCountryList').hidden, false, 'a click opens the whole list');
|
|
653
|
+
assert.equal(w.$('physCountryIn').getAttribute('aria-expanded'), 'true');
|
|
654
|
+
assert.ok(shownCodes(w).length > 200, 'every country');
|
|
655
|
+
assert.equal(w.$('physCountryIn').getAttribute('aria-activedescendant'), 'physCountryOpt-US', 'on the one already chosen');
|
|
656
|
+
typeCountry(w, 'NETH');
|
|
657
|
+
assert.deepEqual(shownCodes(w), ['NL', 'BQ'], 'case does not matter; the name that starts with it first, then Caribbean Netherlands');
|
|
658
|
+
typeCountry(w, 'cote');
|
|
659
|
+
assert.deepEqual(shownCodes(w), ['CI'], 'nor accents (Côte d’Ivoire)');
|
|
660
|
+
typeCountry(w, 'curacao');
|
|
661
|
+
assert.deepEqual(shownCodes(w), ['CW']);
|
|
662
|
+
typeCountry(w, 'ger');
|
|
663
|
+
assert.equal(shownCodes(w)[0], 'DE', 'a name that starts with it leads');
|
|
664
|
+
assert.ok(shownCodes(w).includes('NG') && shownCodes(w).includes('DZ'), 'then names with it inside');
|
|
665
|
+
typeCountry(w, 'usa');
|
|
666
|
+
assert.equal(shownCodes(w)[0], 'US');
|
|
667
|
+
typeCountry(w, 'zzz');
|
|
668
|
+
assert.deepEqual(shownCodes(w), []);
|
|
669
|
+
assert.equal(w.$('physCountryNone').hidden, false, 'nothing matches, and it says so');
|
|
670
|
+
assert.equal(w.$('physCountryIn').getAttribute('aria-activedescendant'), null);
|
|
671
|
+
// every option is a node with its name as text, never markup
|
|
672
|
+
const opts = w.$('physCountryList').children.filter((c) => c.getAttribute('data-code'));
|
|
673
|
+
assert.ok(opts.length > 200);
|
|
674
|
+
const nl = opts.find((c) => c.getAttribute('data-code') === 'NL');
|
|
675
|
+
assert.equal(nl.textContent, 'Netherlands');
|
|
676
|
+
assert.equal(nl.getAttribute('role'), 'option');
|
|
677
|
+
assert.equal(nl.getAttribute('id'), 'physCountryOpt-NL');
|
|
678
|
+
assert.doesNotMatch(SCRIPT.slice(SCRIPT.indexOf('function cboxFold('), SCRIPT.indexOf('function physCountryChanged(')), /innerHTML/);
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
test('arrow keys move through the list, Enter picks, Escape puts the country back', () => {
|
|
682
|
+
const w = boot();
|
|
683
|
+
w.run('physDefaults(); paintChecks();');
|
|
684
|
+
const input = w.$('physCountryIn');
|
|
685
|
+
typeCountry(w, 'ger');
|
|
686
|
+
assert.equal(input.getAttribute('aria-activedescendant'), 'physCountryOpt-DE');
|
|
687
|
+
input.listeners.keydown(key('ArrowDown'));
|
|
688
|
+
const second = shownCodes(w)[1];
|
|
689
|
+
assert.equal(input.getAttribute('aria-activedescendant'), 'physCountryOpt-' + second);
|
|
690
|
+
input.listeners.keydown(key('ArrowUp'));
|
|
691
|
+
assert.equal(input.getAttribute('aria-activedescendant'), 'physCountryOpt-DE');
|
|
692
|
+
input.listeners.keydown(key('Enter'));
|
|
693
|
+
assert.equal(w.a().home_country, 'DE', 'Enter picks');
|
|
694
|
+
assert.equal(w.$('physCountry').value, 'DE');
|
|
695
|
+
assert.equal(input.value, 'Germany');
|
|
696
|
+
assert.equal(w.$('physCountryList').hidden, true, 'and closes the list');
|
|
697
|
+
assert.equal(input.getAttribute('aria-expanded'), 'false');
|
|
698
|
+
typeCountry(w, 'fra');
|
|
699
|
+
input.listeners.keydown(key('Escape'));
|
|
700
|
+
assert.equal(w.a().home_country, 'DE', 'Escape changes nothing');
|
|
701
|
+
assert.equal(input.value, 'Germany', 'and puts the chosen name back');
|
|
702
|
+
assert.equal(w.$('physCountryList').hidden, true);
|
|
703
|
+
input.listeners.keydown(key('ArrowDown'));
|
|
704
|
+
assert.equal(w.$('physCountryList').hidden, false, 'ArrowDown opens it again');
|
|
705
|
+
assert.equal(input.getAttribute('aria-activedescendant'), 'physCountryOpt-DE');
|
|
706
|
+
typeCountry(w, 'France');
|
|
707
|
+
input.listeners.blur();
|
|
708
|
+
assert.equal(w.a().home_country, 'FR', 'leaving with a whole name typed picks it');
|
|
709
|
+
typeCountry(w, 'fr');
|
|
710
|
+
input.listeners.blur();
|
|
711
|
+
assert.equal(w.a().home_country, 'FR', 'leaving half way keeps the country');
|
|
712
|
+
assert.equal(input.value, 'France');
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
test('a country picked from the list runs the select\'s own path: the region, the screen and what Create sends', async () => {
|
|
716
|
+
const w = boot();
|
|
717
|
+
w.run('physDefaults(); paintChecks();');
|
|
718
|
+
w.a().home_region = 'US-CA';
|
|
719
|
+
typeCountry(w, 'canada');
|
|
720
|
+
const ca = w.$('physCountryList').children.find((c) => c.getAttribute('data-code') === 'CA');
|
|
721
|
+
ca.click();
|
|
722
|
+
assert.equal(w.a().home_country, 'CA');
|
|
723
|
+
assert.equal(w.a().home_region, null, 'a state of another country is dropped');
|
|
724
|
+
assert.equal(w.$('physRegionField').hidden, false, 'a country with provinces asks for one');
|
|
725
|
+
assert.ok(w.$('physRegion').children.some((o) => o.value === 'CA-ON'));
|
|
726
|
+
typeCountry(w, 'netherlands');
|
|
727
|
+
w.$('physCountryList').children.find((c) => c.getAttribute('data-code') === 'NL').click();
|
|
728
|
+
assert.equal(w.$('physRegionField').hidden, true, 'and one without does not');
|
|
729
|
+
await w.settle();
|
|
730
|
+
const asked = w.fetched.filter((f) => f.url.includes('physics-check')).map((f) => f.body.detail.home_country);
|
|
731
|
+
assert.deepEqual(asked, ['CA', 'NL'], 'each pick asks the table again, with the code');
|
|
732
|
+
// the same code the select path sends
|
|
733
|
+
const viaSelect = boot();
|
|
734
|
+
viaSelect.run('physDefaults(); paintChecks();');
|
|
735
|
+
viaSelect.$('physCountry').value = 'NL';
|
|
736
|
+
viaSelect.$('physCountry').listeners.change();
|
|
737
|
+
assert.deepEqual(plain(w.run('createDetail()')), plain(viaSelect.run('createDetail()')), 'Create sends exactly what the select sends');
|
|
738
|
+
assert.equal(plain(w.run('createDetail()')).home_country, 'NL');
|
|
739
|
+
// and untouched, Create sends the default
|
|
740
|
+
const untouched = boot();
|
|
741
|
+
untouched.run('physDefaults(); paintChecks();');
|
|
742
|
+
assert.equal(plain(untouched.run('createDetail()')).home_country, 'US');
|
|
743
|
+
});
|