Skip to content

Commit 6f512b9

Browse files
committed
Fix CI screenshot test to capture native widgets properly
The CI instrumentation test was using Android's native View.draw() method to capture screenshots, which doesn't properly include PeerComponents like BrowserComponent (native WebView). This change updates the test to use Codename One's screenshot API (Display.getInstance().screenshot()) which properly captures native widgets via the AndroidScreenshotTask implementation that was fixed in PR #4107. Key changes: - Replace direct View.draw() with CN1 screenshot API - Add proper synchronization using CountDownLatch - Convert CN1 Image to Android Bitmap for encoding - Maintain same output format for CI pipeline compatibility This ensures BrowserComponent and other native widgets are now visible in CI screenshots.
1 parent 1a7ef26 commit 6f512b9

File tree

1 file changed

+55
-19
lines changed

1 file changed

+55
-19
lines changed

scripts/android/tests/HelloCodenameOneInstrumentedTest.java

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,27 +84,52 @@ private static final class ScreenshotCapture {
8484
private static ScreenshotCapture captureScreenshot(ActivityScenario<Activity> scenario, String testName) {
8585
final byte[][] holder = new byte[2][];
8686
final int[] qualityHolder = new int[1];
87-
scenario.onActivity(activity -> {
87+
final CountDownLatch latch = new CountDownLatch(1);
88+
89+
scenario.onActivity(activity -> Display.getInstance().callSerially(() -> {
8890
try {
89-
View root = activity.getWindow().getDecorView().getRootView();
90-
int w = root.getWidth();
91-
int h = root.getHeight();
92-
if (w <= 0 || h <= 0) {
93-
DisplayMetrics dm = activity.getResources().getDisplayMetrics();
94-
w = Math.max(1, dm.widthPixels);
95-
h = Math.max(1, dm.heightPixels);
96-
int sw = View.MeasureSpec.makeMeasureSpec(w, View.MeasureSpec.EXACTLY);
97-
int sh = View.MeasureSpec.makeMeasureSpec(h, View.MeasureSpec.EXACTLY);
98-
root.measure(sw, sh);
99-
root.layout(0, 0, w, h);
100-
println("CN1SS:INFO:test=" + testName + " forced layout to " + w + "x" + h);
91+
// Use Codename One screenshot API which properly captures PeerComponents
92+
final com.codename1.ui.Image[] screenshotHolder = new com.codename1.ui.Image[1];
93+
Display.getInstance().screenshot(img -> {
94+
screenshotHolder[0] = img;
95+
});
96+
97+
// Wait for screenshot to complete (with timeout)
98+
long startTime = System.currentTimeMillis();
99+
while (screenshotHolder[0] == null) {
100+
try {
101+
Thread.sleep(50);
102+
} catch (InterruptedException ie) {
103+
Thread.currentThread().interrupt();
104+
break;
105+
}
106+
if (System.currentTimeMillis() - startTime > 5000) {
107+
println("CN1SS:ERR:test=" + testName + " screenshot timeout");
108+
break;
109+
}
110+
}
111+
112+
if (screenshotHolder[0] == null) {
113+
println("CN1SS:ERR:test=" + testName + " screenshot returned null");
114+
return;
115+
}
116+
117+
// Convert CN1 Image to Android Bitmap
118+
com.codename1.ui.Image screenshot = screenshotHolder[0];
119+
Object nativeImage = screenshot.getImage();
120+
Bitmap bmp;
121+
122+
if (nativeImage instanceof Bitmap) {
123+
bmp = (Bitmap) nativeImage;
101124
} else {
102-
println("CN1SS:INFO:test=" + testName + " natural layout " + w + "x" + h);
125+
println("CN1SS:ERR:test=" + testName + " unexpected native image type: " +
126+
(nativeImage != null ? nativeImage.getClass().getName() : "null"));
127+
return;
103128
}
104129

105-
Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
106-
Canvas c = new Canvas(bmp);
107-
root.draw(c);
130+
int w = bmp.getWidth();
131+
int h = bmp.getHeight();
132+
println("CN1SS:INFO:test=" + testName + " screenshot size " + w + "x" + h);
108133

109134
ByteArrayOutputStream pngOut = new ByteArrayOutputStream(Math.max(1024, w * h / 2));
110135
if (!bmp.compress(Bitmap.CompressFormat.PNG, 100, pngOut)) {
@@ -160,12 +185,23 @@ private static ScreenshotCapture captureScreenshot(ActivityScenario<Activity> sc
160185
} else {
161186
println("CN1SS:INFO:test=" + testName + " preview_jpeg_bytes=0 preview_quality=0");
162187
}
163-
bmp.recycle();
164188
} catch (Throwable t) {
165189
println("CN1SS:ERR:test=" + testName + " " + t);
166190
Log.e(t);
191+
} finally {
192+
latch.countDown();
167193
}
168-
});
194+
}));
195+
196+
try {
197+
if (!latch.await(10, TimeUnit.SECONDS)) {
198+
println("CN1SS:ERR:test=" + testName + " latch timeout");
199+
}
200+
} catch (InterruptedException ie) {
201+
Thread.currentThread().interrupt();
202+
println("CN1SS:ERR:test=" + testName + " interrupted");
203+
}
204+
169205
if (holder[0] == null) {
170206
return new ScreenshotCapture(null, null, 0);
171207
}

0 commit comments

Comments
 (0)