Skip to content

Commit 8086b83

Browse files
committed
Capture Robolectric logs and surface UI test artifacts
1 parent 1956c39 commit 8086b83

File tree

3 files changed

+79
-14
lines changed

3 files changed

+79
-14
lines changed

.github/workflows/scripts-android.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ jobs:
2323
run: ./scripts/build-android-port.sh -q -DskipTests
2424
- name: Build Hello Codename One Android app
2525
run: ./scripts/build-android-app.sh -q -DskipTests
26-
- name: Upload UI test screenshot artifact
26+
- name: Upload UI test artifacts
2727
if: always()
2828
uses: actions/upload-artifact@v4
2929
with:
30-
name: hello-codenameone-ui-test-screenshot
31-
path: ${{ env.CN1_UI_TEST_SCREENSHOT }}
30+
name: hello-codenameone-ui-test-artifacts
31+
path: ${{ env.CN1_UI_TEST_ARTIFACT_DIR }}
3232
if-no-files-found: warn

scripts/build-android-app.sh

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,12 @@ rm -rf "$SCREENSHOT_OUTPUT_DIR"
301301
mkdir -p "$SCREENSHOT_OUTPUT_DIR"
302302
export CN1_TEST_SCREENSHOT_DIR="$SCREENSHOT_OUTPUT_DIR"
303303

304+
FINAL_ARTIFACT_DIR="${CN1_TEST_SCREENSHOT_EXPORT_DIR:-$REPO_ROOT/build-artifacts}"
305+
mkdir -p "$FINAL_ARTIFACT_DIR"
306+
if [ -n "${GITHUB_ENV:-}" ]; then
307+
printf 'CN1_UI_TEST_ARTIFACT_DIR=%s\n' "$FINAL_ARTIFACT_DIR" >> "$GITHUB_ENV"
308+
fi
309+
304310
ba_log "Invoking Gradle build in $GRADLE_PROJECT_DIR"
305311
chmod +x "$GRADLE_PROJECT_DIR/gradlew"
306312
ORIGINAL_JAVA_HOME="$JAVA_HOME"
@@ -326,26 +332,49 @@ else
326332
GRADLE_TEST_WRAPPER=("${GRADLE_TEST_CMD[@]}")
327333
fi
328334

335+
GRADLE_UI_TEST_LOG="$GRADLE_PROJECT_DIR/gradle-ui-test.log"
336+
ba_log "Capturing Gradle UI test output to $GRADLE_UI_TEST_LOG"
337+
ba_log "Robolectric UI tests execute without launching an emulator; consult the captured log for lifecycle output"
338+
329339
set +e
330340
(
331341
cd "$GRADLE_PROJECT_DIR"
332-
"${GRADLE_TEST_WRAPPER[@]}"
342+
"${GRADLE_TEST_WRAPPER[@]}" &>"$GRADLE_UI_TEST_LOG"
333343
)
334344
TEST_EXIT_CODE=$?
335345
set -e
336346

347+
if [ -f "$GRADLE_UI_TEST_LOG" ]; then
348+
cp "$GRADLE_UI_TEST_LOG" "$FINAL_ARTIFACT_DIR/ui-test-gradle.log"
349+
ba_log "Gradle UI test log saved to $FINAL_ARTIFACT_DIR/ui-test-gradle.log"
350+
fi
351+
337352
if [ "$TEST_EXIT_CODE" -eq 124 ]; then
338353
ba_log "Gradle UI tests exceeded ${UI_TEST_TIMEOUT_SECONDS}s timeout and were terminated"
339354
fi
340355
if [ "$TEST_EXIT_CODE" -ne 0 ]; then
341356
ba_log "Gradle UI tests exited with status $TEST_EXIT_CODE"
357+
if [ -s "$GRADLE_UI_TEST_LOG" ]; then
358+
ba_log "----- Begin Gradle UI test log -----"
359+
sed 's/^/[build-android-app] | /' "$GRADLE_UI_TEST_LOG"
360+
ba_log "----- End Gradle UI test log -----"
361+
else
362+
ba_log "Gradle UI test log $GRADLE_UI_TEST_LOG was empty or missing"
363+
fi
342364
TEST_RESULTS_DIR="$APP_MODULE_DIR/build/test-results/testDebugUnitTest"
343365
if [ -d "$TEST_RESULTS_DIR" ]; then
344366
ba_log "Available XML results under $TEST_RESULTS_DIR:"
345367
find "$TEST_RESULTS_DIR" -maxdepth 1 -type f -name '*.xml' -print | sed 's#^.*/##' | sed 's/^/[build-android-app] /'
346368
else
347369
ba_log "No test result XML directory found at $TEST_RESULTS_DIR"
348370
fi
371+
shopt -s nullglob
372+
for ui_log in "$SCREENSHOT_OUTPUT_DIR"/*.log; do
373+
ba_log "----- Begin UI test log: $(basename "$ui_log") -----"
374+
sed 's/^/[build-android-app] | /' "$ui_log"
375+
ba_log "----- End UI test log: $(basename "$ui_log") -----"
376+
done
377+
shopt -u nullglob
349378
fi
350379

351380
if [ "$TEST_EXIT_CODE" -eq 0 ]; then
@@ -364,15 +393,19 @@ if [ -z "$SCREENSHOT_FILE" ]; then
364393
ba_log "UI test completed but no screenshot was produced in $SCREENSHOT_OUTPUT_DIR" >&2
365394
SCREENSHOT_STATUS=1
366395
else
367-
FINAL_SCREENSHOT_DIR="${CN1_TEST_SCREENSHOT_EXPORT_DIR:-$REPO_ROOT/build-artifacts}"
368-
mkdir -p "$FINAL_SCREENSHOT_DIR"
369-
FINAL_SCREENSHOT="$FINAL_SCREENSHOT_DIR/ui-test-screenshot.png"
396+
FINAL_SCREENSHOT="$FINAL_ARTIFACT_DIR/ui-test-screenshot.png"
370397
cp "$SCREENSHOT_FILE" "$FINAL_SCREENSHOT"
371398
if [ -n "${GITHUB_ENV:-}" ]; then
372399
printf 'CN1_UI_TEST_SCREENSHOT=%s\n' "$FINAL_SCREENSHOT" >> "$GITHUB_ENV"
373400
fi
374401
ba_log "UI test screenshot available at $FINAL_SCREENSHOT"
375402
fi
403+
shopt -s nullglob
404+
for ui_log in "$SCREENSHOT_OUTPUT_DIR"/*.log; do
405+
cp "$ui_log" "$FINAL_ARTIFACT_DIR/$(basename "$ui_log")"
406+
ba_log "UI test log saved to $FINAL_ARTIFACT_DIR/$(basename "$ui_log")"
407+
done
408+
shopt -u nullglob
376409
unset CN1_TEST_SCREENSHOT_DIR
377410

378411
if [ "$TEST_EXIT_CODE" -ne 0 ]; then
@@ -385,4 +418,4 @@ fi
385418

386419
APK_PATH=$(find "$GRADLE_PROJECT_DIR" -path "*/outputs/apk/debug/*.apk" | head -n 1 || true)
387420
[ -n "$APK_PATH" ] || { ba_log "Gradle build completed but no APK was found" >&2; exit 1; }
388-
ba_log "Successfully built Android APK at $APK_PATH"
421+
ba_log "Successfully built Android APK at $APK_PATH"

scripts/templates/HelloCodenameOneUiTest.java.tmpl

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ import com.codename1.ui.Form;
1313

1414
import java.io.File;
1515
import java.io.FileOutputStream;
16+
import java.io.FileWriter;
1617
import java.io.IOException;
18+
import java.io.PrintWriter;
1719
import org.junit.Test;
1820
import org.junit.runner.RunWith;
1921
import org.robolectric.Robolectric;
@@ -114,11 +116,7 @@ public class @MAIN_NAME@UiTest {
114116
}
115117

116118
private static File saveScreenshot(Bitmap screenshot) throws IOException {
117-
String directory = System.getenv("CN1_TEST_SCREENSHOT_DIR");
118-
File outputDir = (directory != null && !directory.isEmpty()) ? new File(directory) : new File("build/ui-test-screenshots");
119-
if (!outputDir.exists() && !outputDir.mkdirs()) {
120-
throw new IOException("Failed to create screenshot directory " + outputDir.getAbsolutePath());
121-
}
119+
File outputDir = resolveArtifactDirectory();
122120
File screenshotFile = new File(outputDir, "@[email protected]");
123121
try (FileOutputStream out = new FileOutputStream(screenshotFile)) {
124122
if (!screenshot.compress(Bitmap.CompressFormat.PNG, 100, out)) {
@@ -128,6 +126,25 @@ public class @MAIN_NAME@UiTest {
128126
return screenshotFile;
129127
}
130128

129+
private static File resolveArtifactDirectory() throws IOException {
130+
String directory = System.getenv("CN1_TEST_SCREENSHOT_DIR");
131+
File outputDir = (directory != null && !directory.isEmpty()) ? new File(directory)
132+
: new File("build/ui-test-screenshots");
133+
if (!outputDir.exists() && !outputDir.mkdirs()) {
134+
throw new IOException("Failed to create screenshot directory " + outputDir.getAbsolutePath());
135+
}
136+
return outputDir;
137+
}
138+
139+
private static File resolveArtifactDirectoryForLogging() {
140+
try {
141+
return resolveArtifactDirectory();
142+
} catch (IOException ex) {
143+
System.out.println("[@MAIN_NAME@UiTest] Unable to prepare artifact directory for logging: " + ex.getMessage());
144+
return null;
145+
}
146+
}
147+
131148
private static View waitForDecorViewWithDimensions(@MAIN_NAME@Stub activity, long timeoutMillis) throws InterruptedException {
132149
long start = System.currentTimeMillis();
133150
long nextLog = start;
@@ -165,7 +182,9 @@ public class @MAIN_NAME@UiTest {
165182
}
166183

167184
private static void log(String message) {
168-
System.out.println("[@MAIN_NAME@UiTest] " + message);
185+
String formatted = "[@MAIN_NAME@UiTest] " + message;
186+
System.out.println(formatted);
187+
appendLogLine(formatted);
169188
}
170189

171190
private static void pumpSchedulers() {
@@ -174,4 +193,17 @@ public class @MAIN_NAME@UiTest {
174193
Robolectric.flushForegroundThreadScheduler();
175194
Robolectric.flushBackgroundThreadScheduler();
176195
}
196+
197+
private static synchronized void appendLogLine(String message) {
198+
File directory = resolveArtifactDirectoryForLogging();
199+
if (directory == null) {
200+
return;
201+
}
202+
File logFile = new File(directory, "@[email protected]");
203+
try (FileWriter writer = new FileWriter(logFile, true); PrintWriter out = new PrintWriter(writer)) {
204+
out.println(message);
205+
} catch (IOException ex) {
206+
System.out.println("[@MAIN_NAME@UiTest] Failed to persist log entry: " + ex.getMessage());
207+
}
208+
}
177209
}

0 commit comments

Comments
 (0)