From 73ef3a67cae605cec90450692d7004cbd612eb3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD=20=D0=A2=D1=80=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Sun, 27 Sep 2026 15:02:21 +0300 Subject: [PATCH] ui: put the CAP report in a bordered "CAP details" container (v3.5.19) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CAP analysis now lives in the simulator-style fieldset with the title embedded in the border: - Both CAP boxes (RAM installer, SCP81 Scripts) use the same bordered fieldset + legend pattern as the simulator/eSIM/card fieldsets. - capRenderAnalysis toggles the fieldset and writes into the body div, so the border and title stay visible for analyzing / failed (Retry) / done states alike. - capMemHtml is pure content now; the inner "CAP requirements (estimate)" heading is gone - the border legend titles the box. - i18n: 'CAP details' -> "Детали CAP" (static legend, data-l10n). - refreshDynamicI18n() rebuilds both CAP bodies on a language switch (the dynamic report previously kept the old language). Tests: the wiring test requires both legends and body divs, a new capRenderAnalysis test covers idle/analyzing/error/ok, and the renderer tests no longer expect the inner heading. 593 frontend / 473 Python green; version 3.5.19; sw simple-v272. --- frontend/index.html | 29 +++++++++++++++++--------- frontend/sw.js | 2 +- frontend/tests/capmem.test.js | 38 ++++++++++++++++++++++++++++++++++- pyproject.toml | 2 +- pysim_simple_server/server.py | 2 +- 5 files changed, 60 insertions(+), 13 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index ed32b10..4f7eb80 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -701,7 +701,10 @@ '), out); assert.ok(out.includes('>Requires (1)'), out); @@ -228,4 +229,39 @@ test('the CAP inputs and their action buttons are wired', () => { assert.match(html, /id="ram-cap-info"/); assert.match(html, /id="scripts-cap-info"/); assert.match(html, /\/api\/cap-info/); + // the report lives in a bordered fieldset with the title in the border + // (the simulator/eSIM pattern); the JS fills the body div + assert.match(html, /
]*>\s*]*data-l10n="CAP details">/); + assert.match(html, /
]*>\s*]*data-l10n="CAP details">/); + assert.match(html, /id="ram-cap-body"/); + assert.match(html, /id="scripts-cap-body"/); +}); + +test('capRenderAnalysis toggles the border box and fills its body', () => { + eval(extractFunc(html, 'capRenderAnalysis')); + const box = { hidden: true, classList: { + add() { box.hidden = true; }, + remove() { box.hidden = false; }, + } }; + const body = { innerHTML: '' }; + globalThis.document = { getElementById: id => ({ + 'ram-cap-info': box, 'ram-cap-body': body, + }[id] || null) }; + // idle: hidden and empty + _capAnalysis.ram = { key: null, status: 'idle', memory: null, error: null, token: 0 }; + capRenderAnalysis('ram'); + assert.ok(box.hidden && body.innerHTML === ''); + // a finished analysis: shown, body carries the report + _capAnalysis.ram = { key: null, status: 'ok', memory: memFixture(), error: null, token: 0 }; + capRenderAnalysis('ram'); + assert.ok(!box.hidden, 'the box is shown'); + assert.ok(body.innerHTML.includes('>Requires (1)'), body.innerHTML); + // a failure: shown with the error and a retry + _capAnalysis.ram = { key: null, status: 'error', memory: null, error: 'bad zip', token: 0 }; + capRenderAnalysis('ram'); + assert.ok(!box.hidden && body.innerHTML.includes('bad zip') && body.innerHTML.includes('Retry'), body.innerHTML); + // analyzing: shown with the progress line + _capAnalysis.ram = { key: null, status: 'analyzing', memory: null, error: null, token: 0 }; + capRenderAnalysis('ram'); + assert.ok(body.innerHTML.includes('Analyzing CAP file...'), body.innerHTML); }); diff --git a/pyproject.toml b/pyproject.toml index 00ecb0e..0dbf7a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pysim-simple-server" -version = "3.5.18" +version = "3.5.19" description = "HTTP REST server wrapping pysim for the SIMple PWA" requires-python = ">=3.8" # pysim is a git-only dependency installed explicitly by setup.bat/setup.sh. diff --git a/pysim_simple_server/server.py b/pysim_simple_server/server.py index b70fa3e..724b2ba 100644 --- a/pysim_simple_server/server.py +++ b/pysim_simple_server/server.py @@ -31,7 +31,7 @@ from osmocom.tlv import BER_TLV_IE from osmocom.utils import rpad -VERSION = '3.5.18' +VERSION = '3.5.19' MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE