Skip to content

ALFMOB-178 | Full Integration of Tests Creation and Executions, Metrics Evaluation and CI/CD Setup #41

ALFMOB-178 | Full Integration of Tests Creation and Executions, Metrics Evaluation and CI/CD Setup

ALFMOB-178 | Full Integration of Tests Creation and Executions, Metrics Evaluation and CI/CD Setup #41

name: Alfie Melmac Test Automation
on:
push:
branches:
- main
pull_request:
workflow_dispatch:
schedule:
- cron: "0 3 * * *" # Every day at 3am UTC
jobs:
test:
runs-on: macos-15
env:
APP_URL: "https://github.com/Mindera/Alfie-UITests/releases/download/asdsad/Alfie.apk"
APP_ZIP_URL: "https://github.com/Mindera/Alfie-UITests/releases/download/asdsad/Alfie.zip"
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up JDK
uses: actions/setup-java@v3
with:
distribution: "temurin"
java-version: "17"
- name: Set up Android SDK
uses: android-actions/setup-android@v3
- name: List installed Xcode versions
run: ls -l /Applications | grep Xcode
- name: Install Android system image (arm64)
run: sdkmanager "system-images;android-35;google_apis;arm64-v8a"
- name: Create Android AVD (arm64)
run: echo "no" | avdmanager create avd -n Medium_Phone_API_35 -k "system-images;android-35;google_apis;arm64-v8a"
- name: List Android devices
run: |
echo "=== Emulator List ==="
emulator -list-avds
echo "=== AVD List ==="
avdmanager list avd
echo "=== Connected Devices ==="
adb devices
- name: Select Xcode version
run: sudo xcode-select -s /Applications/Xcode_16.3.0.app/Contents/Developer
- name: Show Xcode version
run: xcodebuild -version
- name: Show available iOS simulators
run: xcrun simctl list devices
- name: Generate Gradle Wrapper
working-directory: Melmac
run: |
gradle wrapper --gradle-version 8.13
- name: Make Gradle Wrapper executable
working-directory: Melmac
run: |
chmod +x gradlew
- name: Build Melmac
working-directory: Melmac
run: |
./gradlew build
- name: Prepare apps folder and download artifacts
working-directory: Melmac
run: |
mkdir -p src/main/resources/apps
echo "Downloading APK from $APP_URL"
curl -L "$APP_URL" -o src/main/resources/apps/Alfie.apk
echo "Downloading app bundle ZIP from $APP_ZIP_URL"
curl -L "$APP_ZIP_URL" -o src/main/resources/apps/Alfie.zip
cd src/main/resources/apps
unzip -o Alfie.zip
rm Alfie.zip
echo "Listing contents of src/main/resources/apps:"
ls -l
- name: Start backend
working-directory: Melmac
env:
CI: true
run: ./gradlew run > $GITHUB_WORKSPACE/backend.log 2>&1 &
- name: Tail backend logs in background
working-directory: Melmac
run: tail -F ../backend.log &
- name: Wait for backend to be ready
run: |
for i in {1..30}; do # Wait up to 1 minute
if curl -s http://localhost:8080/; then
echo "Backend is up!"
exit 0
fi
sleep 2
done
echo "Backend did not start in time" >&2
exit 1
- name: Debug backend process if startup fails
if: failure()
run: |
echo "==== Java processes ===="
ps aux | grep '[j]ava' || true
echo "==== Ports in use ===="
lsof -i :8080 || true
echo "==== Backend logs ===="
cat backend.log || echo "No backend.log file found"
- name: Create test suite
working-directory: Melmac
run: |
mkdir -p results
curl -s -X POST http://localhost:8080/test-suites \
-H "Content-Type: application/json" \
-d '{
"testSuiteName": "My Test Suite",
"testSuiteDescription": "Description of my test suite"
}' | tee results/test_suite.json
export TEST_SUITE_ID=$(jq '.testSuiteId' results/test_suite.json)
echo "TEST_SUITE_ID=$TEST_SUITE_ID" >> $GITHUB_ENV
- name: Create Android test plan
working-directory: Melmac
run: |
curl -s -X POST http://localhost:8080/test-plans \
-H "Content-Type: application/json" \
-d "{
\"notes\": \"Test plan for App Startup Time metric\",
\"testName\": \"Startup Time Plan\",
\"metricMetricId\": 1,
\"deviceName\": \"Medium_Phone_API_35\",
\"appName\": \"Alfie.apk\",
\"appVersion\": \"0.8.0\",
\"appPackage\": \"au.com.alfie.ecomm.debug\",
\"mainActivity\": \"au.com.alfie.ecomm.MainActivity\",
\"executionTypeExecutionTypeId\": 1,
\"thresholds\": [
{
\"targetValue\": 100,
\"thresholdTypeThresholdTypeId\": 2,
\"metricOutputMetricOutputId\": 1
}
],
\"metricParameters\": [
{
\"parameterValue\": \"home-tab\",
\"metricParameterMetricParameterId\": 1
}
],
\"executionTypeParameters\": [],
\"testSuiteVersionId\": ${TEST_SUITE_ID}
}"
- name: Create iOS test plan
working-directory: Melmac
run: |
curl -s -X POST http://localhost:8080/test-plans \
-H "Content-Type: application/json" \
-d "{
\"notes\": \"Test plan for App Startup Time metric\",
\"testName\": \"Startup Time Plan\",
\"metricMetricId\": 1,
\"deviceName\": \"iPhone 16 Pro\",
\"appName\": \"Alfie.app\",
\"appVersion\": \"0.8.1\",
\"appPackage\": \"com.mindera.alfie.debug\",
\"executionTypeExecutionTypeId\": 1,
\"thresholds\": [
{
\"targetValue\": 10000,
\"thresholdTypeThresholdTypeId\": 1,
\"metricOutputMetricOutputId\": 1
}
],
\"metricParameters\": [
{
\"parameterValue\": \"account-btn\",
\"metricParameterMetricParameterId\": 1
},
{
\"parameterValue\": \"50000\",
\"metricParameterMetricParameterId\": 2
}
],
\"executionTypeParameters\": [],
\"testSuiteVersionId\": ${TEST_SUITE_ID}
}"
- name: Run full test suite
working-directory: Melmac
run: |
mkdir -p results
curl -X POST "http://localhost:8080/test-suites/${TEST_SUITE_ID}/run" > results/execution.json
# --- Results summary generation in table format ---
- name: Generate Markdown summary from suite results
run: |
mkdir -p results
suiteExecutionId=$(jq '.suiteExecutionId' results/suite_execution.json)
testSuiteVersionId=$(jq '.testSuiteVersionTestSuiteVersionId' results/suite_execution.json)
echo "## Performance Test Suite Results" > results/summary.md
echo "" >> results/summary.md
echo "**Suite Execution ID:** $suiteExecutionId " >> results/summary.md
echo "**Test Suite Version ID:** $testSuiteVersionId" >> results/summary.md
echo "" >> results/summary.md
echo "### Test Execution Results" >> results/summary.md
echo "| Test Execution ID | Passed | Start Time | End Time | Test Plan Version ID |" >> results/summary.md
echo "|-------------------|--------|------------|----------|----------------------|" >> results/summary.md
jq -r '.executionResults[] | "| \(.testExecutionId) | \(.passed) | \(.initialTimestamp) | \(.endTimestamp) | \(.testPlanVersionTestPlanVersionId) |"' results/suite_execution.json >> results/summary.md
echo "" >> results/summary.md
# For each test execution, fetch and print thresholds and metric outputs
jq -c '.executionResults[]' results/suite_execution.json | while read -r exec; do
testExecutionId=$(echo "$exec" | jq '.testExecutionId')
testPlanVersionId=$(echo "$exec" | jq '.testPlanVersionTestPlanVersionId')
echo "#### Thresholds for Test Execution ID $testExecutionId" >> results/summary.md
echo "| Target Value | Threshold Type | Metric Output ID |" >> results/summary.md
echo "|--------------|---------------|------------------|" >> results/summary.md
curl -s "http://localhost:8080/thresholds?testPlanVersionId=$testPlanVersionId" | jq -r '.[] | "| \(.targetValue) | \(.thresholdTypeThresholdTypeId) | \(.metricOutputMetricOutputId) |"' >> results/summary.md
echo "" >> results/summary.md
echo "#### Metric Output Results for Test Execution ID $testExecutionId" >> results/summary.md
echo "| Metric Output Name | Value |" >> results/summary.md
echo "|--------------------|-------|" >> results/summary.md
curl -s "http://localhost:8080/test-executions/outputs?testExecutionId=$testExecutionId" | jq -r '.[] | "| \(.metricOutputName // "N/A") | \(.value // "N/A") |"' >> results/summary.md
echo "" >> results/summary.md
done
echo "### Raw Suite Execution Result" >> results/summary.md
jq . results/suite_execution.json >> results/summary.md
- name: Upload test results artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: performance-test-results
path: results/summary.md
- name: Add results to GitHub Actions summary
if: always()
run: |
if [ -f results/summary.md ]; then
cat results/summary.md >> $GITHUB_STEP_SUMMARY
else
echo "No summary file found." >> $GITHUB_STEP_SUMMARY
fi
- name: Comment results on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
let body = "No summary file found.";
if (fs.existsSync('results/summary.md')) {
body = fs.readFileSync('results/summary.md', 'utf8');
}
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `### 📝 Performance Test Results\n\n${body}`
});
- name: Upload backend log
if: always()
uses: actions/upload-artifact@v4
with:
name: backend-log
path: backend.log