test(ui): align native card checks and refresh Tracker capture

This commit is contained in:
liu weikai committed 2026-10-15 14:19:57 +08:00
1 parent 2b4420926a
commit dce8aac03d
4 files changed
+19 -5

No files matched your search

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 12 KiB

+10
View File
@@ -21,6 +21,12 @@ Clicking the card also opens its existing action menu. Touch gestures and
keyboard selection remain available. The title has at most two lines; the
region can scroll within its row.
![Wio L2 Tracker route card](../../images/release-1.0.0/firmware-tracker-card-native.png)
This full-page native LVGL capture uses the CI-built Wio L2 preview, sample KML
and simulated GPS. No administrative map dataset is installed in the preview,
so it shows an unknown region. It is not a physical-device screenshot.
Title extraction shares the current selected-file read (at most 64 KiB) with
first-position extraction. Its bounded XML workspace is transient PSRAM and is
freed after the read. No per-route metadata cache or geometry collection is
@@ -31,3 +37,7 @@ against LVGL at 320×240, 480×222 and 240×320, checks control bounds and Actio
and exercises title decoding, UTF-8 truncation, hash fallback and combined
title/coordinate reads. The surrounding native page is a test scaffold, not a
physical device capture. Physical acceptance of this revision is pending.
The full-page native tests also exercise recording, KML document titles, Actions,
previous/next selection and widget reuse on Pager, T-Deck and Wio L2. The shorter
Pager recording card hides the format row to keep location and controls visible.
+3 -1
View File
@@ -21,7 +21,9 @@ for(const device of ['pager','tdeck','wio-tracker-l2']) {
const stop=snapshot().find(item=>item.button&&item.text==='Stop recording');
assert.equal(stop.w,action.w,'Start and stop share a stable button width');
assert.equal(stop.x,action.x,'Start and stop share a stable right-aligned position');
assert.ok(snapshot().some(item=>item.text==='GPX | Recording'),'New recording appears with readable file type/status');
assert.ok(snapshot().some(item=>!item.button&&/^track-\d+$/.test(item.text)),`${device}: new recording has a readable title without the file extension`);
if(device!=='pager')assert.ok(snapshot().some(item=>item.text==='GPX | Recording'),`${device}: recording card shows file type/status`);
else assert.ok(!snapshot().some(item=>item.text==='GPX | Recording'),'Short Pager recording card preserves room for location and actions by hiding the format row');
click('Routes');
assert.ok(!snapshot().some(item=>['Recording','Stop recording'].includes(item.text)),'Route mode has its own status and actions');
click('Tracks');
+6 -4
View File
@@ -12,7 +12,7 @@ for(const [device,width,height] of [['pager',480,222],['tdeck',320,240],['wio-tr
onFrame(pointer){framePointer=pointer;},print(){},printErr(){},
});
runtime._native_init(device==='pager'?0:1);
for(const [page,filterText,contentText,maxTextGap] of [[5,'Direct','Alex',16],[12,'Contacts','No contacts yet',6],[14,'Tracks','Not recording',5]]) {
for(const [page,filterText,contentText,maxTextGap] of [[5,'Direct','Alex',16],[12,'Contacts','No nodes',14],[14,'Tracks','Not recording',5]]) {
runtime._native_open_page(page);
for(let i=0;i<5;i++)runtime._native_tick(50);
const snapshot=JSON.parse(runtime.UTF8ToString(runtime._native_snapshot()));
@@ -23,14 +23,16 @@ for(const [device,width,height] of [['pager',480,222],['tdeck',320,240],['wio-tr
// Message text includes the card's own inset; compare actual rendered geometry.
const limit=device==='tdeck'&&page===5?24:maxTextGap;
assert.ok(gap>=0&&gap<=limit,`${device}:${page}: content lost width to a ${gap}px gap`);
// Contacts deliberately places its heading eight pixels inside the card.
const verticalInset=page===12?8:0;
// T-Deck's message name is vertically inset inside its richer info card.
if(device!=='tdeck'||page!==5)assert.ok(Math.abs(content.y-filter.y)<=3,`${device}:${page}: first rows align`);
if(device!=='tdeck'||page!==5)assert.ok(Math.abs(content.y-filter.y-verticalInset)<=3,`${device}:${page}: first rows align with their intended inset`);
const pixels=new Uint16Array(runtime.HEAPU8.buffer,framePointer,width*height);
const y=height-50;
const background=pixels[y*width+10];
// Tracker now deliberately uses colored item cards. Its seam must remain
// Contacts and Tracker deliberately use colored item cards. Their seam must remain
// continuous, while the content card may contrast with the pane background.
const seamEnd=page===14?content.x:width-10;
const seamEnd=page===12?content.x-11:page===14?content.x:width-10;
for(let x=10;x<seamEnd;x++)assert.equal(pixels[y*width+x],background,`${device}:${page}: divider or contrasting panel at ${x},${y}`);
}
console.log(`${device}: compact two-pane geometry, row alignment and continuous background passed.`);