Skip to content

Commit c9f4160

Browse files
committed
Simplify Robolectric UI test waits
1 parent ac0ebf9 commit c9f4160

File tree

1 file changed

+21
-53
lines changed

1 file changed

+21
-53
lines changed

scripts/templates/HelloCodenameOneUiTest.java.tmpl

Lines changed: 21 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import static org.junit.Assert.assertTrue;
55

66
import android.graphics.Bitmap;
77
import android.graphics.Canvas;
8+
import android.os.SystemClock;
89
import android.util.DisplayMetrics;
910
import android.view.View;
1011

@@ -14,24 +15,21 @@ import com.codename1.ui.Form;
1415
import java.io.File;
1516
import java.io.FileOutputStream;
1617
import java.io.IOException;
17-
import java.util.concurrent.CountDownLatch;
18-
import java.util.concurrent.TimeUnit;
19-
import java.util.concurrent.atomic.AtomicReference;
20-
2118
import org.junit.Test;
2219
import org.junit.runner.RunWith;
2320
import org.robolectric.Robolectric;
2421
import org.robolectric.RobolectricTestRunner;
2522
import org.robolectric.android.controller.ActivityController;
2623
import org.robolectric.annotation.Config;
24+
import org.robolectric.shadows.ShadowLooper;
2725

2826
@RunWith(RobolectricTestRunner.class)
2927
@Config(sdk = 30)
3028
public class @MAIN_NAME@UiTest {
3129

3230
@Test
3331
public void mainFormScreenshotContainsRenderedContent() throws Exception {
34-
ActivityController<@MAIN_NAME@Stub> controller = Robolectric.buildActivity(@[email protected]).setup();
32+
ActivityController<@MAIN_NAME@Stub> controller = Robolectric.buildActivity(@[email protected]).setup().visible();
3533
try {
3634
Form displayed = waitForDisplayedForm(5000L);
3735
assertNotNull("Codename One form should be displayed", displayed);
@@ -52,13 +50,13 @@ public class @MAIN_NAME@UiTest {
5250
}
5351

5452
private static Form waitForDisplayedForm(long timeoutMillis) throws InterruptedException {
55-
long deadline = System.currentTimeMillis() + timeoutMillis;
56-
final Form[] current = new Form[1];
57-
while (System.currentTimeMillis() < deadline) {
53+
long deadline = SystemClock.uptimeMillis() + timeoutMillis;
54+
while (SystemClock.uptimeMillis() < deadline) {
55+
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
5856
if (Display.isInitialized()) {
59-
Display.getInstance().callSeriallyAndWait(() -> current[0] = Display.getInstance().getCurrent());
60-
if (current[0] != null) {
61-
return current[0];
57+
Form current = Display.getInstance().getCurrent();
58+
if (current != null) {
59+
return current;
6260
}
6361
}
6462
Thread.sleep(50L);
@@ -69,10 +67,8 @@ public class @MAIN_NAME@UiTest {
6967
private static Bitmap captureScreenshot(@MAIN_NAME@Stub activity) throws InterruptedException {
7068
View decorView = waitForDecorViewWithDimensions(activity, 5000L);
7169
Bitmap bitmap = Bitmap.createBitmap(decorView.getWidth(), decorView.getHeight(), Bitmap.Config.ARGB_8888);
72-
runOnUiThreadAndWait(activity, () -> {
73-
Canvas canvas = new Canvas(bitmap);
74-
decorView.draw(canvas);
75-
});
70+
Canvas canvas = new Canvas(bitmap);
71+
decorView.draw(canvas);
7672
return bitmap;
7773
}
7874

@@ -120,57 +116,29 @@ public class @MAIN_NAME@UiTest {
120116
}
121117

122118
private static View waitForDecorViewWithDimensions(@MAIN_NAME@Stub activity, long timeoutMillis) throws InterruptedException {
123-
long deadline = System.currentTimeMillis() + timeoutMillis;
124-
while (System.currentTimeMillis() < deadline) {
119+
long deadline = SystemClock.uptimeMillis() + timeoutMillis;
120+
while (SystemClock.uptimeMillis() < deadline) {
125121
View decorView = activity.getWindow().getDecorView();
126122
if (decorView != null) {
127-
ensureViewHasLayout(activity, decorView);
123+
ensureViewHasLayout(decorView);
128124
if (decorView.getWidth() > 0 && decorView.getHeight() > 0) {
129125
return decorView;
130126
}
131127
}
128+
ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
132129
Thread.sleep(50L);
133130
}
134131
throw new AssertionError("Timed out waiting for decor view layout");
135132
}
136133

137-
private static void ensureViewHasLayout(@MAIN_NAME@Stub activity, View view) throws InterruptedException {
134+
private static void ensureViewHasLayout(View view) {
138135
if (view.getWidth() > 0 && view.getHeight() > 0) {
139136
return;
140137
}
141-
runOnUiThreadAndWait(activity, () -> {
142-
DisplayMetrics metrics = activity.getResources().getDisplayMetrics();
143-
int widthSpec = View.MeasureSpec.makeMeasureSpec(metrics.widthPixels, View.MeasureSpec.EXACTLY);
144-
int heightSpec = View.MeasureSpec.makeMeasureSpec(metrics.heightPixels, View.MeasureSpec.EXACTLY);
145-
view.measure(widthSpec, heightSpec);
146-
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
147-
});
148-
}
149-
150-
private static void runOnUiThreadAndWait(@MAIN_NAME@Stub activity, Runnable runnable) throws InterruptedException {
151-
CountDownLatch latch = new CountDownLatch(1);
152-
AtomicReference<Throwable> error = new AtomicReference<>();
153-
activity.runOnUiThread(() -> {
154-
try {
155-
runnable.run();
156-
} catch (Throwable t) {
157-
error.set(t);
158-
} finally {
159-
latch.countDown();
160-
}
161-
});
162-
if (!latch.await(5, TimeUnit.SECONDS)) {
163-
throw new AssertionError("Timed out waiting for UI thread task");
164-
}
165-
if (error.get() != null) {
166-
Throwable thrown = error.get();
167-
if (thrown instanceof RuntimeException) {
168-
throw (RuntimeException) thrown;
169-
}
170-
if (thrown instanceof Error) {
171-
throw (Error) thrown;
172-
}
173-
throw new RuntimeException(thrown);
174-
}
138+
DisplayMetrics metrics = view.getResources().getDisplayMetrics();
139+
int widthSpec = View.MeasureSpec.makeMeasureSpec(metrics.widthPixels, View.MeasureSpec.EXACTLY);
140+
int heightSpec = View.MeasureSpec.makeMeasureSpec(metrics.heightPixels, View.MeasureSpec.EXACTLY);
141+
view.measure(widthSpec, heightSpec);
142+
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
175143
}
176144
}

0 commit comments

Comments
 (0)