Skip to content

Commit 12144ce

Browse files
committed
Fixed race condition in screenshot capture
1 parent 1b52c50 commit 12144ce

3 files changed

Lines changed: 309 additions & 105 deletions

File tree

Ports/JavaScriptPort/STATUS.md

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Current State
1515
- `CN1SS:SUITE:FINISHED`
1616
- `TOP_BLOCKER=none|none|none`
1717
- The screenshot pipeline now decodes/report-generates reliably from logs, but screenshot content is still mostly wrong (white-frame capture path is still being used in CI artifacts).
18+
- New patch (not yet CI-validated in this document revision): worker-side fallback screenshot path now waits for a host-side UI-settle barrier before ready-callback dispatch and before canvas capture, to avoid pre-paint frame capture.
1819

1920
What Was Fixed In This Pass
2021
---------------------------
@@ -70,6 +71,21 @@ What Was Fixed In This Pass
7071
- Local check:
7172
- `JavascriptCn1CoreCompletenessTest#executesMeaningfulCodenameOneCoreSliceInWorkerRuntime` passes locally after this update.
7273

74+
7. Added explicit host-side UI settle barrier and wired it into screenshot readiness/capture flow.
75+
- Files:
76+
- `vm/ByteCodeTranslator/src/javascript/browser_bridge.js`
77+
- `Ports/JavaScriptPort/src/main/webapp/port.js`
78+
- Changes:
79+
- New host native `__cn1_wait_for_ui_settle__` waits across RAF frames and monitors canvas signature/score stability.
80+
- `BaseTest.registerReadyCallbackImmediate` now waits on host UI settle before invoking callback.
81+
- `Cn1ssDeviceRunnerHelper.emitCurrentFormScreenshotDom` now waits on host UI settle before `__cn1_capture_canvas_png__`.
82+
- Added diagnostics:
83+
- `PARPAR:DIAG:SCREENSHOT_START:settleReason=...`
84+
- `PARPAR:DIAG:SCREENSHOT_START:settleChanged=...`
85+
- `PARPAR:DIAG:FALLBACK:baseTestRegisterReady:afterUiSettle=1:...`
86+
- Motivation:
87+
- CI showed near-identical screenshot payloads (same hash/size) indicating repeated capture of a stale frame rather than per-test painted UI.
88+
7389
Known Failing Symptoms (Latest CI Logs/Artifacts)
7490
-------------------------------------------------
7591

@@ -91,16 +107,18 @@ Other CI Signal
91107
Priority Next Steps
92108
-------------------
93109

94-
1. Eliminate host-canvas screenshot fallback usage for named tests; route through translated screenshot helper path and capture real UI frames.
95-
2. Fix per-test null receiver/init path (`__classDef` null) at first failing stack, not via broad fallbacks.
96-
3. Fix missing `Button.initLaf(UIManager)` symbol resolution in worker runtime path.
97-
4. Fix worker-mode orientation lock path so DOM access is host-bridge mediated (no direct `document` access in worker).
98-
5. Confirm VM completeness stability in CI with new parser/runtime patches (`expected 7` consistently).
110+
1. Validate CI output after UI-settle barrier:
111+
- Expect non-identical PNG hashes for distinct tests.
112+
- Confirm `settleChanged` and `canvasSig` diagnostics vary across tests.
113+
2. If white-frame reuse persists, capture and compare per-test `settleSig`/`canvasSig` to identify whether paint is not happening or capture target is wrong.
114+
3. Fix per-test null receiver/init path (`__classDef` null) at first failing stack, not via broad fallbacks.
115+
4. Fix missing `Button.initLaf(UIManager)` symbol resolution in worker runtime path.
116+
5. Fix worker-mode orientation lock path so DOM access is host-bridge mediated (no direct `document` access in worker).
117+
6. Confirm VM completeness stability in CI with parser/runtime patches (`expected 7` consistently).
99118

100119
Files Touched In This Pass
101120
--------------------------
102121

103-
- `scripts/run-javascript-screenshot-tests.sh`
104-
- `vm/ByteCodeTranslator/src/javascript/parparvm_runtime.js`
105-
- `vm/tests/src/test/java/com/codename1/tools/translator/JavascriptRuntimeSemanticsTest.java`
122+
- `vm/ByteCodeTranslator/src/javascript/browser_bridge.js`
123+
- `Ports/JavaScriptPort/src/main/webapp/port.js`
106124
- `Ports/JavaScriptPort/STATUS.md`

Ports/JavaScriptPort/src/main/webapp/port.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3153,6 +3153,11 @@ bindCiFallback("Cn1ssDeviceRunnerHelper.emitCurrentFormScreenshotDom", [
31533153
let capturedDataUrl = "";
31543154
if (jvm && typeof jvm.invokeHostNative === "function") {
31553155
try {
3156+
yield jvm.invokeHostNative("__cn1_wait_for_ui_settle__", [{
3157+
reason: "screenshot:" + normalizedTest,
3158+
maxFrames: 18,
3159+
stableFrames: 2
3160+
}]);
31563161
const hostResult = yield jvm.invokeHostNative("__cn1_capture_canvas_png__", []);
31573162
capturedDataUrl = hostResult == null ? "" : String(hostResult);
31583163
} catch (_hostCaptureErr) {
@@ -3230,7 +3235,23 @@ bindCiFallback("BaseTest.registerReadyCallbackImmediate", [
32303235
baseTestRegisterReadyCallbackMethodId,
32313236
baseTestRegisterReadyCallbackMethodId + "__impl"
32323237
], function*(_baseTest, _form, callback) {
3233-
emitDiagLine("PARPAR:DIAG:FALLBACK:baseTestRegisterReady:immediateDispatch=1");
3238+
const activeTest = normalizeCn1ssTestName(cn1ssActiveTestName || "default");
3239+
let settleChanged = "na";
3240+
if (jvm && typeof jvm.invokeHostNative === "function") {
3241+
try {
3242+
const settleResult = yield jvm.invokeHostNative("__cn1_wait_for_ui_settle__", [{
3243+
reason: "ready:" + activeTest,
3244+
maxFrames: 24,
3245+
stableFrames: 2
3246+
}]);
3247+
if (settleResult && settleResult.changedFromPrevious != null) {
3248+
settleChanged = String((settleResult.changedFromPrevious | 0) !== 0 ? 1 : 0);
3249+
}
3250+
} catch (_settleErr) {
3251+
settleChanged = "err";
3252+
}
3253+
}
3254+
emitDiagLine("PARPAR:DIAG:FALLBACK:baseTestRegisterReady:afterUiSettle=1:test=" + activeTest + ":changed=" + settleChanged);
32343255
if (!callback || !callback.__class) {
32353256
return null;
32363257
}

0 commit comments

Comments
 (0)