Skip to content

[MOO-1927] Add js actions test #279

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jul 4, 2025
Merged
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
5 changes: 4 additions & 1 deletion .github/scripts/determine-widget-scope.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,13 @@ if [ "$event_name" == "pull_request" ]; then
echo "widgets=${all_widgets}" >> $GITHUB_OUTPUT
fi
else
if [ -n "$input_workspace" ] && [ "$input_workspace" != "*-native" ]; then
if [ -n "$input_workspace" ] && [ "$input_workspace" != "*-native" ] && [ "$input_workspace" != "js-actions" ]; then
selected_workspaces=$(echo "$input_workspace" | sed 's/,/ /g')
echo "scope=--all --include '${selected_workspaces}'" >> $GITHUB_OUTPUT
echo "widgets=[\"$input_workspace\"]" >> $GITHUB_OUTPUT
elif [ "$input_workspace" == "js-actions" ]; then
echo "scope=--all --include 'mobile-resources-native nanoflow-actions-native'" >> $GITHUB_OUTPUT
echo "widgets=[\"mobile-resources-native\",\"nanoflow-actions-native\"]" >> $GITHUB_OUTPUT
else
echo "scope=--all --include '*-native'" >> $GITHUB_OUTPUT
echo "widgets=${all_widgets}" >> $GITHUB_OUTPUT
Expand Down
232 changes: 216 additions & 16 deletions .github/workflows/NativePipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ on:
type: choice
options:
- "*-native"
- js-actions
- accordion-native
- activity-indicator-native
- animation-native
Expand Down Expand Up @@ -83,7 +84,7 @@ jobs:
- name: "Debug Scope Output"
run: |
echo "Scope is: ${{ steps.scope.outputs.scope }}"
echo "Widgets are: ${{ steps.scope.outputs.widgets }}"
echo "Widgets or js actions are: ${{ steps.scope.outputs.widgets }}"
mendix-version:
runs-on: ubuntu-22.04
outputs:
Expand Down Expand Up @@ -196,14 +197,35 @@ jobs:
run: yarn install --immutable
- name: "Force rebuild resources"
run: |
yarn workspaces foreach ${{ needs.scope.outputs.scope }} run build # Ensure all resources are rebuilt
# Build JS actions if needed
if [ "${{ github.event.inputs.workspace }}" = "js-actions" ] || \
[ "${{ github.event.inputs.workspace }}" = "*-native" ] || \
[ "${{ github.event_name }}" = "schedule" ]; then
yarn workspace mobile-resources-native run build
yarn workspace nanoflow-actions-native run build
fi

# Build widgets if needed (any specific widget, *-native, or nightly)
if [ "${{ github.event.inputs.workspace }}" != "js-actions" ] || \
[ "${{ github.event.inputs.workspace }}" = "*-native" ] || \
[ "${{ github.event_name }}" = "schedule" ]; then
widgets=$(echo '${{ needs.scope.outputs.widgets }}' | jq -r '.[]')
for w in $widgets; do
yarn workspace $w run build
done
fi
- name: "Unit test"
run: yarn workspaces foreach ${{ needs.scope.outputs.scope }} run test
- name: "Run build for development"
run: yarn workspaces foreach ${{ needs.scope.outputs.scope }} run build
env:
NODE_OPTIONS: --max_old_space_size=6144
- name: "Upload resources artifact"
- name: "Upload JS actions resources artifact"
if: ${{ github.event.inputs.workspace == 'js-actions' }}
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 #v4
with:
name: resources
path: |
packages/jsActions/mobile-resources-native/dist/**/*
packages/jsActions/nanoflow-actions-native/dist/**/*
- name: "Upload widget and JS actions resources artifact"
if: ${{ github.event.inputs.workspace != 'js-actions' }}
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 #v4
with:
name: resources
Expand Down Expand Up @@ -238,6 +260,7 @@ jobs:
- name: "List resources"
run: ls -R resources
- name: "Move widgets"
if: ${{ github.event.inputs.workspace != 'js-actions' }}
shell: bash
run: |
if compgen -G 'resources/pluggableWidgets/**/dist/*/*.mpk' > /dev/null; then
Expand Down Expand Up @@ -436,8 +459,9 @@ jobs:
name: ios-app
path: native-template/ios/build/Build/Products/**/*.app

android-tests:
android-widget-tests:
needs: [scope, mendix-version, project, android-app]
if: ${{ github.event.inputs.workspace != 'js-actions' || github.event_name == 'schedule' }}
runs-on: ubuntu-22.04
timeout-minutes: 60
strategy:
Expand Down Expand Up @@ -518,7 +542,7 @@ jobs:
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: "Run the android tests"
- name: "Run android tests"
uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # v2.0.0
with:
api-level: 30
Expand All @@ -529,9 +553,9 @@ jobs:
disable-animations: true
script: |
chmod +x maestro/helpers/prepare_android.sh
chmod +x maestro/run_maestro_tests.sh
chmod +x maestro/run_maestro_widget_tests.sh
bash maestro/helpers/prepare_android.sh
bash maestro/run_maestro_tests.sh android "${{ matrix.widget }}"
bash maestro/run_maestro_widget_tests.sh android "${{ matrix.widget }}"

- name: "Archive runtime logs"
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 #v4
Expand All @@ -555,8 +579,9 @@ jobs:
path: packages/pluggableWidgets/**/artifacts/
if-no-files-found: ignore

ios-tests:
ios-widget-tests:
needs: [scope, mendix-version, project, ios-app]
if: ${{ github.event.inputs.workspace != 'js-actions' || github.event_name == 'schedule' }}
runs-on: macos-15
timeout-minutes: 60
strategy:
Expand Down Expand Up @@ -645,9 +670,9 @@ jobs:
- name: "Run iOS tests"
run: |
chmod +x maestro/helpers/prepare_ios.sh
chmod +x maestro/run_maestro_tests.sh
chmod +x maestro/run_maestro_widget_tests.sh
bash maestro/helpers/prepare_ios.sh
bash maestro/run_maestro_tests.sh ios "${{ matrix.widget }}"
bash maestro/run_maestro_widget_tests.sh ios "${{ matrix.widget }}"

- name: "Archive runtime logs"
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 #v4
Expand All @@ -671,8 +696,176 @@ jobs:
path: packages/pluggableWidgets/**/artifacts/
if-no-files-found: ignore

android-js-tests:
if: ${{ github.event.inputs.workspace == '*-native' || github.event_name == 'schedule' || github.event.inputs.workspace == 'js-actions'}}
needs: [mendix-version, project, android-app]
runs-on: ubuntu-22.04
timeout-minutes: 90
steps:
- name: "Check out code"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
fetch-depth: 0
- name: "Set up node"
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
with:
node-version-file: .nvmrc
cache: yarn
- name: "Install dependencies"
run: yarn install --immutable
- name: "Download project MDA file"
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: mda
- name: "Download Android app"
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: android-app
path: android-app
- name: "Start runtime"
uses: ./.github/actions/start-runtime
with:
mda-file: automation.mda
mendix-version: ${{ needs.mendix-version.outputs.mendix_version }}
- name: "Install Maestro"
run: |
mkdir -p $HOME/.local/bin
curl -L "https://github.com/mobile-dev-inc/maestro/releases/latest/download/maestro.zip" -o maestro.zip
unzip maestro.zip -d $HOME/.local/bin
chmod +x $HOME/.local/bin/maestro/bin/maestro
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Verify maestro
run: $HOME/.local/bin/maestro/bin/maestro --version
- name: Set up Android SDK
run: echo "ANDROID_HOME=$ANDROID_SDK_ROOT" >> $GITHUB_ENV
- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: "Run android tests"
uses: reactivecircus/android-emulator-runner@62dbb605bba737720e10b196cb4220d374026a6d # v2.0.0
with:
api-level: 30
target: google_apis
arch: x86_64
profile: pixel
emulator-options: "-no-window -gpu swiftshader_indirect -no-boot-anim -no-snapshot -memory 4096 -cores 4"
disable-animations: true
script: |
chmod +x maestro/helpers/prepare_android.sh
chmod +x maestro/run_maestro_jsactions_tests.sh
bash maestro/helpers/prepare_android.sh
bash maestro/run_maestro_jsactions_tests.sh android

- name: "Archive runtime logs"
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 #v4
if: always()
with:
name: android-runtime-logs-js-actions
path: log/*.log
if-no-files-found: ignore
- name: "Archive test screenshots"
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 #v4
if: always()
with:
name: android-screenshots-js-actions
path: ${{ github.workspace }}/maestro/images/actual/android/**/*.png
if-no-files-found: ignore
- name: "Archive artifacts"
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 #v4
if: always()
with:
name: android-artifacts-js-actions
path: packages/pluggableWidgets/**/artifacts/
if-no-files-found: ignore

ios-js-tests:
if: ${{ github.event.inputs.workspace == '*-native' || github.event_name == 'schedule' || github.event.inputs.workspace == 'js-actions'}}
needs: [mendix-version, project, ios-app]
runs-on: macos-15
timeout-minutes: 90
steps:
- name: "Check out code"
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
fetch-depth: 0
- name: "Set up node"
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
with:
node-version-file: .nvmrc
cache: yarn
- name: "Install dependencies"
run: |
yarn cache clean
yarn install --immutable
- name: "Download project MDA file"
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: mda
- name: "Start runtime"
uses: ./.github/actions/start-runtime
with:
mda-file: automation.mda
mendix-version: ${{ needs.mendix-version.outputs.mendix_version }}

- name: "Download iOS app"
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: ios-app
path: ios-app
- name: Check iOS App Path
run: ls ios-app

- name: "Verify Xcode CLI Tools"
run: |
if ! xcode-select --print-path; then
echo "Xcode CLI tools not set. Setting them now."
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
else
echo "Xcode CLI tools are already configured."
fi
- name: "Install Maestro"
run: |
mkdir -p $HOME/.local/bin
curl -L "https://github.com/mobile-dev-inc/maestro/releases/latest/download/maestro.zip" -o maestro.zip
unzip maestro.zip -d $HOME/.local/bin
chmod +x $HOME/.local/bin/maestro/bin/maestro
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: "Verify maestro"
run: $HOME/.local/bin/maestro/bin/maestro --version
- name: "List Available Simulators"
run: xcrun simctl list devices
- name: "Run iOS tests"
run: |
chmod +x maestro/helpers/prepare_ios.sh
chmod +x maestro/run_maestro_jsactions_tests.sh
bash maestro/helpers/prepare_ios.sh
bash maestro/run_maestro_jsactions_tests.sh ios

- name: "Archive runtime logs"
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 #v4
if: always()
with:
name: ios-runtime-logs-js-actions
path: log/*.log
if-no-files-found: ignore
- name: "Archive test screenshots"
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 #v4
if: always()
with:
name: ios-screenshots-js-actions
path: ${{ github.workspace }}/maestro/images/actual/ios/**/*.png
if-no-files-found: ignore
- name: "Archive artifacts"
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 #v4
if: always()
with:
name: ios-artifacts-js-actions
path: packages/pluggableWidgets/**/artifacts/
if-no-files-found: ignore
compare-screenshots:
needs: [scope, android-tests, ios-tests]
needs: [scope, android-widget-tests, ios-widget-tests, android-js-tests, ios-js-tests]
runs-on: ubuntu-latest
if: always()
env:
Expand All @@ -690,6 +883,10 @@ jobs:
gh run download ${{ github.run_id }} --name android-screenshots-${widget} --dir images/actual/android/ || true
ls -l images/actual/android/
done
# Download JS actions screenshots
echo "Downloading android-screenshots-js-actions"
gh run download ${{ github.run_id }} --name android-screenshots-js-actions --dir images/actual/android/ || true
ls -l images/actual/android/

- name: "Download iOS screenshots"
run: |
Expand All @@ -700,8 +897,11 @@ jobs:
gh run download ${{ github.run_id }} --name ios-screenshots-${widget} --dir images/actual/ios/ || true
ls -l images/actual/ios/
done
# Download JS actions screenshots
echo "Downloading ios-screenshots-js-actions"
gh run download ${{ github.run_id }} --name ios-screenshots-js-actions --dir images/actual/ios/ || true
ls -l images/actual/ios/


- name: "Set up node"
uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a # v4
with:
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added maestro/images/expected/android/clipboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file added maestro/images/expected/ios/clipboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added maestro/images/expected/ios/toggle_sidebar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading