v3.23.9: the CAP compatibility test suggestion on a failed install

A RAM install that fails at a LOAD step is typically the library-version
gate: the card verifies the CAP's import list when the Import component
completes (JC VM 4.5.2).  The failure hint now says so and points at the
CAP compatibility test (Set all 0.0, then restore the lines one at a time
to find the missing package and version), replacing the old "retry with a
smaller LOAD block" advice, which is a red herring for that gate.

The failure popup gains a one-click "Run the CAP compatibility test"
button: it closes the popup, switches the RAM operation selector to compat
and runs it with the same .cap (the file input still holds it and the probe
list is prefilled with its imports), so the diagnostic is one click away.

An INSTALL [for load] refusal now gets its own advice instead of the LOAD
hint: the card refused to open the load file - usually a duplicate load
file from an earlier run (delete the package first, Explore -> Delete), or
rejected load parameters.

Tests: the hint's wording and branches (LOAD vs INSTALL [for load]), the
button handler's op switch.  862 frontend + 842 Python; sw cache
simple-v422.
This commit is contained in:
2026-10-09 21:59:51 +03:00
parent dc8d71c6a7
commit 1473396e5b
7 changed files with 68 additions and 12 deletions
+26 -3
View File
@@ -466,13 +466,23 @@ test('ramInstallFailHint names the CAP import requirement for a rejected LOAD',
steps: [{ name: 'INSTALL [for load]' }, { name: 'LOAD (1/240)' }, { name: 'LOAD (2/240)', por_sw: '6985' }],
};
const hint = ramInstallFailHint(failedLoad, { requires_java_card: '2.2.2' });
assert.ok(hint.includes('every import version under Requires'), hint);
// v3.23.9: a rejected LOAD points at the compatibility test (the typical
// library-version gate) - the old "smaller LOAD block" advice is gone
assert.ok(hint.includes('CAP compatibility test'), hint);
assert.ok(hint.includes('(Java Card \u2265 2.2.2)'), hint);
assert.ok(hint.includes('smaller LOAD block'), hint);
assert.ok(!hint.includes('smaller LOAD block'), hint);
// without a CAP analysis (INSTALL [for install] ops) the level is omitted
const noMem = ramInstallFailHint(failedLoad, null);
assert.ok(noMem.includes('every import version under Requires'), noMem);
assert.ok(noMem.includes('CAP compatibility test'), noMem);
assert.ok(!noMem.includes('Java Card'), noMem);
// an INSTALL [for load] refusal gets its own advice (a duplicate load
// file from an earlier run is the usual cause), not the LOAD hint
const installFail = ramInstallFailHint(
{ success: false, failed_step: 1,
steps: [{ name: 'INSTALL [for load]', por_sw: '6985' }] }, null);
assert.ok(installFail.includes('refused to open the load file'), installFail);
assert.ok(installFail.includes('delete it first'), installFail);
assert.ok(!installFail.includes('compatibility test'), installFail);
// only a load-related step gets the hint
assert.strictEqual(ramInstallFailHint(
{ success: false, failed_step: 2, steps: [{ name: 'INSTALL [for load]' }, { name: 'INSTALL [for install]' }] }, null), '');
@@ -487,6 +497,19 @@ test('ramInstallFailHint names the CAP import requirement for a rejected LOAD',
assert.ok(withBoundary.startsWith('the failed step completes Import. '), withBoundary);
});
test('the failed install offers the one-click compatibility test', () => {
// the modal carries the button for a failed LOAD; the handler switches the
// RAM operation to the compatibility test and runs it (the CAP file input
// still holds the same file)
const install = extractFunc(html, 'ramShowInstallResult');
assert.ok(install.includes('ramRunCompatTest()'), install.slice(0, 400));
assert.ok(install.includes("t('Run the CAP compatibility test')"), install);
const run = extractFunc(html, 'ramRunCompatTest');
assert.ok(run.includes("sel.value = 'compat'"), run);
assert.ok(run.includes('ramOpChanged()'), run);
assert.ok(run.includes('ramExecute()'), run);
});
test('ramOpChanged clears the executed status only on a real op change', () => {
const els = fakeRamDocument(['ram-op', 'ram-install-params', 'ram-result', 'ram-explorer', 'ram-steps', 'ram-progress']);
_ramOpLast = null;