feat(test): add Maestro end-to-end coverage

This commit is contained in:
edde746
2026-07-15 06:40:35 +02:00
parent ddb7520ce8
commit 139cf83507
50 changed files with 3961 additions and 20 deletions
+14
View File
@@ -0,0 +1,14 @@
flows:
- "flows/*.yaml"
testOutputDir: "build/maestro"
executionOrder:
continueOnFailure: false
flowsOrder:
- Fresh install authentication choices
- Jellyfin onboarding reaches Home
- Browse library and open media details
- Search media and open a result
- Start and exit video playback
- Open empty downloads state
- Manage profiles and open settings
- Logout returns to authentication
+33
View File
@@ -0,0 +1,33 @@
appId: com.edde746.plezy
name: Fresh install authentication choices
tags:
- e2e
- auth
---
- retry:
maxRetries: 1
commands:
- launchApp:
clearState: true
permissions:
all: allow
- extendedWaitUntil:
visible: "(?s)^(?:Sign in with Plex|Wait).*"
timeout: 30000
- tapOn:
text: "Wait"
optional: true
- extendedWaitUntil:
visible: "Sign in with Plex"
timeout: 30000
- assertVisible: "Show QR Code"
- assertVisible: "Connect to Jellyfin"
- tapOn: "Connect to Jellyfin"
- extendedWaitUntil:
visible: "Add Jellyfin server"
timeout: 10000
- assertVisible: "(?s)Server URLs.*"
- assertVisible: "Find server"
- hideKeyboard
- back
- assertVisible: "Sign in with Plex"
+13
View File
@@ -0,0 +1,13 @@
appId: com.edde746.plezy
name: Jellyfin onboarding reaches Home
tags:
- e2e
- onboarding
---
- runFlow: ../subflows/onboard_jellyfin.yaml
- assertVisible: "(?s)^Home.*"
- assertVisible: "(?s)^Recently Added.*"
- assertVisible: "(?s).*Zulu Zone 4.*"
- assertVisible: "(?s)^Libraries.*"
- assertVisible: "(?s)^Search.*"
- assertVisible: "(?s)^Downloads.*"
+22
View File
@@ -0,0 +1,22 @@
appId: com.edde746.plezy
name: Browse library and open media details
tags:
- e2e
- library
---
- runFlow: ../subflows/onboard_jellyfin.yaml
- tapOn: "(?s)^Libraries.*"
- extendedWaitUntil:
visible: "Maestro Movies"
timeout: 15000
- extendedWaitUntil:
visible: "(?s).*Zulu Zone 4$"
timeout: 15000
- tapOn: "(?s).*Zulu Zone 4$"
- extendedWaitUntil:
visible: "Overview"
timeout: 15000
- assertVisible: "A deterministic title for TV alphabet focus coverage."
- assertVisible: "Play"
- back
- assertVisible: "Maestro Movies"
+24
View File
@@ -0,0 +1,24 @@
appId: com.edde746.plezy
name: Search media and open a result
tags:
- e2e
- search
---
- runFlow: ../subflows/onboard_jellyfin.yaml
- tapOn: "(?s)^Search.*"
- extendedWaitUntil:
visible: "Search movies, shows, music..."
timeout: 10000
- tapOn: "Search movies, shows, music..."
- inputText: "Maestro"
- hideKeyboard
- extendedWaitUntil:
visible: "Maestro Movie"
timeout: 15000
- tapOn: "Maestro Movie"
- extendedWaitUntil:
visible: "Overview"
timeout: 15000
- assertVisible: "A deterministic movie used to verify Plezy's end-to-end flows."
- back
- assertVisible: "(?s)^Maestro Movie.*"
+29
View File
@@ -0,0 +1,29 @@
appId: com.edde746.plezy
name: Start and exit video playback
tags:
- e2e
- playback
---
- runFlow: ../subflows/onboard_jellyfin.yaml
- tapOn: "(?s)^Libraries.*"
- extendedWaitUntil:
visible: "(?s).*Zulu Zone 4$"
timeout: 15000
- tapOn: "(?s).*Zulu Zone 4$"
- extendedWaitUntil:
visible: "Play"
timeout: 15000
- tapOn:
text: "Play"
waitToSettleTimeoutMs: 1000
- extendedWaitUntil:
visible: "Pause"
timeout: 20000
- back
- extendedWaitUntil:
notVisible: "Pause"
timeout: 10000
- back
- extendedWaitUntil:
visible: "Overview"
timeout: 10000
+11
View File
@@ -0,0 +1,11 @@
appId: com.edde746.plezy
name: Open empty downloads state
tags:
- e2e
- downloads
---
- runFlow: ../subflows/onboard_jellyfin.yaml
- tapOn: "(?s)^Downloads.*"
- extendedWaitUntil:
visible: "No downloads"
timeout: 15000
+62
View File
@@ -0,0 +1,62 @@
appId: com.edde746.plezy
name: Manage profiles and open settings
tags:
- e2e
- profiles
- settings
---
- runFlow: ../subflows/onboard_jellyfin.yaml
- tapOn: "M"
- tapOn:
text: "Profiles"
above:
text: "Settings"
- extendedWaitUntil:
visible: "Switch Profile"
timeout: 10000
- assertVisible: "(?s).*Maestro.*"
- tapOn: "Add Plezy profile"
- extendedWaitUntil:
visible: "New profile"
timeout: 10000
- tapOn: "e.g. Guests, Kids, Family Room"
- inputText: "E2E Guest"
- hideKeyboard
- tapOn: "Continue"
- extendedWaitUntil:
visible: "Add to E2E Guest"
timeout: 10000
- assertVisible: "(?s)^Sign in with Plex.*"
- assertVisible: "(?s)^Connect to Jellyfin.*"
- back
- assertVisible: "(?s).*E2E Guest.*"
- back
- extendedWaitUntil:
visible: "(?s)^Home.*"
timeout: 10000
- waitForAnimationToEnd:
timeout: 5000
- repeat:
times: 2
while:
notVisible: "Settings"
commands:
- tapOn: "M"
- waitForAnimationToEnd:
timeout: 3000
- tapOn:
text: "Settings"
below:
text: "Profiles"
- extendedWaitUntil:
visible: "(?s)^Appearance.*"
timeout: 10000
- assertVisible: "(?s)^Video Playback.*"
- assertVisible: "(?s)^Connections.*"
- tapOn: "(?s)^Appearance.*"
- extendedWaitUntil:
visible: "(?s)^Theme.*"
timeout: 10000
- assertVisible: "(?s).*Library Density.*"
- back
- assertVisible: "(?s)^Appearance.*"
+23
View File
@@ -0,0 +1,23 @@
appId: com.edde746.plezy
name: Logout returns to authentication
tags:
- e2e
- auth
---
- runFlow: ../subflows/onboard_jellyfin.yaml
- tapOn: "M"
- tapOn:
text: "Logout"
below:
text: "Settings"
- extendedWaitUntil:
visible: "Are you sure you want to logout?"
timeout: 10000
- tapOn:
text: "Logout"
below:
text: "Are you sure you want to logout?"
- extendedWaitUntil:
visible: "Sign in with Plex"
timeout: 20000
- assertVisible: "Connect to Jellyfin"
+56
View File
@@ -0,0 +1,56 @@
# syntax=docker/dockerfile:1.7
ARG JELLYFIN_IMAGE=jellyfin/jellyfin:10.11.11@sha256:aefb67e6a7ff1debdd154a78a7bbb780fd0c873d8639210a7f6a2016ad2b35db
FROM ${JELLYFIN_IMAGE} AS seed
USER root
RUN apt-get update \
&& apt-get install --yes --no-install-recommends ca-certificates python3 \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /opt/plezy-demo
COPY scripts/maestro_fixtures.py scripts/maestro_real_jellyfin.py scripts/prepare_maestro_media.py ./
COPY .maestro/jellyfin-demo/seed.sh ./seed.sh
ARG PLEZY_DEMO_MEDIA_BASE_URL=https://demo-files.plezy.app/media-samples/
ARG PLEZY_DEMO_MEDIA_REVISION=2026-07-14
ARG PLEZY_DEMO_MEDIA_DURATION=300
RUN test -n "${PLEZY_DEMO_MEDIA_REVISION}" \
&& python3 maestro_real_jellyfin.py download-codecs \
--base-url "${PLEZY_DEMO_MEDIA_BASE_URL}" \
--output-dir /tmp/plezy-codecs \
&& PATH="/usr/lib/jellyfin-ffmpeg:${PATH}" python3 prepare_maestro_media.py \
/tmp/plezy-codecs /tmp/plezy-codecs-prepared \
--duration "${PLEZY_DEMO_MEDIA_DURATION}" \
--extend av1_opus_ass_srt.mkv \
--extend h264_eac3_multisub.mkv \
--extend hevc10_flac_ass.mkv \
&& python3 maestro_real_jellyfin.py prepare \
--output-dir /media \
--codec-source-dir /tmp/plezy-codecs-prepared \
--include-codecs \
&& rm -rf /tmp/plezy-codecs /tmp/plezy-codecs-prepared __pycache__ \
&& chmod -R a=rX /media
RUN ./seed.sh
FROM ${JELLYFIN_IMAGE}
LABEL org.opencontainers.image.title="Plezy Jellyfin demo server" \
org.opencontainers.image.description="Ready-to-run Jellyfin server with Plezy's deterministic codec demo catalog" \
org.opencontainers.image.source="https://github.com/edde746/plezy"
COPY --from=seed /media /media
COPY --from=seed /opt/plezy-demo/seed-config /opt/plezy-demo/seed-config
COPY .maestro/jellyfin-demo/entrypoint.sh /usr/local/bin/plezy-demo-entrypoint
RUN chmod 0755 /usr/local/bin/plezy-demo-entrypoint \
&& chmod -R a=rX /media /opt/plezy-demo/seed-config
ENV TZ=UTC \
JELLYFIN_PublishedServerUrl=http://localhost:8096
EXPOSE 8096
STOPSIGNAL SIGTERM
ENTRYPOINT ["/usr/local/bin/plezy-demo-entrypoint"]
+17
View File
@@ -0,0 +1,17 @@
#!/bin/sh
set -eu
SEED_CONFIG=/opt/plezy-demo/seed-config
SEED_MARKER=.plezy-demo-seed
if [ ! -f "/config/${SEED_MARKER}" ]; then
existing="$(find /config -mindepth 1 -maxdepth 1 -print -quit)"
if [ -n "${existing}" ]; then
echo "Refusing to overwrite a non-demo Jellyfin configuration in /config." >&2
echo "Start this image with a new or empty /config volume." >&2
exit 1
fi
cp -a "${SEED_CONFIG}/." /config/
fi
exec /jellyfin/jellyfin "$@"
+46
View File
@@ -0,0 +1,46 @@
#!/bin/sh
set -eu
SEED_ROOT=/opt/plezy-demo
SEED_CONFIG="${SEED_ROOT}/seed-config"
SEED_CACHE="${SEED_ROOT}/seed-cache"
JELLYFIN_PID=""
stop_jellyfin() {
if [ -n "${JELLYFIN_PID}" ] && kill -0 "${JELLYFIN_PID}" 2>/dev/null; then
kill -TERM "${JELLYFIN_PID}"
wait "${JELLYFIN_PID}" || true
fi
}
on_exit() {
exit_status=$?
if [ "${exit_status}" -ne 0 ] && [ -f "${SEED_ROOT}/seed-jellyfin.log" ]; then
cat "${SEED_ROOT}/seed-jellyfin.log" >&2
fi
stop_jellyfin
}
trap on_exit EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
mkdir -p "${SEED_CONFIG}/config" "${SEED_CONFIG}/log" "${SEED_CACHE}"
JELLYFIN_DATA_DIR="${SEED_CONFIG}" \
JELLYFIN_CONFIG_DIR="${SEED_CONFIG}/config" \
JELLYFIN_LOG_DIR="${SEED_CONFIG}/log" \
JELLYFIN_CACHE_DIR="${SEED_CACHE}" \
XDG_CACHE_HOME="${SEED_CACHE}" \
JELLYFIN_PublishedServerUrl="http://127.0.0.1:8096" \
/jellyfin/jellyfin >"${SEED_ROOT}/seed-jellyfin.log" 2>&1 &
JELLYFIN_PID=$!
python3 "${SEED_ROOT}/maestro_real_jellyfin.py" bootstrap \
--url http://127.0.0.1:8096 \
--timeout 180 \
--include-codecs
stop_jellyfin
JELLYFIN_PID=""
rm -rf "${SEED_CONFIG}/log" "${SEED_CACHE}" "${SEED_ROOT}/seed-jellyfin.log"
printf '%s\n' 'Plezy Jellyfin demo seed v1' >"${SEED_CONFIG}/.plezy-demo-seed"
trap - EXIT INT TERM
+12
View File
@@ -0,0 +1,12 @@
flows:
- "*.yaml"
testOutputDir: "build/maestro-media"
executionOrder:
continueOnFailure: false
flowsOrder:
- Codec sample - UHD Dolby Vision TrueHD and PGS
- Codec sample - Web Dolby Vision EAC3 Atmos and SRT
- Codec sample - AV1 Opus ASS and SRT
- Codec sample - H264 High10 DTS-HD and ASS
- Codec sample - H264 EAC3 multilingual SRT
- Codec sample - HEVC10 FLAC and ASS
+26
View File
@@ -0,0 +1,26 @@
appId: com.edde746.plezy
name: Codec sample - UHD Dolby Vision TrueHD and PGS
tags:
- e2e
- media
- dolby-vision
---
- runFlow:
file: ../subflows/open_codec_sample.yaml
env:
SAMPLE_TITLE: "Codec DV UHD TrueHD PGS"
SAMPLE_OVERVIEW: "Dolby Vision profile 8 with an HDR fallback, TrueHD Atmos, AC-3, and PGS subtitles."
- runFlow:
file: ../subflows/switch_codec_tracks.yaml
env:
AUDIO_TRACK: "(?is)^English.*(?:AC3|TrueHD|Surround|5\\.1|7\\.1).*"
SUBTITLE_TRACK: "(?is)^Spanish.*PGS.*"
- repeat:
times: 2
while:
notVisible: "Overview"
commands:
- back
- extendedWaitUntil:
visible: "Overview"
timeout: 10000
+26
View File
@@ -0,0 +1,26 @@
appId: com.edde746.plezy
name: Codec sample - Web Dolby Vision EAC3 Atmos and SRT
tags:
- e2e
- media
- dolby-vision
---
- runFlow:
file: ../subflows/open_codec_sample.yaml
env:
SAMPLE_TITLE: "Codec DV Web EAC3 SRT"
SAMPLE_OVERVIEW: "Dolby Vision profile 8 with an HDR fallback, E-AC-3 Atmos, and multilingual SRT subtitles."
- runFlow:
file: ../subflows/switch_codec_tracks.yaml
env:
AUDIO_TRACK: "(?is)^German.*(?:E-AC3|Dolby Digital Plus|Surround|5\\.1).*"
SUBTITLE_TRACK: "(?is)^German.*(?:SRT|APPLICATION/X-SUBRIP).*"
- repeat:
times: 2
while:
notVisible: "Overview"
commands:
- back
- extendedWaitUntil:
visible: "Overview"
timeout: 10000
+26
View File
@@ -0,0 +1,26 @@
appId: com.edde746.plezy
name: Codec sample - AV1 Opus ASS and SRT
tags:
- e2e
- media
- av1
---
- runFlow:
file: ../subflows/open_codec_sample.yaml
env:
SAMPLE_TITLE: "Codec AV1 Opus ASS"
SAMPLE_OVERVIEW: "AV1 video with multilingual Opus audio, styled ASS subtitles, SRT subtitles, and embedded fonts."
- runFlow:
file: ../subflows/switch_codec_tracks.yaml
env:
AUDIO_TRACK: "(?is)^English.*(?:Opus|Stereo).*"
SUBTITLE_TRACK: "(?is)^English.*(?:ASS|TEXT/X-SSA).*"
- repeat:
times: 2
while:
notVisible: "Overview"
commands:
- back
- extendedWaitUntil:
visible: "Overview"
timeout: 10000
+26
View File
@@ -0,0 +1,26 @@
appId: com.edde746.plezy
name: Codec sample - H264 High10 DTS-HD and ASS
tags:
- e2e
- media
- h264-high10
---
- runFlow:
file: ../subflows/open_codec_sample.yaml
env:
SAMPLE_TITLE: "Codec H264 High10 DTS-HD ASS"
SAMPLE_OVERVIEW: "H.264 High 10 video with dual DTS-HD MA audio, styled ASS subtitles, and embedded fonts."
- runFlow:
file: ../subflows/switch_codec_tracks.yaml
env:
AUDIO_TRACK: "(?is)^Japanese.*(?:DTS-HD MA|DTS|Surround|5\\.1).*"
SUBTITLE_TRACK: "(?is)^English.*(?:ASS|TEXT/X-SSA).*"
- repeat:
times: 2
while:
notVisible: "Overview"
commands:
- back
- extendedWaitUntil:
visible: "Overview"
timeout: 10000
+27
View File
@@ -0,0 +1,27 @@
appId: com.edde746.plezy
name: Codec sample - H264 EAC3 multilingual SRT
tags:
- e2e
- media
- subtitles
---
- runFlow:
file: ../subflows/open_codec_sample.yaml
env:
SAMPLE_TITLE: "Codec H264 EAC3 Multisub"
SAMPLE_OVERVIEW: "H.264 video with three E-AC-3 audio tracks and a broad multilingual SRT subtitle set."
- runFlow:
file: ../subflows/switch_codec_tracks_deep.yaml
env:
AUDIO_TRACK: "(?is)^English.*(?:Dolby Digital Plus|E-AC3|Surround|5\\.1).*"
SUBTITLE_TRACK: "(?is)^English.*APPLICATION/X-SUBRIP.*"
SHEET_MARKER: "(?is)^Japanese.*(?:Dolby Digital Plus|E-AC3|Surround|5\\.1).*"
- repeat:
times: 2
while:
notVisible: "Overview"
commands:
- back
- extendedWaitUntil:
visible: "Overview"
timeout: 10000
+26
View File
@@ -0,0 +1,26 @@
appId: com.edde746.plezy
name: Codec sample - HEVC10 FLAC and ASS
tags:
- e2e
- media
- hevc
---
- runFlow:
file: ../subflows/open_codec_sample.yaml
env:
SAMPLE_TITLE: "Codec HEVC10 FLAC ASS"
SAMPLE_OVERVIEW: "HEVC Main 10 video with dual FLAC 5.1 audio, styled ASS subtitles, and embedded fonts."
- runFlow:
file: ../subflows/switch_codec_tracks.yaml
env:
AUDIO_TRACK: "(?is)^Japanese.*(?:FLAC|Surround|5\\.1).*"
SUBTITLE_TRACK: "(?is)^English.*(?:ASS|TEXT/X-SSA).*"
- repeat:
times: 2
while:
notVisible: "Overview"
commands:
- back
- extendedWaitUntil:
visible: "Overview"
timeout: 10000
+38
View File
@@ -0,0 +1,38 @@
appId: com.edde746.plezy
name: Real Jellyfin imports and opens codec media
tags:
- e2e
- real-jellyfin
- media
---
- runFlow: ../subflows/onboard_jellyfin.yaml
- tapOn: "(?s)^Search.*"
- extendedWaitUntil:
visible: "Search movies, shows, music..."
timeout: 10000
- tapOn: "Search movies, shows, music..."
- inputText: "Codec DV UHD"
- hideKeyboard
- extendedWaitUntil:
visible: "(?s).*Codec DV UHD TrueHD PGS$"
timeout: 15000
- tapOn: "(?s).*Codec DV UHD TrueHD PGS$"
- extendedWaitUntil:
visible: "Overview"
timeout: 15000
- assertVisible: "Dolby Vision profile 8 with an HDR fallback, TrueHD Atmos, AC-3, and PGS subtitles."
- tapOn:
text: "Play"
waitToSettleTimeoutMs: 1000
- extendedWaitUntil:
notVisible: "Overview"
timeout: 15000
- back
- runFlow:
when:
notVisible: "Overview"
commands:
- back
- extendedWaitUntil:
visible: "Overview"
timeout: 10000
+54
View File
@@ -0,0 +1,54 @@
appId: com.edde746.plezy
name: Jellyfin music browsing survives grouping reloads
tags:
- e2e
- real-jellyfin
- music
- regression
---
- runFlow: ../subflows/onboard_jellyfin.yaml
- assertVisible: "(?s)^Latest Albums in Maestro Music.*"
- assertVisible: "(?s)^Regression Album.*"
- tapOn: "(?s)^Libraries.*"
- extendedWaitUntil:
visible: "Maestro Movies"
timeout: 15000
- tapOn: "Maestro Movies"
- extendedWaitUntil:
visible: "Maestro Music"
timeout: 10000
- tapOn: "Maestro Music"
- extendedWaitUntil:
visible: "(?s)^Regression Album.*"
timeout: 15000
- assertVisible: "(?s)^Latest Albums in Maestro Music.*"
- tapOn: "Browse"
- runFlow:
when:
visible: "Retry"
commands:
- tapOn: "Retry"
- extendedWaitUntil:
visible: "Maestro Artist"
timeout: 15000
- assertNotVisible: "(?i).*connection timeout.*"
- tapOn: "Library options"
- tapOn: "(?s)^Grouping.*Artists$"
- tapOn: "Albums"
- extendedWaitUntil:
visible: "(?s)^Regression Album.*"
timeout: 15000
- tapOn: "Library options"
- tapOn: "(?s)^Grouping.*Albums$"
- tapOn: "Tracks"
- extendedWaitUntil:
visible: "(?s)^Resilient Track.*"
timeout: 15000
- tapOn: "Library options"
- tapOn: "(?s)^Grouping.*Tracks$"
- tapOn: "Folders"
- extendedWaitUntil:
visible: "Maestro Artist"
timeout: 15000
- assertNotVisible: "(?i).*connection timeout.*"
@@ -0,0 +1,66 @@
appId: com.edde746.plezy
name: Profile switching isolates Jellyfin content and libraries
tags:
- e2e
- regression
- profiles
---
- runFlow: ../subflows/onboard_jellyfin.yaml
- assertVisible: "(?s).*Zulu Zone 4.*"
- tapOn: "(?s)^Libraries.*"
- extendedWaitUntil:
visible: "Maestro Movies"
timeout: 15000
- assertNotVisible: "Guest Movies"
- tapOn: "(?s)^Home.*"
- runFlow: ../subflows/create_guest_jellyfin_profile.yaml
- tapOn: "(?s)^E\nE2E Guest\n.*"
- extendedWaitUntil:
visible: "(?s).*Guest Galaxy$"
timeout: 30000
- assertNotVisible: "(?s).*Zulu Zone 4.*"
- tapOn: "(?s)^Libraries.*"
- extendedWaitUntil:
visible: "Guest Movies"
timeout: 15000
- assertNotVisible: "Maestro Movies"
- tapOn: "(?s)^Home.*"
- extendedWaitUntil:
visible: "(?s).*Guest Galaxy$"
timeout: 15000
- tapOn: "E"
- tapOn:
text: "Profiles"
above:
text: "Settings"
- extendedWaitUntil:
visible: "Switch Profile"
timeout: 10000
- tapOn: "(?s)^M\nMaestro\n.*"
- extendedWaitUntil:
visible: "(?s).*Zulu Zone 4.*"
timeout: 30000
- assertNotVisible: "(?s).*Guest Galaxy$"
- tapOn: "(?s)^Libraries.*"
- extendedWaitUntil:
visible: "Maestro Movies"
timeout: 15000
- assertNotVisible: "Guest Movies"
- tapOn: "(?s)^Home.*"
- extendedWaitUntil:
visible: "(?s).*Zulu Zone 4.*"
timeout: 15000
- tapOn: "M"
- tapOn:
text: "Profiles"
above:
text: "Settings"
- extendedWaitUntil:
visible: "Switch Profile"
timeout: 10000
- tapOn: "(?s)^E\nE2E Guest\n.*"
- extendedWaitUntil:
visible: "(?s).*Guest Galaxy$"
timeout: 30000
- assertNotVisible: "(?s).*Zulu Zone 4.*"
@@ -0,0 +1,48 @@
appId: com.edde746.plezy
name: Removing a Jellyfin profile connection leaves no orphaned session
tags:
- e2e
- regression
- profiles
- teardown
---
- runFlow: ../subflows/onboard_jellyfin.yaml
- runFlow: ../subflows/create_guest_jellyfin_profile.yaml
- tapOn:
text: "Manage"
index: 1
- tapOn: "Manage"
- extendedWaitUntil:
visible: "Profile name"
timeout: 10000
- assertVisible: "(?s)^E2E Guest.*"
- assertVisible: "(?s)^Maestro Jellyfin.*Default.*Manage$"
- tapOn: "Manage"
- extendedWaitUntil:
visible: "Remove"
timeout: 10000
- tapOn: "Remove"
- extendedWaitUntil:
visible: "^Remove connection\\?$"
timeout: 10000
- assertVisible: "(?s).*E2E Guest's access to Maestro Jellyfin.*"
- tapOn: "Remove"
- extendedWaitUntil:
notVisible: "(?s)^Maestro Jellyfin.*Default.*Manage$"
timeout: 15000
- assertVisible: "Delete profile"
- tapOn: "Delete profile"
- extendedWaitUntil:
visible: "^Delete profile\\?$"
timeout: 10000
- tapOn: "^Delete$"
- extendedWaitUntil:
visible: "Switch Profile"
timeout: 30000
- assertNotVisible: "(?s).*E2E Guest.*"
- assertVisible: "(?s)^M\nMaestro\nActive.*"
- back
- extendedWaitUntil:
visible: "(?s).*Zulu Zone 4.*"
timeout: 30000
@@ -0,0 +1,68 @@
appId: com.edde746.plezy
name: TV alphabet rail retains focus until returning to the media grid
tags:
- e2e
- regression
- tv
- focus
---
- runFlow: ../subflows/onboard_jellyfin_tv.yaml
- pressKey: "Remote Dpad Left"
- pressKey: "Remote Dpad Down"
- pressKey: "Remote Dpad Down"
- pressKey: "Remote Dpad Center"
- extendedWaitUntil:
visible: "Recommended"
timeout: 15000
- pressKey: "Remote Dpad Right"
- pressKey: "Remote Dpad Up"
- pressKey: "Remote Dpad Right"
- pressKey: "Remote Dpad Center"
- pressKey: "Remote Dpad Up"
- pressKey: "Remote Dpad Right"
- pressKey: "Remote Dpad Right"
- pressKey: "Remote Dpad Center"
- extendedWaitUntil:
visible: "Title"
timeout: 10000
- pressKey: "Remote Dpad Center"
- pressKey: "Remote Dpad Left"
- extendedWaitUntil:
notVisible: "Sort by"
timeout: 10000
- pressKey: "Remote Dpad Down"
- extendedWaitUntil:
visible: "(?s).*Alpha Archive.*"
timeout: 15000
- repeat:
times: 8
commands:
- pressKey: "Remote Dpad Right"
- repeat:
times: 13
commands:
- pressKey: "Remote Dpad Down"
- extendedWaitUntil:
visible: "(?s).*Mike Matrix.*"
timeout: 15000
- assertNotVisible: "(?s).*Alpha Archive.*"
- repeat:
times: 13
commands:
- pressKey: "Remote Dpad Down"
- extendedWaitUntil:
visible: "(?s).*Zulu Zone.*"
timeout: 15000
- assertNotVisible: "(?s).*Mike Matrix.*"
- pressKey: "Remote Dpad Left"
- pressKey: "Remote Dpad Center"
- extendedWaitUntil:
visible: "Play"
timeout: 15000
- assertVisible: "(?s).*Zulu Zone.*"
- pressKey: "back"
- extendedWaitUntil:
visible: "Browse"
timeout: 15000
- assertVisible: "(?s).*Zulu Zone.*"
@@ -0,0 +1,39 @@
appId: com.edde746.plezy
name: TV hardware media and back keys follow player chrome state
tags:
- e2e
- regression
- tv
- playback
---
- runFlow: ../subflows/onboard_jellyfin_tv.yaml
- pressKey: "Remote Dpad Center"
- extendedWaitUntil:
visible: "Play"
timeout: 15000
- pressKey: "Remote Dpad Center"
- extendedWaitUntil:
visible: "Pause"
timeout: 30000
- extendedWaitUntil:
notVisible: "Pause"
timeout: 15000
- pressKey: "Remote Media Play Pause"
- extendedWaitUntil:
visible: "Play"
timeout: 10000
- pressKey: "Remote Media Play Pause"
- extendedWaitUntil:
visible: "Pause"
timeout: 10000
- pressKey: "back"
- extendedWaitUntil:
notVisible: "Pause"
timeout: 10000
- assertNotVisible: "Overview"
- pressKey: "back"
- extendedWaitUntil:
visible: "(?s)^(Play|Resume).*$"
timeout: 15000
- assertVisible: "(?s).*Zulu Zone 4.*"
@@ -0,0 +1,43 @@
appId: com.edde746.plezy
name: TV Back dismisses Next Episode without leaving playback
tags:
- e2e
- regression
- tv
- playback
---
- runFlow: ../subflows/onboard_jellyfin_tv.yaml
- tapOn:
point: "6%,22%"
- tapOn: "Search"
- extendedWaitUntil:
visible: "Search movies, shows, music..."
timeout: 10000
- tapOn: "Search movies, shows, music..."
- inputText: "Maestro Show"
- tapOn:
point: "87%,90%"
- extendedWaitUntil:
visible: "(?s).*Maestro Show$"
timeout: 15000
- tapOn:
point: "50%,24%"
- waitForAnimationToEnd:
timeout: 5000
- tapOn:
point: "15%,76%"
- extendedWaitUntil:
visible: "Pause"
timeout: 30000
- pressKey: "Remote Media Fast Forward"
- pressKey: "Remote Media Fast Forward"
- extendedWaitUntil:
visible: "Next Episode"
timeout: 20000
- pressKey: "back"
- assertNotVisible: "Next Episode"
- assertNotVisible: "Overview"
- pressKey: "Remote Dpad Up"
- extendedWaitUntil:
visible: "(?s).*Maestro Episode 1.*"
timeout: 10000
@@ -0,0 +1,32 @@
appId: com.edde746.plezy
name: Playback recovers after a transient stream failure
tags:
- e2e
- regression
- playback
- recovery
---
- runFlow: ../subflows/onboard_jellyfin.yaml
- tapOn: "(?s)^Libraries.*"
- extendedWaitUntil:
visible: "(?s).*Zulu Zone 4$"
timeout: 15000
- tapOn: "(?s).*Zulu Zone 4$"
- extendedWaitUntil:
visible: "Play"
timeout: 15000
- tapOn:
text: "Play"
waitToSettleTimeoutMs: 1000
- extendedWaitUntil:
visible: "Pause"
timeout: 45000
- assertNotVisible: "Overview"
- back
- extendedWaitUntil:
notVisible: "Pause"
timeout: 10000
- back
- extendedWaitUntil:
visible: "Overview"
timeout: 15000
@@ -0,0 +1,43 @@
appId: com.edde746.plezy
---
- tapOn: "M"
- tapOn:
text: "Profiles"
above:
text: "Settings"
- extendedWaitUntil:
visible: "Switch Profile"
timeout: 10000
- tapOn: "Add Plezy profile"
- extendedWaitUntil:
visible: "New profile"
timeout: 10000
- tapOn: "e.g. Guests, Kids, Family Room"
- inputText: "E2E Guest"
- hideKeyboard
- tapOn: "Continue"
- extendedWaitUntil:
visible: "Add to E2E Guest"
timeout: 10000
- tapOn: "(?s)^Connect to Jellyfin.*"
- extendedWaitUntil:
visible: "Add Jellyfin server"
timeout: 10000
- tapOn: "(?s)Server URLs.*"
- inputText: ${JELLYFIN_URL}
- hideKeyboard
- tapOn: "Find server"
- extendedWaitUntil:
visible: "Maestro Jellyfin"
timeout: 15000
- tapOn: "Username"
- inputText: "guest"
- tapOn: "Password"
- inputText: "guest"
- hideKeyboard
- tapOn: "Sign in"
- extendedWaitUntil:
visible: "Switch Profile"
timeout: 30000
- assertVisible: "(?s)^M\nMaestro\n.*"
- assertVisible: "(?s)^E\nE2E Guest\n.*"
+38
View File
@@ -0,0 +1,38 @@
appId: com.edde746.plezy
---
- retry:
maxRetries: 1
commands:
- launchApp:
clearState: true
permissions:
all: allow
- extendedWaitUntil:
visible: "(?s)^(?:Connect to Jellyfin|Wait).*"
timeout: 30000
- tapOn:
text: "Wait"
optional: true
- extendedWaitUntil:
visible: "Connect to Jellyfin"
timeout: 30000
- tapOn: "Connect to Jellyfin"
- extendedWaitUntil:
visible: "Add Jellyfin server"
timeout: 10000
- tapOn: "(?s)Server URLs.*"
- inputText: ${JELLYFIN_URL}
- hideKeyboard
- tapOn: "Find server"
- extendedWaitUntil:
visible: "Maestro Jellyfin"
timeout: 15000
- tapOn: "Username"
- inputText: "maestro"
- tapOn: "Password"
- inputText: "maestro"
- hideKeyboard
- tapOn: "Sign in"
- extendedWaitUntil:
visible: "Discover"
timeout: 30000
@@ -0,0 +1,54 @@
appId: com.edde746.plezy
---
- retry:
maxRetries: 1
commands:
- launchApp:
appId: com.edde746.plezy
clearState: true
permissions:
all: allow
- extendedWaitUntil:
visible: "(?s)^(?:Connect to Jellyfin|Wait).*"
timeout: 30000
- tapOn:
text: "Wait"
optional: true
- extendedWaitUntil:
visible: "Connect to Jellyfin"
timeout: 30000
- tapOn: "Connect to Jellyfin"
- extendedWaitUntil:
visible: "Add Jellyfin server"
timeout: 10000
- tapOn: "(?s)Server URLs.*"
- inputText: ${JELLYFIN_URL}
- tapOn: "Find server"
- extendedWaitUntil:
visible: "Username"
timeout: 15000
- tapOn: "Username"
- inputText: "maestro"
- tapOn: "Password"
- inputText: "maestro"
- tapOn: "Sign in"
- extendedWaitUntil:
visible: "Discover"
timeout: 30000
- tapOn: "M"
- tapOn:
text: "Settings"
below:
text: "Profiles"
- extendedWaitUntil:
visible: "(?s)^Appearance.*"
timeout: 10000
- tapOn: "(?s)^Appearance.*"
- swipe:
start: 50%, 85%
end: 50%, 25%
duration: 500
- tapOn: "(?s)^Force TV mode.*"
- extendedWaitUntil:
visible: "(?s).*Zulu Zone 4.*"
timeout: 30000
+26
View File
@@ -0,0 +1,26 @@
appId: com.edde746.plezy
---
- runFlow: onboard_jellyfin.yaml
- tapOn: "(?s)^Search.*"
- extendedWaitUntil:
visible: "Search movies, shows, music..."
timeout: 10000
- tapOn: "Search movies, shows, music..."
- inputText: "${SAMPLE_TITLE}"
- hideKeyboard
- extendedWaitUntil:
visible: "(?s).*${SAMPLE_TITLE}$"
timeout: 15000
- tapOn:
point: "50%,24%"
- extendedWaitUntil:
visible: "Overview"
timeout: 15000
- assertVisible: "${SAMPLE_OVERVIEW}"
- tapOn:
text: "Play"
waitToSettleTimeoutMs: 1000
- extendedWaitUntil:
notVisible: "Overview"
timeout: 15000
- pressKey: "Remote Media Play Pause"
@@ -0,0 +1,21 @@
appId: com.edde746.plezy
---
- runFlow:
when:
notVisible: "${SHEET_MARKER}"
commands:
- repeat:
times: 8
while:
notVisible: "${SHEET_MARKER}"
commands:
- tapOn:
point: "50%,50%"
- runFlow:
when:
visible: "Pause"
commands:
- pressKey: "Remote Media Play Pause"
- tapOn:
point: "75%,11%"
- assertVisible: "${SHEET_MARKER}"
@@ -0,0 +1,27 @@
appId: com.edde746.plezy
---
- runFlow:
file: show_codec_track_sheet.yaml
env:
SHEET_MARKER: "${AUDIO_TRACK}"
- assertVisible: "${AUDIO_TRACK}"
- tapOn:
point: "30%,70%"
- runFlow:
file: show_codec_track_sheet.yaml
env:
SHEET_MARKER: "${AUDIO_TRACK}"
- assertVisible: "${SUBTITLE_TRACK}"
- tapOn:
point: "70%,66%"
- runFlow:
file: show_codec_track_sheet.yaml
env:
SHEET_MARKER: "${AUDIO_TRACK}"
- assertVisible:
text: "${AUDIO_TRACK}"
selected: true
- assertVisible:
text: "${SUBTITLE_TRACK}"
selected: true
- back
@@ -0,0 +1,40 @@
appId: com.edde746.plezy
---
- runFlow:
file: show_codec_track_sheet.yaml
env:
SHEET_MARKER: "${SHEET_MARKER}"
- assertVisible: "${AUDIO_TRACK}"
- tapOn:
point: "30%,84%"
- runFlow:
file: show_codec_track_sheet.yaml
env:
SHEET_MARKER: "${AUDIO_TRACK}"
- repeat:
times: 12
while:
notVisible: "${SUBTITLE_TRACK}"
commands:
- swipe:
start: 70%, 82%
end: 70%, 68%
duration: 300
- assertVisible: "${SUBTITLE_TRACK}"
- swipe:
start: 70%, 78%
end: 70%, 68%
duration: 300
- tapOn:
point: "70%,86%"
- runFlow:
file: show_codec_track_sheet.yaml
env:
SHEET_MARKER: "${AUDIO_TRACK}"
- assertVisible:
text: "${AUDIO_TRACK}"
selected: true
- assertVisible:
text: "${SUBTITLE_TRACK}"
selected: true
- back