Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/scripts-android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,61 @@ name: Test Android build scripts
jobs:
build-android:
runs-on: ubuntu-latest
outputs:
artifact_dir: ${{ steps.build-app.outputs.artifact_dir }}
app_apk: ${{ steps.build-app.outputs.app_apk }}
test_apk: ${{ steps.build-app.outputs.test_apk }}
package_name: ${{ steps.build-app.outputs.package_name }}
steps:
- uses: actions/checkout@v4
- name: Setup workspace
run: ./scripts/setup-workspace.sh -q -DskipTests
- name: Build Android port
run: ./scripts/build-android-port.sh -q -DskipTests
- name: Build Hello Codename One Android app
id: build-app
run: ./scripts/build-android-app.sh -q -DskipTests
- name: Upload Android APK artifacts
uses: actions/upload-artifact@v4
with:
name: hello-codenameone-apks
path: ${{ steps.build-app.outputs.artifact_dir }}
if-no-files-found: error

android-device-tests:
needs: build-android
runs-on: ubuntu-22.04-arm
steps:
- name: Download APK artifacts
uses: actions/download-artifact@v4
with:
name: hello-codenameone-apks
path: artifacts
- name: Launch emulator and capture screenshots
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 33
arch: arm64-v8a
profile: pixel_6
script: |
set -euxo pipefail
mkdir -p screenshots
adb install -r artifacts/${{ needs.build-android.outputs.app_apk }}
adb install -r artifacts/${{ needs.build-android.outputs.test_apk }}
adb logcat -c
adb shell monkey -p ${{ needs.build-android.outputs.package_name }} 1 || true
sleep 20
if [ -f artifacts/tests.txt ]; then
while IFS= read -r testName; do
[ -n "$testName" ] || continue
adb exec-out screencap -p > "screenshots/${testName}.png"
done < artifacts/tests.txt
Comment on lines +55 to +66

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Emulator workflow never runs the generated unit tests

The android-device-tests job installs both APKs and then immediately captures screenshots, but it never launches the unit-test APK or runs an instrumentation command. The only runtime interaction is adb shell monkey against the main application package followed by a sleep, so no tests are actually executed and the screenshots will just reflect the idle app. This means the workflow does not exercise or verify the tests it builds. Invoke the test runner (e.g. adb shell am instrument … or start the test package) before taking screenshots so the unit tests execute.

Useful? React with 👍 / 👎.

else
adb exec-out screencap -p > screenshots/test-suite.png
fi
- name: Upload emulator screenshots
uses: actions/upload-artifact@v4
with:
name: hello-codenameone-test-screenshots
path: screenshots
if-no-files-found: error
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.codename1.samples;

import com.codename1.testing.AbstractTest;
import com.codename1.ui.Component;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Label;

/**
* A simple Codename One unit test that verifies the "Hi World" label is displayed
* when {@link SampleMain} starts.
*/
public class SampleHelloTest extends AbstractTest {
@Override
public boolean runTest() throws Exception {
SampleMain app = new SampleMain();
app.init(null);
app.start();

Form current = Display.getInstance().getCurrent();
assertNotNull(current, "The main form should be visible");

Label found = findLabelWithText(current, "Hi World");
assertNotNull(found, "Expected to find the \"Hi World\" label on the form");
return true;
}

private Label findLabelWithText(Form form, String expected) {
for (int i = 0; i < form.getContentPane().getComponentCount(); i++) {
Component child = form.getContentPane().getComponentAt(i);
if (child instanceof Label) {
Label label = (Label) child;
if (expected.equals(label.getText())) {
return label;
}
}
}
return null;
}

@Override
public boolean shouldExecuteOnEDT() {
return true;
}

@Override
public String toString() {
return "SampleHelloTest";
}
}
80 changes: 79 additions & 1 deletion scripts/build-android-app.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ ba_log "Detected Codename One version $CN1_VERSION"

WORK_DIR="$TMPDIR/cn1-hello-android"
rm -rf "$WORK_DIR"; mkdir -p "$WORK_DIR"
ARTIFACTS_DIR="$WORK_DIR/artifacts"
mkdir -p "$ARTIFACTS_DIR"
TEST_LIST_FILE="$ARTIFACTS_DIR/tests.txt"
> "$TEST_LIST_FILE"

GROUP_ID="com.codenameone.examples"
ARTIFACT_ID="hello-codenameone"
Expand Down Expand Up @@ -191,6 +195,25 @@ done < <(find "$APP_DIR" -type f -name pom.xml -print0)
# 5) Build with the property set so any lingering refs resolve to the local snapshot
EXTRA_MVN_ARGS+=("-Dcodenameone.version=${CN1_VERSION}")

# --- Record discovered unit tests ---
while IFS= read -r -d '' TEST_FILE; do
REL_PATH="${TEST_FILE#$APP_DIR/}"
REL_PATH="${REL_PATH#*/src/test/java/}"
CLASS_NAME="${REL_PATH%.java}"
CLASS_NAME="${CLASS_NAME//\//.}"
if [ -n "$CLASS_NAME" ]; then
echo "$CLASS_NAME" >> "$TEST_LIST_FILE"
fi
done < <(find "$APP_DIR" -path "*/src/test/java/*.java" -print0)

if [ ! -s "$TEST_LIST_FILE" ]; then
rm -f "$TEST_LIST_FILE"
ba_log "Warning: no unit test sources were discovered"
else
ba_log "Recorded unit test classes:"
sed 's/^/[build-android-app] /' "$TEST_LIST_FILE"
fi

# (Optional) quick non-fatal checks
xmlstarlet sel -N "$NS" -t -v "/mvn:project/mvn:properties/mvn:codenameone.version" -n "$ROOT_POM" || true
xmlstarlet sel -N "$NS" -t -c "/mvn:project/mvn:build/mvn:plugins" -n "$ROOT_POM" | head -n 60 || true
Expand Down Expand Up @@ -282,4 +305,59 @@ export JAVA_HOME="$ORIGINAL_JAVA_HOME"

APK_PATH=$(find "$GRADLE_PROJECT_DIR" -path "*/outputs/apk/debug/*.apk" | head -n 1 || true)
[ -n "$APK_PATH" ] || { ba_log "Gradle build completed but no APK was found" >&2; exit 1; }
ba_log "Successfully built Android APK at $APK_PATH"
FINAL_APP_APK="$ARTIFACTS_DIR/${ARTIFACT_ID}-debug.apk"
cp "$APK_PATH" "$FINAL_APP_APK"
ba_log "Successfully built Android APK at $APK_PATH"
ba_log "Copied Android APK to $FINAL_APP_APK"

ba_log "Building Android unit test APK"
rm -rf "$APP_DIR/android/target"
xvfb-run -a "${MAVEN_CMD[@]}" -q -f "$APP_DIR/pom.xml" package \
-DskipTests \
-Dcodename1.platform=android \
-Dcodename1.buildTarget=android-source \
-Dcodename1.arg.build.unitTest=1 \
-Dopen=false \
"${EXTRA_MVN_ARGS[@]}"

GRADLE_PROJECT_DIR=$(find "$APP_DIR/android/target" -maxdepth 2 -type d -name "*-android-source" | head -n 1 || true)
[ -n "$GRADLE_PROJECT_DIR" ] || { ba_log "Failed to locate generated Android project for unit tests" >&2; exit 1; }

ba_log "Invoking Gradle build for unit test project in $GRADLE_PROJECT_DIR"
chmod +x "$GRADLE_PROJECT_DIR/gradlew"
ORIGINAL_JAVA_HOME="$JAVA_HOME"
export JAVA_HOME="$JAVA17_HOME"
(
cd "$GRADLE_PROJECT_DIR"
if command -v sdkmanager >/dev/null 2>&1; then
yes | sdkmanager --licenses >/dev/null 2>&1 || true
elif [ -x "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" ]; then
yes | "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" --licenses >/dev/null 2>&1 || true
fi
./gradlew --no-daemon assembleDebug
)
export JAVA_HOME="$ORIGINAL_JAVA_HOME"

UNIT_TEST_APK_PATH=$(find "$GRADLE_PROJECT_DIR" -path "*/outputs/apk/debug/*.apk" | head -n 1 || true)
[ -n "$UNIT_TEST_APK_PATH" ] || { ba_log "Gradle unit test build completed but no APK was found" >&2; exit 1; }
FINAL_TEST_APK="$ARTIFACTS_DIR/${ARTIFACT_ID}-tests-debug.apk"
cp "$UNIT_TEST_APK_PATH" "$FINAL_TEST_APK"
ba_log "Successfully built Android unit test APK at $UNIT_TEST_APK_PATH"
ba_log "Copied Android unit test APK to $FINAL_TEST_APK"

TESTS_METADATA=$(find "$APP_DIR" -name tests.dat | head -n 1 || true)
if [ -n "$TESTS_METADATA" ]; then
cp "$TESTS_METADATA" "$ARTIFACTS_DIR/tests.dat"
ba_log "Copied test metadata to $ARTIFACTS_DIR/tests.dat"
else
ba_log "Warning: tests.dat metadata file not found"
fi

if [ -n "${GITHUB_OUTPUT:-}" ]; then
{
echo "artifact_dir=$ARTIFACTS_DIR"
echo "app_apk=$(basename "$FINAL_APP_APK")"
echo "test_apk=$(basename "$FINAL_TEST_APK")"
echo "package_name=$PACKAGE_NAME"
} >> "$GITHUB_OUTPUT"
fi
Loading