Skip to content

Commit 7ef8583

Browse files
committed
Switched to androidx testing
1 parent 4151c2a commit 7ef8583

File tree

1 file changed

+119
-72
lines changed

1 file changed

+119
-72
lines changed

scripts/build-android-app.sh

Lines changed: 119 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ xmlstarlet sel -N "$NS" -t -c "/mvn:project/mvn:build/mvn:plugins" -n "$ROOT_POM
201201
[ -f "$APP_DIR/build.sh" ] && chmod +x "$APP_DIR/build.sh"
202202

203203
SETTINGS_FILE="$APP_DIR/common/codenameone_settings.properties"
204+
echo "codename1.arg.android.useAndroidX=true" >> "$SETTINGS_FILE"
204205
[ -f "$SETTINGS_FILE" ] || { ba_log "codenameone_settings.properties not found at $SETTINGS_FILE" >&2; exit 1; }
205206

206207
# --- Read settings ---
@@ -266,112 +267,158 @@ if [ -z "$GRADLE_PROJECT_DIR" ]; then
266267
fi
267268

268269
ba_log "Configuring instrumentation test sources in $GRADLE_PROJECT_DIR"
270+
271+
# Ensure AndroidX flags in gradle.properties
272+
GRADLE_PROPS="$GRADLE_PROJECT_DIR/gradle.properties"
273+
grep -q '^android.useAndroidX=' "$GRADLE_PROPS" 2>/dev/null || echo 'android.useAndroidX=true' >> "$GRADLE_PROPS"
274+
grep -q '^android.enableJetifier=' "$GRADLE_PROPS" 2>/dev/null || echo 'android.enableJetifier=true' >> "$GRADLE_PROPS"
275+
269276
APP_BUILD_GRADLE="$GRADLE_PROJECT_DIR/app/build.gradle"
270-
if [ -f "$APP_BUILD_GRADLE" ]; then
271-
python3 - "$APP_BUILD_GRADLE" <<'PYTHON'
272-
import pathlib
273-
import re
274-
import sys
277+
ROOT_BUILD_GRADLE="$GRADLE_PROJECT_DIR/build.gradle"
275278

276-
path = pathlib.Path(sys.argv[1])
277-
text = path.read_text()
278-
modified = False
279+
# Add google()/mavenCentral() to repositories blocks (root + app), but don't touch dependencies
280+
for F in "$ROOT_BUILD_GRADLE" "$APP_BUILD_GRADLE"; do
281+
if [ -f "$F" ]; then
282+
if ! grep -q 'repositories[[:space:]]*{' "$F"; then
283+
cat >> "$F" <<'EOS'
284+
285+
repositories {
286+
google()
287+
mavenCentral()
288+
}
289+
EOS
290+
else
291+
# insert only if missing
292+
grep -q 'google()' "$F" || sed -E -i '0,/repositories[[:space:]]*\{/s//repositories {\n google()\n mavenCentral()/' "$F"
293+
grep -q 'mavenCentral()' "$F" || sed -E -i '0,/repositories[[:space:]]*\{/s//repositories {\n google()\n mavenCentral()/' "$F"
294+
fi
295+
fi
296+
done
279297

280-
if "android.test.InstrumentationTestRunner" not in text:
281-
def add_runner(match):
282-
prefix = match.group(0)
283-
return prefix + "\n testInstrumentationRunner \"android.test.InstrumentationTestRunner\""
298+
if [ -f "$APP_BUILD_GRADLE" ]; then
299+
python3 - "$APP_BUILD_GRADLE" <<'PY'
300+
import sys, re, pathlib
301+
p = pathlib.Path(sys.argv[1])
302+
txt = p.read_text()
303+
orig = txt
304+
modified = False
284305
285-
new_text, count = re.subn(r"(defaultConfig\s*\{)", add_runner, text, count=1, flags=re.MULTILINE)
286-
if count:
287-
text = new_text
306+
def strip_block(name, s):
307+
return re.sub(rf'(?ms)^\s*{name}\s*\{{.*?\}}\s*', '', s)
308+
module_view = strip_block('buildscript', txt)
309+
module_view = strip_block('pluginManagement', module_view)
310+
311+
# Runner -> AndroidX
312+
if "androidx.test.runner.AndroidJUnitRunner" not in module_view:
313+
t2, n = re.subn(r'(?m)^\s*testInstrumentationRunner\s*".*?"\s*$',
314+
' testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"', txt)
315+
if n == 0:
316+
t2, n = re.subn(r'(?m)(^\s*defaultConfig\s*\{)',
317+
r'\1\n testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"', txt, count=1)
318+
if n == 0:
319+
t2, n = re.subn(r'(?ms)(^\s*android\s*\{)',
320+
r'\1\n defaultConfig {\n testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"\n }', txt, count=1)
321+
if n:
322+
txt = t2
323+
module_view = strip_block('buildscript', txt)
324+
module_view = strip_block('pluginManagement', module_view)
288325
modified = True
289-
else:
290-
raise SystemExit("defaultConfig block not found while adding instrumentation runner")
291326
292-
libraries = [
293-
"useLibrary 'android.test.base'",
294-
"useLibrary 'android.test.mock'",
295-
"useLibrary 'android.test.runner'",
296-
]
327+
# Remove legacy useLibrary
328+
t2, n = re.subn(r'(?m)^\s*useLibrary\s+\'android\.test\.(base|mock|runner)\'\s*$', '', txt)
329+
if n:
330+
txt = t2
331+
module_view = strip_block('buildscript', txt)
332+
module_view = strip_block('pluginManagement', module_view)
333+
modified = True
334+
335+
# Pick config name (modern vs legacy)
336+
uses_modern = re.search(r'(?m)^\s*(implementation|api|testImplementation|androidTestImplementation)\b', module_view) is not None
337+
conf = "androidTestImplementation" if uses_modern else "androidTestCompile"
297338
298-
missing_libraries = [lib for lib in libraries if lib not in text]
299-
if missing_libraries:
300-
match = re.search(r"^(\s*android\s*\{)", text, flags=re.MULTILINE)
301-
if not match:
302-
raise SystemExit("android block not found while adding instrumentation libraries")
303-
line = match.group(1)
304-
indent = re.match(r"^(\s*)", line).group(1)
305-
insertion = "".join(f"\n{indent} {lib}" for lib in missing_libraries)
306-
text = text[: match.end()] + insertion + text[match.end():]
339+
# Append deps block at EOF (module-level)
340+
needed = [
341+
("androidx.test:ext:junit:1.1.5", conf), # <-- provides AndroidJUnit4
342+
("androidx.test:runner:1.5.2", conf),
343+
("androidx.test:core:1.5.0", conf),
344+
("androidx.test.services:storage:1.4.2", conf),
345+
]
346+
to_add = [(coord, c) for coord, c in needed if coord not in module_view]
347+
if to_add:
348+
block = "\n\ndependencies {\n" + "".join([f" {c} \"{coord}\"\n" for coord, c in to_add]) + "}\n"
349+
txt = txt.rstrip() + block
307350
modified = True
308351
309-
if modified:
310-
if not text.endswith("\n"):
311-
text += "\n"
312-
path.write_text(text)
313-
PYTHON
314-
ba_log "Ensured instrumentation runner and libraries are declared"
315-
else
316-
ba_log "Warning: Gradle build file not found at $APP_BUILD_GRADLE; skipping instrumentation dependency configuration" >&2
352+
if modified and txt != orig:
353+
if not txt.endswith("\n"): txt += "\n"
354+
p.write_text(txt)
355+
print(f"Patched app/build.gradle (deps via {conf}, appended at EOF)")
356+
else:
357+
print("No changes needed in app/build.gradle")
358+
PY
359+
ba_log "Applied AndroidX test runner/deps (EOF append, module-only)"
317360
fi
318361

362+
echo "----- app/build.gradle tail -----"
363+
tail -n 80 "$APP_BUILD_GRADLE" | sed 's/^/| /'
364+
echo "---------------------------------"
365+
319366
TEST_SRC_DIR="$GRADLE_PROJECT_DIR/app/src/androidTest/java/${PACKAGE_PATH}"
320367
mkdir -p "$TEST_SRC_DIR"
321368
TEST_CLASS="$TEST_SRC_DIR/HelloCodenameOneInstrumentedTest.java"
322-
cat >"$TEST_CLASS" <<EOF
323-
package $PACKAGE_NAME;
324-
325-
import android.content.Context;
326-
import android.test.InstrumentationTestCase;
369+
cat >"$TEST_CLASS" <<'EOF'
370+
package @PACKAGE@;
327371
328372
import android.app.Instrumentation;
329373
import android.os.ParcelFileDescriptor;
330-
import android.util.Base64;
331374
332-
import java.io.FileInputStream;
333-
import java.io.IOException;
375+
import androidx.test.ext.junit.runners.AndroidJUnit4;
376+
import androidx.test.platform.app.InstrumentationRegistry;
377+
import androidx.test.services.storage.TestStorage;
378+
import androidx.test.core.app.ApplicationProvider;
379+
380+
import org.junit.Test;
381+
import org.junit.runner.RunWith;
382+
334383
import java.io.InputStream;
384+
import java.io.FileInputStream;
385+
import java.io.OutputStream;
386+
import java.io.ByteArrayOutputStream;
335387
336-
public class HelloCodenameOneInstrumentedTest extends InstrumentationTestCase {
388+
import static org.junit.Assert.assertEquals;
337389
338-
public void testUseAppContext() {
339-
Context appContext = getInstrumentation().getTargetContext();
340-
assertEquals("$PACKAGE_NAME", appContext.getPackageName());
341-
}
390+
@RunWith(AndroidJUnit4.class)
391+
public class HelloCodenameOneInstrumentedTest {
342392
343-
private static final int CHUNK = 200_000;
393+
@Test
394+
public void testUseAppContext_andSaveScreenshot() throws Exception {
395+
// Keep your assertion
396+
String expectedPkg = "@PACKAGE@";
397+
String actualPkg = ApplicationProvider.getApplicationContext().getPackageName();
398+
assertEquals(expectedPkg, actualPkg);
344399
345-
public static void printPngToStdout(Instrumentation inst) {
346-
try {
400+
// Capture PNG from emulator
401+
Instrumentation inst = InstrumentationRegistry.getInstrumentation();
347402
ParcelFileDescriptor pfd = inst.getUiAutomation().executeShellCommand("screencap -p");
348-
byte[] png;
349-
try (InputStream in = new FileInputStream(pfd.getFileDescriptor())) {
350-
png = readAll(in);
351-
}
352-
String b64 = Base64.encodeToString(png, Base64.NO_WRAP);
353-
System.out.println("<<CN1_SCREENSHOT_BEGIN>>");
354-
for (int i = 0; i < b64.length(); i += CHUNK) {
355-
int end = Math.min(i + CHUNK, b64.length());
356-
System.out.println(b64.substring(i, end));
403+
byte[] png = readAll(new FileInputStream(pfd.getFileDescriptor()));
404+
405+
// Write to AndroidX TestStorage (runner copies back to host)
406+
try (OutputStream out = TestStorage.openOutputFile("emulator-screenshot.png")) {
407+
out.write(png);
357408
}
358-
System.out.println("<<CN1_SCREENSHOT_END>>");
359-
System.out.flush();
360-
} catch (IOException err) {
361-
err.printStackTrace();
362-
throw new RuntimeException(err);
363-
}
409+
System.out.println("WROTE_TO_TEST_STORAGE:emulator-screenshot.png");
364410
}
365411
366-
private static byte[] readAll(InputStream in) throws IOException {
412+
private static byte[] readAll(InputStream in) throws Exception {
367413
byte[] buf = new byte[64 * 1024];
368414
int n;
369-
java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
415+
ByteArrayOutputStream out = new ByteArrayOutputStream();
370416
while ((n = in.read(buf)) != -1) out.write(buf, 0, n);
371417
return out.toByteArray();
372418
}
373419
}
374420
EOF
421+
sed -i "s|@PACKAGE@|$PACKAGE_NAME|g" "$TEST_CLASS"
375422
ba_log "Created instrumentation test at $TEST_CLASS"
376423

377424
DEFAULT_ANDROID_TEST="$GRADLE_PROJECT_DIR/app/src/androidTest/java/com/example/myapplication2/ExampleInstrumentedTest.java"

0 commit comments

Comments
 (0)