Skip to content

Commit c8de824

Browse files
committed
Add timeout rule and setup lifecycle for Robolectric test
1 parent 06291ae commit c8de824

File tree

1 file changed

+63
-43
lines changed

1 file changed

+63
-43
lines changed

scripts/templates/HelloCodenameOneUiTest.java.tmpl

Lines changed: 63 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ import java.io.FileOutputStream;
1414
import java.io.FileWriter;
1515
import java.io.IOException;
1616
import java.io.PrintWriter;
17+
import java.util.concurrent.TimeUnit;
18+
import org.junit.After;
19+
import org.junit.Before;
20+
import org.junit.Rule;
1721
import org.junit.Test;
22+
import org.junit.rules.TestRule;
23+
import org.junit.rules.Timeout;
1824
import org.junit.runner.RunWith;
1925
import org.robolectric.Robolectric;
2026
import org.robolectric.RobolectricTestRunner;
@@ -28,54 +34,68 @@ import org.robolectric.shadows.ShadowLooper;
2834
@LooperMode(LooperMode.Mode.LEGACY)
2935
public 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

Comments
 (0)