Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 39 additions & 9 deletions .github/workflows/NativePipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,35 @@ jobs:
- name: "Overlay built widget mpks"
if: ${{ github.event.inputs.workspace != 'js-actions' }}
shell: bash
# Located by `find` rather than a fixed-depth glob: upload-artifact strips the least-common
# ancestor of the paths it is given, so the depth here follows whatever else is in the
# artifact. Adding resources-manifest.txt at the repo root moved that ancestor from
# packages/ to the root, every path gained a packages/ prefix, and the old
# 'resources/pluggableWidgets/**' glob silently stopped matching — so no built mpk was
# installed and the e2e suite tested the baseline project's widgets instead.
#
# And it is fatal rather than silent: a widget that was built but not installed makes the
# e2e run test something other than the commit under test, which is worse than not running.
run: |
if compgen -G 'resources/pluggableWidgets/**/dist/*/*.mpk' > /dev/null; then
for oldPath in resources/pluggableWidgets/**/dist/*/*.mpk; do
newPath="Native-Mobile-Resources-main/widgets/$(basename "$oldPath")"
mv -f "$oldPath" "$newPath"
done
found=0
while IFS= read -r oldPath; do
[ -n "$oldPath" ] || continue
found=$((found + 1))
echo "installing $(basename "$oldPath")"
mv -f "$oldPath" "Native-Mobile-Resources-main/widgets/$(basename "$oldPath")"
done < <(find resources -type f -path '*/dist/*/*.mpk')

# The scope this job was given, read from the manifest rather than needs.scope: `project`
# does not depend on `scope`, so its outputs are not visible here. Compared as a string
# rather than parsed as JSON: the manifest line is written by echoing an interpolated
# expression, and the shell strips the inner quotes on the way in, so it reads
# [a, b] rather than ["a","b"].
built=$(sed -n 's/^built widgets: //p' resources/resources-manifest.txt)
echo "mpks installed: ${found}; widgets in scope: ${built:-unknown}"
if [ "$found" -eq 0 ] && [ -n "$built" ] && [ "$built" != "[]" ]; then
echo "::error::Widgets ${built} were built but no .mpk was found under resources/ — the test project would run stale widgets."
find resources -type f | head -50
exit 1
fi
- name: "Register widgets in the test project"
# Run unconditionally: update-widgets must sync the project's widget definitions with the
Expand All @@ -364,17 +387,24 @@ jobs:
# then skip it and leave stale Atlas widget defs for the portable-app build.
shell: bash
run: mx update-widgets --loose-version-check Native-Mobile-Resources-main/NativeComponentsTestProject.mpr
# Same layout-independence as the mpk overlay above: locate the dist dir rather than assume
# its depth in the artifact. Each guard also checks its OWN source dir — nanoflow-actions
# previously tested mobile-resources-native, so it moved either both or neither.
- name: "Move mobile-resources"
shell: bash
run: |
if compgen -G 'resources/jsActions/mobile-resources-native/*' > /dev/null; then
mv -f resources/jsActions/mobile-resources-native/* Native-Mobile-Resources-main/javascriptsource/nativemobileresources/actions/
src=$(find resources -type d -path '*/mobile-resources-native/dist' | head -1)
if [ -n "$src" ]; then
echo "installing mobile-resources from $src"
mv -f "$src"/* Native-Mobile-Resources-main/javascriptsource/nativemobileresources/actions/
fi
- name: "Move nanoflow-actions"
shell: bash
run: |
if compgen -G 'resources/jsActions/mobile-resources-native/*' > /dev/null; then
mv -f resources/jsActions/nanoflow-actions-native/* Native-Mobile-Resources-main/javascriptsource/nanoflowcommons/actions/
src=$(find resources -type d -path '*/nanoflow-actions-native/dist' | head -1)
if [ -n "$src" ]; then
echo "installing nanoflow-actions from $src"
mv -f "$src"/* Native-Mobile-Resources-main/javascriptsource/nanoflowcommons/actions/
fi
- name: "Build portable app package (self-contained runtime)"
# Run this BEFORE the native-packager deploy: portable-app-package re-prepares and
Expand Down
11 changes: 9 additions & 2 deletions maestro/helpers/helpers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,12 @@ run_maestro() {
return "$status"
}

# Move a fault's evidence aside BEFORE the retry, which reuses both paths.
# Move an attempt's evidence aside BEFORE the retry, which reuses both paths and would otherwise
# delete it: start_recording rm -f's the same REC_FILE and run_maestro rm -rf's the same
# DEBUG_RUN_DIR, so a flake that passes on retry left no video and no hierarchy to diagnose from.
preserve_fault_artifacts() {
local video="${1:-}"
local suffix="driver-fault"
local suffix="${2:-driver-fault}"
if [ -n "$video" ] && [ -f "$video" ]; then
mv -f "$video" "${video%.mp4}-${suffix}.mp4" 2>/dev/null || true
fi
Expand Down Expand Up @@ -318,7 +320,12 @@ run_tests() {
fi
else
echo "❌ Test failed: $yaml_test_file"
# Capture the path before stop_recording clears REC_FILE.
local failed_video="$REC_FILE"
stop_recording keep
# The retry reuses both paths, so a flake that passes on retry would erase the only
# evidence of the failure. Keep this attempt's video and hierarchy under -attempt1.
preserve_fault_artifacts "$failed_video" "attempt1"
failed_tests+=("$yaml_test_file")
fi
completed_tests=$((completed_tests + 1))
Expand Down
4 changes: 4 additions & 0 deletions packages/pluggableWidgets/intro-screen-native/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Fixed

- We fixed an issue where the IntroScreen did not show the slide set by the active slide attribute, and where swiping between slides did not work reliably on slower Android devices.

## [4.4.1] - 2026-6-10

### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,33 @@ appId: "${APP_ID}"
timeout: 5000
- assertVisible:
text: "Changes: 0"
# Coordinates match Gallery_native_horizontal.yaml, which swipes a horizontal list reliably, and
# keep the two directions symmetric — which `direction:` alone also does, but not visibly.
#
# The wait is the part that matters. A slide change writes the active slide attribute and waits for
# the runtime to hand the value back, so the JS thread is still busy for a moment after the
# assertions above pass. Swiping into that window loses the opening touch-move events, so the list
# lags the finger and can be short of the halfway point when the touch lifts — it then snaps back,
# with every counter correctly still on the old slide.
#
# Duration is deliberately left at the default: a paging list commits on position OR lift-off
# velocity, so a slower drag is worse, not better — same distance travelled, less velocity to carry
# it over, and on a slow device the position term is the part already degraded.
- waitForAnimationToEnd:
timeout: 2000
- swipe:
direction: LEFT
start: 90%, 10%
end: 15%, 10%
- extendedWaitUntil:
visible: "Active slide: 3"
timeout: 5000
- assertVisible:
text: "Changes: 1"
- waitForAnimationToEnd:
timeout: 2000
- swipe:
direction: RIGHT
start: 15%, 10%
end: 90%, 10%
- extendedWaitUntil:
visible: "Active slide: 2"
timeout: 5000
Expand Down Expand Up @@ -53,6 +71,11 @@ appId: "${APP_ID}"
timeout: 5000
- tapOn:
text: "NEXT"
# NEXT is what turns into FINISH on the last slide, so tapping straight through races the
# re-render: wait for the slide the button belongs to before reaching for it.
- extendedWaitUntil:
visible: "Active slide: 3"
timeout: 5000
- tapOn:
text: "FINISH"
- extendedWaitUntil:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "intro-screen-native",
"widgetName": "IntroScreen",
"version": "4.4.1",
"version": "4.4.2",
"license": "Apache-2.0",
"repository": {
"type": "git",
Expand Down
Loading
Loading