FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
pythonnative/scripts/run-e2e.sh at main · pythonnative/pythonnative · GitHub
pythonnative
/
pythonnative
Public
Notifications
You must be signed in to change notification settings
Fork
23
Star
131
Code
Issues
11
Pull requests
4
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
pythonnative
/
scripts
/
run-e2e.sh
Copy path
More file actions
More file actions
Latest commit
History
History
History
executable file
·
169 lines (153 loc) · 6.12 KB
Breadcrumbs
pythonnative
/
scripts
/
run-e2e.sh
Copy path
File metadata and controls
executable file
·
169 lines (153 loc) · 6.12 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!
/usr/bin/env bash
#
Build the e2e-suite example app and run the comprehensive Maestro suite.
#
#
This script is the supported way for AI agents and humans to run the
#
full E2E pass locally. It mirrors what CI does in .github/workflows/e2e.yml.
#
#
Usage:
#
./scripts/run-e2e.sh android [suite ...]
#
./scripts/run-e2e.sh ios [suite ...]
#
#
Examples:
#
./scripts/run-e2e.sh android # full suite
#
./scripts/run-e2e.sh android components # only the components suite
#
./scripts/run-e2e.sh ios hooks # only the hooks suite on iOS
#
./scripts/run-e2e.sh android hooks navigation # two categories, one session
#
#
Available suites: inbox, full, components, hooks, navigation, layout, styling,
#
animations, gestures, assets, misc. The components and hooks categories also
#
have lettered parts (components-a/b/c, hooks-a/b) that CI's Android shards
#
run separately.
#
#
Multiple category suites can be passed at once; they run sequentially in
#
a single Maestro session (and against a single emulator/simulator boot).
#
CI uses this to shard the Android run into a few balanced groups so no
#
single emulator session has to survive the entire 60-flow marathon;
#
GitHub-hosted Android emulators grow unstable under ~15 minutes of
#
sustained Maestro driving and start reporting "device offline". See
#
.github/workflows/e2e.yml and tests/e2e/AGENTS.md.
#
#
Prerequisites:
#
- `pn` CLI available (e.g. via `uv sync`, then run through `uv run`).
#
- `maestro` CLI on PATH (https://maestro.dev/).
#
- For Android: an emulator running.
#
- For iOS: a simulator running.
#
#
The script:
#
1. Builds + installs the e2e-suite app via `pn run <platform> --no-logs`.
#
2. Resolves each requested suite to its Maestro YAML target.
#
3. Runs `maestro test` (over all targets) up to ``MAESTRO_MAX_ATTEMPTS``
#
times (default 2) and exits with the last attempt's exit code.
#
#
A successful run prints "All E2E suites passed." at the end and exits 0.
#
Any failed flow is reported by Maestro in its standard format; see
#
tests/e2e/AGENTS.md for guidance on interpreting failures.
set
-euo pipefail
SCRIPT_DIR=
"
$(
cd
"
$(
dirname
"
${BASH_SOURCE[0]}
"
)
"
&&
pwd
)
"
ROOT_DIR=
"
$(
cd
"
$SCRIPT_DIR
/..
"
&&
pwd
)
"
cd
"
$ROOT_DIR
"
PLATFORM=
"
${1
:-
android}
"
shift
||
true
#
Remaining args are suite names; default to the full aggregate suite.
SUITES=(
"
$@
"
)
if
[[
${
#
SUITES[@]}
-eq
0 ]]
;
then
SUITES=(
"
full
"
)
fi
case
"
$PLATFORM
"
in
android|ios) ;;
*
)
echo
"
Error: platform must be 'android' or 'ios' (got:
$PLATFORM
)
"
>&2
exit
2
;;
esac
if
!
command
-v pn
>
/dev/null
;
then
echo
"
Error: 'pn' CLI not found on PATH. Run 'uv sync', then invoke this
"
>&2
echo
"
script through 'uv run ./scripts/run-e2e.sh ...'.
"
>&2
exit
2
fi
if
!
command
-v maestro
>
/dev/null
;
then
echo
"
Error: 'maestro' CLI not found on PATH.
"
>&2
echo
"
Install: curl -Ls 'https://get.maestro.mobile.dev' | bash
"
>&2
exit
2
fi
if
[[
"
${SUITES[*]}
"
==
"
inbox
"
]]
;
then
exec
"
$SCRIPT_DIR
/run-inbox-e2e.sh
"
"
$PLATFORM
"
fi
#
Resolve the app/bundle id straight from the example's pythonnative.toml so
#
this stays correct no matter what id the config declares.
APP_ID=
"
$(
cd examples/e2e-suite
&&
pn app-id
"
$PLATFORM
"
)
"
if
[[
-z
"
$APP_ID
"
]]
;
then
echo
"
Error: could not resolve APP_ID via 'pn app-id
$PLATFORM
'.
"
>&2
exit
2
fi
#
Resolve each requested suite to a Maestro YAML target. ``full`` expands
#
to the platform's master aggregate; the category names map to the
#
per-category suite files under tests/e2e/suites/.
MAESTRO_TARGETS=()
for
suite
in
"
${SUITES[@]}
"
;
do
case
"
$suite
"
in
full)
if
[[
"
$PLATFORM
"
==
"
android
"
]]
;
then
MAESTRO_TARGETS+=(
"
tests/e2e/android.yaml
"
)
else
MAESTRO_TARGETS+=(
"
tests/e2e/ios.yaml
"
)
fi
;;
components|components-a|components-b|components-c|hooks|hooks-a|hooks-b|navigation|layout|styling|animations|gestures|assets|misc)
MAESTRO_TARGETS+=(
"
tests/e2e/suites/
${suite}
.yaml
"
)
;;
*
)
echo
"
Error: unknown suite '
$suite
'
"
>&2
echo
"
Available suites: full, components, components-a, components-b, components-c, hooks, hooks-a, hooks-b, navigation, layout, styling, animations, gestures, assets, misc
"
>&2
exit
2
;;
esac
done
printf
"
\n==> Building e2e-suite app for %s\n
"
"
$PLATFORM
"
pushd
examples/e2e-suite
>
/dev/null
pn run
"
$PLATFORM
"
--no-logs
popd
>
/dev/null
run_maestro
() {
if
[[
"
$PLATFORM
"
==
"
ios
"
]]
;
then
maestro --platform ios
test
-e
"
APP_ID=
$APP_ID
"
"
${MAESTRO_TARGETS[@]}
"
else
maestro
test
-e
"
APP_ID=
$APP_ID
"
"
${MAESTRO_TARGETS[@]}
"
fi
}
printf
"
\n==> Running Maestro suite(s): %s\n
"
"
${MAESTRO_TARGETS[*]}
"
#
Maestro's iOS XCUITest driver occasionally loses its connection to the
#
app during long suites and surfaces transient "Application is not
#
running" / "Request for viewHierarchy failed" errors that have nothing
#
to do with the test under test. Allow one automatic retry of the whole
#
suite (overridable via ``MAESTRO_MAX_ATTEMPTS``) so CI doesn't fail on
#
driver flakes. A retry can also mask a genuine race in the suite, so
#
treat the "retrying..." line as a signal to investigate, not just to
#
trust the second pass.
#
Kill the app so the next Maestro attempt starts from a cold launch
#
(open_demo relaunches a dead app). A failed attempt can leave the app
#
mid-demo with dirty in-process state (e.g. module-level counters some
#
demos display), which would make a same-process retry fail assertions
#
that hold on a first visit.
terminate_app
() {
if
[[
"
$PLATFORM
"
==
"
ios
"
]]
;
then
xcrun simctl terminate booted
"
$APP_ID
"
2>
/dev/null
||
true
else
adb shell am force-stop
"
$APP_ID
"
2>
/dev/null
||
true
fi
}
MAX_ATTEMPTS=
"
${MAESTRO_MAX_ATTEMPTS
:-
2}
"
attempt=1
while
((
attempt
<=
MAX_ATTEMPTS
))
;
do
if
run_maestro
;
then
break
fi
if
((
attempt
==
MAX_ATTEMPTS
))
;
then
printf
"
\nMaestro suite failed after %d attempt(s).\n
"
"
$attempt
"
>&2
exit
1
fi
printf
"
\n==> Maestro suite failed (attempt %d/%d); restarting app and retrying...\n
"
\
"
$attempt
"
"
$MAX_ATTEMPTS
"
>&2
terminate_app
attempt=
$((
attempt
+
1
))
done
printf
"
\nAll E2E suites passed.\n
"
Back
|
FazBrowse Home
|
New Git URL