@@ -14,7 +14,13 @@ import java.io.FileOutputStream;
1414import java.io.FileWriter;
1515import java.io.IOException;
1616import java.io.PrintWriter;
17+ import java.util.concurrent.TimeUnit;
18+ import org.junit.After;
19+ import org.junit.Before;
20+ import org.junit.Rule;
1721import org.junit.Test;
22+ import org.junit.rules.TestRule;
23+ import org.junit.rules.Timeout;
1824import org.junit.runner.RunWith;
1925import org.robolectric.Robolectric;
2026import org.robolectric.RobolectricTestRunner;
@@ -28,54 +34,68 @@ import org.robolectric.shadows.ShadowLooper;
2834@LooperMode(LooperMode.Mode.LEGACY)
2935public class @MAIN_NAME@UiTest {
3036
31- @Test
32- public void mainFormScreenshotContainsRenderedContent() throws Exception {
37+ private static final long TEST_TIMEOUT_SECONDS = 300L;
38+
39+ private ActivityController<@MAIN_NAME@Stub> controller;
40+ private @MAIN_NAME@Stub activity;
41+
42+ @Rule
43+ public final TestRule timeoutRule = Timeout.builder()
44+ .withTimeout(TEST_TIMEOUT_SECONDS, TimeUnit.SECONDS)
45+ .withLookingForStuckThread(true)
46+ .build();
47+
48+ @Before
49+ public void setUp() {
3350 log("Starting Robolectric activity for screenshot test");
34- ActivityController<@MAIN_NAME@Stub> controller = Robolectric.buildActivity(@
[email protected] );
51+ controller = Robolectric.buildActivity(@
[email protected] );
3552 log("ActivityController created");
36- controller.create();
37- log("Activity created (Display.isInitialized=" + Display.isInitialized() + ")");
38- controller.start();
39- log("Activity started");
40- log("Calling controller.resume() on Robolectric thread");
41- controller.resume();
42- log("controller.resume() completed");
43- log("Display initialized after resume: " + Display.isInitialized());
44- controller.visible();
45- log("Activity made visible");
53+ log("Invoking controller.setup() to create/start/resume activity");
54+ activity = controller.setup();
55+ log("controller.setup() completed (Display.isInitialized=" + Display.isInitialized() + ")");
56+ log("Processing pending Codename One tasks after setup");
57+ ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
58+ log("Initial runUiThreadTasksIncludingDelayedTasks call finished");
59+ }
4660
47- try {
48- log("Idling main looper to process pending tasks");
49- ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
50- log("Completed runUiThreadTasksIncludingDelayedTasks");
51-
52- if (Display.isInitialized()) {
53- log("Codename One display reports current form="
54- + Display.getInstance().getCurrent());
55- } else {
56- log("Codename One display not initialized; continuing with screenshot capture");
57- }
61+ @After
62+ public void tearDown() {
63+ if (controller == null) {
64+ return;
65+ }
66+ safelyInvokeLifecycle(controller::pause, "pause");
67+ safelyInvokeLifecycle(controller::stop, "stop");
68+ safelyInvokeLifecycle(controller::destroy, "destroy");
69+ }
5870
59- @MAIN_NAME@Stub activity = controller.get();
60- log("Capturing decor view screenshot without additional waits");
61- Bitmap screenshot = captureScreenshot(activity);
62- assertTrue("Screenshot capture should succeed", screenshot != null);
63- log("Screenshot dimensions=" + screenshot.getWidth() + "x" + screenshot.getHeight());
64- assertTrue("Screenshot width should be positive", screenshot.getWidth() > 0);
65- assertTrue("Screenshot height should be positive", screenshot.getHeight() > 0);
66- boolean hasContent = hasRenderableContent(screenshot);
67- log("Screenshot content analysis result=" + hasContent);
68- assertTrue("Screenshot should contain rendered content beyond the background", hasContent);
69-
70- File screenshotFile = saveScreenshot(screenshot);
71- log("Screenshot stored at " + screenshotFile.getAbsolutePath());
72- assertTrue("Screenshot file should exist", screenshotFile.isFile());
73- assertTrue("Screenshot file should not be empty", screenshotFile.length() > 0L);
74- } finally {
75- safelyInvokeLifecycle(controller::pause, "pause");
76- safelyInvokeLifecycle(controller::stop, "stop");
77- safelyInvokeLifecycle(controller::destroy, "destroy");
71+ @Test
72+ public void mainFormScreenshotContainsRenderedContent() throws Exception {
73+ log("Running screenshot assertions with prepared activity");
74+ log("Idling main looper to process pending tasks");
75+ ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
76+ log("Completed runUiThreadTasksIncludingDelayedTasks");
77+
78+ if (Display.isInitialized()) {
79+ log("Codename One display reports current form="
80+ + Display.getInstance().getCurrent());
81+ } else {
82+ log("Codename One display not initialized; continuing with screenshot capture");
7883 }
84+
85+ log("Capturing decor view screenshot without additional waits");
86+ Bitmap screenshot = captureScreenshot(activity);
87+ assertTrue("Screenshot capture should succeed", screenshot != null);
88+ log("Screenshot dimensions=" + screenshot.getWidth() + "x" + screenshot.getHeight());
89+ assertTrue("Screenshot width should be positive", screenshot.getWidth() > 0);
90+ assertTrue("Screenshot height should be positive", screenshot.getHeight() > 0);
91+ boolean hasContent = hasRenderableContent(screenshot);
92+ log("Screenshot content analysis result=" + hasContent);
93+ assertTrue("Screenshot should contain rendered content beyond the background", hasContent);
94+
95+ File screenshotFile = saveScreenshot(screenshot);
96+ log("Screenshot stored at " + screenshotFile.getAbsolutePath());
97+ assertTrue("Screenshot file should exist", screenshotFile.isFile());
98+ assertTrue("Screenshot file should not be empty", screenshotFile.length() > 0L);
7999 }
80100
81101 private static Bitmap captureScreenshot(@MAIN_NAME@Stub activity) {
0 commit comments