Skip to content

Commit 25e2d07

Browse files
authored
chore: Merge 4.68.0 into master (#6881)
2 parents 45c9899 + 3315fb4 commit 25e2d07

File tree

295 files changed

+16902
-5302
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

295 files changed

+16902
-5302
lines changed

.github/scripts/run-maestro.sh

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
PLATFORM="${1:-${PLATFORM:-android}}"
5+
SHARD="${2:-${SHARD:-default}}"
6+
FLOWS_DIR=".maestro/tests"
7+
MAIN_REPORT="maestro-report.xml"
8+
MAX_RERUN_ROUNDS="${MAX_RERUN_ROUNDS:-3}"
9+
RERUN_REPORT_PREFIX="maestro-rerun"
10+
export MAESTRO_DRIVER_STARTUP_TIMEOUT="${MAESTRO_DRIVER_STARTUP_TIMEOUT:-120000}"
11+
12+
if ! command -v maestro >/dev/null 2>&1; then
13+
echo "ERROR: maestro not found in PATH"
14+
exit 2
15+
fi
16+
17+
if [ "$PLATFORM" = "android" ]; then
18+
if ! command -v adb >/dev/null 2>&1; then
19+
echo "ERROR: adb not found"
20+
exit 2
21+
fi
22+
else
23+
if ! command -v xcrun >/dev/null 2>&1; then
24+
echo "ERROR: xcrun not found"
25+
exit 2
26+
fi
27+
fi
28+
29+
MAPFILE="$(mktemp)"
30+
trap 'rm -f "$MAPFILE"' EXIT
31+
32+
while IFS= read -r -d '' file; do
33+
if grep -qE "^[[:space:]]*-[[:space:]]*['\"]?test-${SHARD}['\"]?([[:space:]]*$|[[:space:]]*,|[[:space:]]*\\])" "$file"; then
34+
raw_name="$(grep -m1 -E '^[[:space:]]*name:' "$file" || true)"
35+
if [ -n "$raw_name" ]; then
36+
name_val="$(echo "$raw_name" | sed -E 's/^[[:space:]]*name:[[:space:]]*//; s/^["'\'']//; s/["'\'']$//; s/[[:space:]]*$//')"
37+
name_val="$(echo "$name_val" | sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//')"
38+
if [ -n "$name_val" ]; then
39+
printf '%s\t%s\n' "$name_val" "$file" >> "$MAPFILE"
40+
fi
41+
fi
42+
fi
43+
done < <(find "$FLOWS_DIR" -type f \( -iname '*.yml' -o -iname '*.yaml' \) -print0)
44+
45+
if [ ! -s "$MAPFILE" ]; then
46+
echo "No flows for test-${SHARD}"
47+
exit 1
48+
fi
49+
50+
echo "Mapped flows for tag test-${SHARD}:"
51+
awk -F'\t' '{ printf " %s -> %s\n", $1, $2 }' "$MAPFILE"
52+
53+
FLOW_FILES=()
54+
SEEN_PATHS=""
55+
56+
while IFS=$'\t' read -r name path; do
57+
if ! printf '%s\n' "$SEEN_PATHS" | grep -Fqx "$path"; then
58+
FLOW_FILES+=("$path")
59+
SEEN_PATHS="${SEEN_PATHS}"$'\n'"$path"
60+
fi
61+
done < "$MAPFILE"
62+
63+
echo "Main run will execute:"
64+
printf ' %s\n' "${FLOW_FILES[@]}"
65+
66+
if [ "$PLATFORM" = "android" ]; then
67+
adb shell settings put system show_touches 1 || true
68+
adb install -r "app-experimental-release.apk" || true
69+
adb shell monkey -p "chat.rocket.reactnative" -c android.intent.category.LAUNCHER 1 || true
70+
sleep 6
71+
adb shell am force-stop "chat.rocket.reactnative" || true
72+
73+
maestro test "${FLOW_FILES[@]}" \
74+
--exclude-tags=util \
75+
--include-tags="test-${SHARD}" \
76+
--format junit \
77+
--output "$MAIN_REPORT" || true
78+
79+
else
80+
maestro test "${FLOW_FILES[@]}" \
81+
--exclude-tags=util \
82+
--include-tags="test-${SHARD}" \
83+
--exclude-tags=android-only \
84+
--format junit \
85+
--output "$MAIN_REPORT" || true
86+
fi
87+
88+
if [ ! -f "$MAIN_REPORT" ]; then
89+
echo "Main report not found"
90+
exit 1
91+
fi
92+
93+
FAILED_NAMES="$(python3 - <<PY
94+
import sys,xml.etree.ElementTree as ET
95+
try:
96+
tree = ET.parse("$MAIN_REPORT")
97+
except:
98+
sys.exit(0)
99+
root = tree.getroot()
100+
failed=[]
101+
for tc in root.findall(".//testcase"):
102+
if tc.find("failure") is not None or tc.find("error") is not None:
103+
if tc.get("name"):
104+
failed.append(tc.get("name").strip())
105+
for n in sorted(set(failed)):
106+
print(n)
107+
PY
108+
)"
109+
110+
if [ -z "$FAILED_NAMES" ]; then
111+
echo "All tests passed."
112+
exit 0
113+
fi
114+
115+
IFS=$'\n' read -rd '' -a FAILED_ARRAY <<<"$FAILED_NAMES" || true
116+
117+
CANDIDATE_FILES=()
118+
SEEN2=""
119+
for NAME in "${FAILED_ARRAY[@]}"; do
120+
FILE="$(awk -F'\t' -v n="$NAME" '$1==n {print $2; exit}' "$MAPFILE" || true)"
121+
if [ -n "$FILE" ] && ! printf '%s\n' "$SEEN2" | grep -Fq "$FILE"; then
122+
CANDIDATE_FILES+=("$FILE")
123+
SEEN2="${SEEN2}"$'\n'"${FILE}"
124+
fi
125+
done
126+
127+
if [ ${#CANDIDATE_FILES[@]} -eq 0 ]; then
128+
echo "No flow files to retry"
129+
exit 1
130+
fi
131+
132+
CURRENT_FAILS=("${CANDIDATE_FILES[@]}")
133+
ROUND=1
134+
135+
while [ ${#CURRENT_FAILS[@]} -gt 0 ] && [ "$ROUND" -le "$MAX_RERUN_ROUNDS" ]; do
136+
echo "=== RERUN ROUND $ROUND (${#CURRENT_FAILS[@]} flows) ==="
137+
138+
RPT="${RERUN_REPORT_PREFIX}-round-${ROUND}.xml"
139+
140+
if [ "$PLATFORM" = "android" ]; then
141+
maestro test "${CURRENT_FAILS[@]}" \
142+
--exclude-tags=util \
143+
--include-tags="test-${SHARD}" \
144+
--format junit \
145+
--output "$RPT" || true
146+
else
147+
maestro test "${CURRENT_FAILS[@]}" \
148+
--exclude-tags=util \
149+
--include-tags="test-${SHARD}" \
150+
--exclude-tags=android-only \
151+
--format junit \
152+
--output "$RPT" || true
153+
fi
154+
155+
if [ ! -f "$RPT" ]; then
156+
echo "Rerun report missing"
157+
break
158+
fi
159+
160+
NEXT_FAILED="$(python3 - <<PY
161+
import sys,xml.etree.ElementTree as ET
162+
try:
163+
tree = ET.parse("$RPT")
164+
except:
165+
sys.exit(0)
166+
root = tree.getroot()
167+
failed=[]
168+
for tc in root.findall(".//testcase"):
169+
if tc.find("failure") is not None or tc.find("error") is not None:
170+
if tc.get("name"):
171+
failed.append(tc.get("name").strip())
172+
for n in sorted(set(failed)):
173+
print(n)
174+
PY
175+
)"
176+
177+
if [ -z "$NEXT_FAILED" ]; then
178+
echo "All retried flows passed in this round."
179+
exit 0
180+
fi
181+
182+
IFS=$'\n' read -rd '' -a NEXT_FAILED_ARRAY <<<"$NEXT_FAILED" || true
183+
184+
NEXT_FILES=()
185+
SEEN3=""
186+
for NAME in "${NEXT_FAILED_ARRAY[@]}"; do
187+
FILE="$(awk -F'\t' -v n="$NAME" '$1==n {print $2; exit}' "$MAPFILE" || true)"
188+
if [ -n "$FILE" ] && ! printf '%s\n' "$SEEN3" | grep -Fq "$FILE"; then
189+
NEXT_FILES+=("$FILE")
190+
SEEN3="${SEEN3}"$'\n'"${FILE}"
191+
fi
192+
done
193+
194+
CURRENT_FAILS=("${NEXT_FILES[@]}")
195+
ROUND=$((ROUND+1))
196+
done
197+
198+
echo "Retry strategy finished with remaining failures:"
199+
printf '%s\n' "${CURRENT_FAILS[@]}"
200+
exit 1

.github/workflows/maestro-android.yml

Lines changed: 7 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -43,63 +43,12 @@ jobs:
4343
sudo udevadm control --reload-rules
4444
sudo udevadm trigger --name-match=kvm
4545
46-
- name: Create Maestro script
47-
run: |
48-
cat << 'EOF' > run-maestro.sh
49-
#!/bin/bash
50-
SHARD=${{ inputs.shard }}
51-
echo "Running shard: $SHARD"
52-
53-
adb shell settings put system show_touches 1
54-
adb install app-experimental-release.apk
55-
adb shell monkey -p chat.rocket.reactnative -c android.intent.category.LAUNCHER 1
56-
sleep 10
57-
adb shell am force-stop chat.rocket.reactnative
58-
export MAESTRO_DRIVER_STARTUP_TIMEOUT=120000
59-
60-
MAX_RETRIES=3
61-
ATTEMPT=1
62-
FINAL_EXIT_CODE=1
63-
64-
while [ $ATTEMPT -le $MAX_RETRIES ]; do
65-
echo "Attempt $ATTEMPT of $MAX_RETRIES"
66-
67-
echo "Starting screen recording..."
68-
adb shell screenrecord /sdcard/test_run.mp4 > /dev/null 2>&1 &
69-
RECORD_PID=$!
70-
71-
maestro test .maestro --exclude-tags=util --include-tags=test-$SHARD --format junit --output maestro-report.xml
72-
TEST_EXIT_CODE=$?
73-
74-
echo "Stopping screen recording..."
75-
kill -INT $RECORD_PID || true
76-
sleep 2
77-
78-
echo "Pulling video from device..."
79-
adb pull /sdcard/test_run.mp4 test_run_${SHARD}_attempt_${ATTEMPT}.mp4 || true
80-
adb shell rm /sdcard/test_run.mp4 || true
81-
82-
if [ $TEST_EXIT_CODE -eq 0 ]; then
83-
echo "Maestro passed on attempt $ATTEMPT"
84-
FINAL_EXIT_CODE=0
85-
break
86-
else
87-
echo "Maestro failed on attempt $ATTEMPT"
88-
fi
89-
90-
ATTEMPT=$((ATTEMPT+1))
91-
done
92-
93-
exit $FINAL_EXIT_CODE
94-
EOF
95-
96-
chmod +x run-maestro.sh
97-
env:
98-
SHARD: ${{ inputs.shard }}
46+
- name: Make Maestro script executable
47+
run: chmod +x .github/scripts/run-maestro.sh
9948

10049
- name: Start Android Emulator and Run Maestro Tests
10150
uses: reactivecircus/android-emulator-runner@v2
102-
timeout-minutes: 60
51+
timeout-minutes: 120
10352
with:
10453
api-level: 34
10554
disk-size: 4096M
@@ -111,20 +60,12 @@ jobs:
11160
force-avd-creation: false
11261
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
11362
disable-animations: true
114-
script: ./run-maestro.sh
63+
script: ./.github/scripts/run-maestro.sh android ${{ inputs.shard }}
11564

116-
- name: Upload Test Report
65+
- name: Android Maestro Logs
11766
if: always()
11867
uses: actions/upload-artifact@v4
11968
with:
120-
name: Android Test Report - Shard ${{ inputs.shard }}
121-
path: maestro-report.xml
69+
name: Android Maestro Logs - Shard ${{ inputs.shard }}
70+
path: ~/.maestro/tests/**/*.png
12271
retention-days: 7
123-
124-
- name: Upload Screen Recording
125-
if: always()
126-
uses: actions/upload-artifact@v4
127-
with:
128-
name: maestro-video-${{ inputs.shard }}
129-
path: test_run_${{ inputs.shard }}_attempt_*.mp4
130-
retention-days: 7

.github/workflows/maestro-ios.yml

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -84,40 +84,21 @@ jobs:
8484
echo "UDID=$UDID"
8585
echo "UDID=$UDID" >> $GITHUB_ENV
8686
87+
- name: Make Maestro script executable
88+
run: chmod +x .github/scripts/run-maestro.sh
89+
8790
- name: Install App
8891
run: |
8992
xcrun simctl install $UDID "ios-simulator-app"
9093
9194
- name: Run Tests
92-
id: maestro-tests
93-
uses: nick-fields/retry@v3
94-
with:
95-
max_attempts: 3
96-
timeout_minutes: 60
97-
command: |
98-
SHARD=${{ inputs.shard }}
99-
echo "Running shard: $SHARD"
100-
export MAESTRO_DRIVER_STARTUP_TIMEOUT=120000
101-
102-
maestro test .maestro \
103-
--exclude-tags=util \
104-
--include-tags=test-$SHARD \
105-
--exclude-tags=android-only \
106-
--format junit \
107-
--output maestro-report.xml
108-
109-
- name: Maestro Test Report
110-
if: always()
111-
uses: actions/upload-artifact@v4
112-
with:
113-
name: Test Report - Shard ${{ inputs.shard }}
114-
path: maestro-report.xml
115-
retention-days: 28
95+
timeout-minutes: 120
96+
run: ./.github/scripts/run-maestro.sh ios ${{ inputs.shard }}
11697

11798
- name: iOS Maestro Logs
11899
if: always()
119100
uses: actions/upload-artifact@v4
120101
with:
121102
name: iOS Maestro Logs - Shard ${{ inputs.shard }}
122-
path: ~/.maestro/tests/
123-
retention-days: 28
103+
path: ~/.maestro/tests/**/*.png
104+
retention-days: 7

.maestro/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Contains the scripts that are going to be executed by the flows before running t
3939
#### `data.js`
4040

4141
- Contains seeds to common test data, like server url, public channels, etc
42-
- Currently we point to https://mobile.rocket.chat as main server
42+
- Currently we point to https://mobile.qa.rocket.chat as main server
4343
- Pointing to a local server is not recommended yet, as you would need to create a few public channels and change some permissions
4444
- Ideally we should point to a docker or even a mocked server, but that's tbd
4545
- Try not to add new data there. Use random values instead.

.maestro/scripts/data.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const data = {
2-
server: 'https://mobile.rocket.chat',
2+
server: 'https://mobile.qa.rocket.chat',
33
alternateServer: 'https://stable.rocket.chat',
44
...output.account,
55
accounts: [],
@@ -15,4 +15,4 @@ const data = {
1515
e2eePassword: 'Password1@abcdefghijklmnopqrst'
1616
};
1717

18-
output.data = data;
18+
output.data = data;

0 commit comments

Comments
 (0)