diff --git a/.github/workflows/visual-tests-demos.yml b/.github/workflows/visual-tests-demos.yml index d69ff7bbd0a5..36be57f4777f 100644 --- a/.github/workflows/visual-tests-demos.yml +++ b/.github/workflows/visual-tests-demos.yml @@ -26,76 +26,23 @@ jobs: id: check run: echo "should-run=${{ env.RUN_TESTS }}" >> $GITHUB_OUTPUT - get-changes: - runs-on: ubuntu-latest - needs: check-should-run - if: github.event_name == 'pull_request' && needs.check-should-run.outputs.should-run == 'true' - name: Get changed demos - timeout-minutes: 5 - outputs: - has-changed-demos: ${{ steps.check-changes.outputs.has-changed-demos }} - - steps: - - name: Get sources - uses: actions/checkout@v6 - - - name: Get changed files - uses: DevExpress/github-actions/get-changed-files@get-changed-files - with: - gh-token: ${{ secrets.GITHUB_TOKEN }} - paths: 'apps/demos/Demos/**/*' - output: apps/demos/changed-files.json - - - name: Display changed files - id: check-changes - run: | - HAS_CHANGED="false" - if [ -f "apps/demos/changed-files.json" ]; then - DEMO_COUNT=$(jq length apps/demos/changed-files.json) - echo "Found changed-files.json" - echo "Content of changed-files.json:" - cat apps/demos/changed-files.json - echo "Number of changed files: $DEMO_COUNT" - if [ "$DEMO_COUNT" -gt 0 ]; then - HAS_CHANGED="true" - fi - else - echo "changed-files.json not found" - fi - echo "has-changed-demos=${HAS_CHANGED}" >> $GITHUB_OUTPUT - - - name: Upload artifacts - uses: actions/upload-artifact@v7 - with: - name: changed-demos - path: apps/demos/changed-files.json - retention-days: 1 - determine-framework-tests-scope: runs-on: ubuntu-slim name: Determine scope for framework tests - needs: [check-should-run, get-changes] + needs: [check-should-run] if: | !cancelled() && - needs.check-should-run.outputs.should-run == 'true' && - (needs.get-changes.result == 'success' || needs.get-changes.result == 'skipped') + needs.check-should-run.outputs.should-run == 'true' outputs: framework-tests-scope: ${{ steps.determine.outputs.framework-tests-scope }} steps: - name: Determine framework tests scope id: determine + # Always run the full matrix: any library change can affect demos, and PR labels are often forgotten. run: | - if [ "${{ github.event_name }}" != "pull_request" ] || [ "${{ contains(github.event.pull_request.labels.*.name, 'force all tests') }}" = "true" ]; then - echo "Framework tests scope: all demos" - echo "framework-tests-scope=all" >> $GITHUB_OUTPUT - elif [ "${{ needs.get-changes.outputs.has-changed-demos }}" = "true" ]; then - echo "Framework tests scope: changed demos" - echo "framework-tests-scope=changed" >> $GITHUB_OUTPUT - else - echo "Framework tests NOT needed" - echo "framework-tests-scope=none" >> $GITHUB_OUTPUT - fi + echo "Framework tests scope: all demos" + echo "framework-tests-scope=all" >> $GITHUB_OUTPUT determine-jquery-test-matrix: runs-on: ubuntu-slim @@ -112,33 +59,24 @@ jobs: - name: Build matrix id: matrix run: | - base_matrix=$(cat <<'JSON' - [ - { "STRATEGY": "screenshots", "THEME": "material.blue.light", "CONSTEL": "jquery(1/3)" }, - { "STRATEGY": "screenshots", "THEME": "material.blue.light", "CONSTEL": "jquery(2/3)" }, - { "STRATEGY": "screenshots", "THEME": "material.blue.light", "CONSTEL": "jquery(3/3)" }, - { "STRATEGY": "screenshots", "THEME": "fluent.blue.light", "CONSTEL": "jquery(1/3)" }, - { "STRATEGY": "screenshots", "THEME": "fluent.blue.light", "CONSTEL": "jquery(2/3)" }, - { "STRATEGY": "screenshots", "THEME": "fluent.blue.light", "CONSTEL": "jquery(3/3)" }, - { "STRATEGY": "accessibility", "THEME": "material.blue.light", "CONSTEL": "jquery" }, - { "STRATEGY": "accessibility", "THEME": "fluent.blue.light", "CONSTEL": "jquery" } - ] - JSON - ) - - dark_accessibility_matrix=$(cat <<'JSON' - [ - { "STRATEGY": "accessibility", "THEME": "material.blue.dark", "CONSTEL": "jquery" }, - { "STRATEGY": "accessibility", "THEME": "fluent.blue.dark", "CONSTEL": "jquery" } - ] + matrix=$(cat <<'JSON' + { + "include": [ + { "STRATEGY": "screenshots", "THEME": "material.blue.light", "CONSTEL": "jquery(1/3)" }, + { "STRATEGY": "screenshots", "THEME": "material.blue.light", "CONSTEL": "jquery(2/3)" }, + { "STRATEGY": "screenshots", "THEME": "material.blue.light", "CONSTEL": "jquery(3/3)" }, + { "STRATEGY": "screenshots", "THEME": "fluent.blue.light", "CONSTEL": "jquery(1/3)" }, + { "STRATEGY": "screenshots", "THEME": "fluent.blue.light", "CONSTEL": "jquery(2/3)" }, + { "STRATEGY": "screenshots", "THEME": "fluent.blue.light", "CONSTEL": "jquery(3/3)" }, + { "STRATEGY": "accessibility", "THEME": "material.blue.light", "CONSTEL": "jquery" }, + { "STRATEGY": "accessibility", "THEME": "fluent.blue.light", "CONSTEL": "jquery" }, + { "STRATEGY": "accessibility", "THEME": "material.blue.dark", "CONSTEL": "jquery" }, + { "STRATEGY": "accessibility", "THEME": "fluent.blue.dark", "CONSTEL": "jquery" } + ] + } JSON ) - - matrix=$(jq -c -n \ - --argjson base "$base_matrix" \ - --argjson darkAccessibility "$dark_accessibility_matrix" \ - --arg frameworkTestsScope "${{ needs.determine-framework-tests-scope.outputs.framework-tests-scope }}" \ - '{ include: ($base + (if $frameworkTestsScope != "none" then $darkAccessibility else [] end)) }') + matrix=$(echo "$matrix" | jq -c .) echo "matrix=$matrix" >> $GITHUB_OUTPUT @@ -228,15 +166,7 @@ jobs: ${{ runner.os }}-nx-v2-${{ github.workflow }}-${{ github.job }}- ${{ runner.os }}-nx-v2- - - name: DevExtreme - Build - if: needs.determine-framework-tests-scope.outputs.framework-tests-scope == 'none' - shell: bash - run: | - pnpm exec nx build devextreme-scss - pnpm exec nx build devextreme -c testing - - name: DevExtreme - Build-all - if: needs.determine-framework-tests-scope.outputs.framework-tests-scope != 'none' run: pnpm nx all:build-testing workflows - name: Zip artifacts (for jQuery tests) @@ -252,7 +182,6 @@ jobs: retention-days: 1 - name: Move packages - if: needs.determine-framework-tests-scope.outputs.framework-tests-scope != 'none' run: | mv ./packages/devextreme/artifacts/npm/devextreme/*.tgz ./devextreme-installer.tgz mv ./packages/devextreme/artifacts/npm/devextreme-dist/*.tgz ./devextreme-dist-installer.tgz @@ -261,7 +190,6 @@ jobs: mv ./packages/devextreme-vue/npm/*.tgz ./devextreme-vue-installer.tgz - name: Copy build artifacts - if: needs.determine-framework-tests-scope.outputs.framework-tests-scope != 'none' uses: actions/upload-artifact@v7 with: name: devextreme-sources @@ -364,14 +292,6 @@ jobs: - name: Get sources uses: actions/checkout@v6 - - name: Download artifacts - if: github.event_name == 'pull_request' - uses: actions/download-artifact@v8 - with: - name: changed-demos - path: apps/demos - continue-on-error: true - - name: Download devextreme sources uses: actions/download-artifact@v8 with: @@ -424,7 +344,6 @@ jobs: - name: Run lint on all demos id: lint_all - if: needs.determine-framework-tests-scope.outputs.framework-tests-scope == 'all' continue-on-error: true working-directory: apps/demos env: @@ -432,51 +351,19 @@ jobs: NODE_OPTIONS: --max-old-space-size=8192 run: pnpm exec nx lint - - name: Run lint on changed demos - id: lint_changed - if: needs.determine-framework-tests-scope.outputs.framework-tests-scope == 'changed' - continue-on-error: true - working-directory: apps/demos - env: - DEBUG: 'eslint:cli-engine,stylelint:standalone' - run: | - pnpm exec nx lint-non-demos - - if [ -f "changed-files.json" ]; then - echo "Running lint-demos on changed files" - CHANGED_DEMOS=$(jq -r '.[].filename' changed-files.json \ - | grep '^apps/demos/Demos/' \ - | sed 's|^apps/demos/||' \ - | while read f; do - [ -f "$f" ] && echo "$f" - done \ - | tr '\n' ' ') - if [ ! -z "$CHANGED_DEMOS" ]; then - echo "Changed demo files: $CHANGED_DEMOS" - pnpm run eslint $CHANGED_DEMOS - else - echo "No demo files changed, skipping lint-demos" - fi - else - echo "changed-files.json not found" - pnpm run lint-demos - fi - - name: Check TS and lint results if: always() env: TS_VUE_OUTCOME: ${{ steps.ts_vue.outcome }} TS_REACT_OUTCOME: ${{ steps.ts_react.outcome }} LINT_ALL_OUTCOME: ${{ steps.lint_all.outcome }} - LINT_CHANGED_OUTCOME: ${{ steps.lint_changed.outcome }} run: | failed=0 for check in \ "Demos - Check Vue TS:$TS_VUE_OUTCOME" \ "Demos - Check React TS:$TS_REACT_OUTCOME" \ - "Run lint on all demos:$LINT_ALL_OUTCOME" \ - "Run lint on changed demos:$LINT_CHANGED_OUTCOME"; do + "Run lint on all demos:$LINT_ALL_OUTCOME"; do name="${check%%:*}" outcome="${check#*:}" @@ -488,119 +375,6 @@ jobs: exit "$failed" - check-generated-demos-changed: - name: Check generated demos (changed only) - runs-on: devextreme-shr2 - timeout-minutes: 20 - needs: [check-should-run, get-changes, build-devextreme, determine-framework-tests-scope] - if: | - !cancelled() && - needs.check-should-run.outputs.should-run == 'true' && - needs.determine-framework-tests-scope.result == 'success' && - needs.determine-framework-tests-scope.outputs.framework-tests-scope == 'changed' && - needs.build-devextreme.result == 'success' - - steps: - - name: Get sources - uses: actions/checkout@v6 - - - name: Download changed demos - uses: actions/download-artifact@v8 - with: - name: changed-demos - path: apps/demos - continue-on-error: true - - - name: Detect changed React TS demos - id: changed-react-demos - working-directory: apps/demos - run: | - if [ ! -f "changed-files.json" ]; then - echo "changed-files.json not found, skipping generated JS demos check" - echo "has-react-demos=false" >> $GITHUB_OUTPUT - exit 0 - fi - - jq -r '.[].filename' changed-files.json \ - | grep '/React/' \ - | grep -E '\.tsx?$' \ - | sed 's|^apps/demos/||' \ - | sed -E 's|/[^/]*\.tsx?$||' \ - | sort \ - | uniq > changed-react-demos.txt || true - - if [ -s changed-react-demos.txt ]; then - echo "Changed React demos:" - cat changed-react-demos.txt - echo "has-react-demos=true" >> $GITHUB_OUTPUT - else - echo "No React demos found in changed files, skipping conversion" - echo "has-react-demos=false" >> $GITHUB_OUTPUT - fi - - - uses: pnpm/action-setup@v6 - if: steps.changed-react-demos.outputs.has-react-demos == 'true' - with: - run_install: false - - - name: Use Node.js - if: steps.changed-react-demos.outputs.has-react-demos == 'true' - uses: actions/setup-node@v6 - with: - node-version-file: '.node-version' - - - name: Download devextreme sources - if: steps.changed-react-demos.outputs.has-react-demos == 'true' - uses: actions/download-artifact@v8 - with: - name: devextreme-sources - - - name: Get pnpm store directory - if: steps.changed-react-demos.outputs.has-react-demos == 'true' - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - - uses: actions/cache/restore@v5 - if: steps.changed-react-demos.outputs.has-react-demos == 'true' - name: Restore pnpm cache - with: - path: ${{ env.STORE_PATH }} - key: ${{ runner.os }}-pnpm-cache-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-cache - - - name: Install dependencies - if: steps.changed-react-demos.outputs.has-react-demos == 'true' - run: pnpm install --frozen-lockfile - - - name: Install tgz - if: steps.changed-react-demos.outputs.has-react-demos == 'true' - working-directory: apps/demos - run: pnpm add --ignore-workspace --allow-build=core-js --allow-build=inferno devextreme-aspnet-data@5.1.0 devextreme-aspnet-data-nojquery@5.1.0 ../../devextreme-installer.tgz ../../devextreme-dist-installer.tgz ../../devextreme-react-installer.tgz ../../devextreme-vue-installer.tgz ../../devextreme-angular-installer.tgz && rm -f pnpm-workspace.yaml pnpm-lock.yaml - - - name: Prepare JS - if: steps.changed-react-demos.outputs.has-react-demos == 'true' - working-directory: apps/demos - run: pnpm run prepare-js - - - name: Check generated JS demos - if: steps.changed-react-demos.outputs.has-react-demos == 'true' - working-directory: apps/demos - run: | - echo "Running convert-to-js on changed files only" - xargs -r pnpm run convert-to-js < changed-react-demos.txt - - git add ./Demos -N - - if git diff --exit-code . ':!package.json' ; then - echo "Generated JS demos are up-to-date" - else - echo "Generated JS demos are outdated. Execute 'pnpm run convert-to-js split' and commit changes." - echo "If you see another diff, ensure that extra listed files have LF endings." - exit 1 - fi - check-generated-demos-all: name: Check generated demos runs-on: ${{ github.event_name == 'merge_group' && 'devextreme-shr2-ondemand' || 'devextreme-shr2' }} @@ -786,7 +560,6 @@ jobs: env: NODE_OPTIONS: --max-old-space-size=8192 STRATEGY: ${{ matrix.STRATEGY }} - CHANGEDFILEINFOSPATH: changed-files.json BROWSERS: ${{ steps.chrome-flags.outputs.flags }} #DEBUG: hammerhead:*,testcafe:* CONCURRENCY: 4 @@ -977,136 +750,10 @@ jobs: path: ${{ github.workspace }}/apps/demos/testing/artifacts/compared-screenshots/**/* if-no-files-found: ignore - testcafe-frameworks-changed: - needs: [check-should-run, determine-framework-tests-scope, build-demos] - if: | - !cancelled() && - needs.check-should-run.outputs.should-run == 'true' && - needs.determine-framework-tests-scope.result == 'success' && - needs.determine-framework-tests-scope.outputs.framework-tests-scope == 'changed' && - needs.build-demos.result == 'success' - strategy: - fail-fast: false - matrix: - CONSTEL: [react, vue, angular] - THEME: ['fluent.blue.light'] - - runs-on: ${{ github.event_name == 'merge_group' && 'devextreme-shr2-ondemand' || 'devextreme-shr2' }} - name: ${{ matrix.CONSTEL }}-screenshots-${{ matrix.THEME }} - timeout-minutes: 60 - - steps: - - name: Get sources - uses: actions/checkout@v6 - - - name: Setup Chrome - uses: ./.github/actions/setup-chrome - with: - chrome-version: '150.0.7871.181' - - - name: Use Node.js - uses: actions/setup-node@v6 - with: - node-version-file: '.node-version' - - - name: Download devextreme sources - uses: actions/download-artifact@v8 - with: - name: devextreme-sources - - - name: Download changed demos - uses: actions/download-artifact@v8 - with: - name: changed-demos - path: apps/demos - continue-on-error: true - - - uses: pnpm/action-setup@v6 - with: - run_install: false - - - name: Get pnpm store directory - shell: bash - run: | - echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV - - - uses: actions/cache/restore@v5 - name: Restore pnpm cache - with: - path: ${{ env.STORE_PATH }} - key: ${{ runner.os }}-pnpm-cache-${{ hashFiles('**/pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm-cache - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Install tgz - working-directory: apps/demos - run: pnpm add --ignore-workspace --allow-build=core-js --allow-build=inferno devextreme-aspnet-data@5.1.0 devextreme-aspnet-data-nojquery@5.1.0 ../../devextreme-installer.tgz ../../devextreme-dist-installer.tgz ../../devextreme-react-installer.tgz ../../devextreme-vue-installer.tgz ../../devextreme-angular-installer.tgz && rm -f pnpm-workspace.yaml pnpm-lock.yaml - - - name: Prepare JS - working-directory: apps/demos - run: pnpm run prepare-js - - - name: Update bundles config - working-directory: apps/demos - run: pnpm run update-config - - - name: Create bundles dir - run: mkdir -p apps/demos/bundles - - - name: Download bundles artifacts - uses: actions/download-artifact@v8 - with: - name: devextreme-bundles - path: apps/demos/bundles - - - name: Download changes artifacts - uses: actions/download-artifact@v8 - with: - name: changed-demos - path: apps/demos - - - name: Run Web Server - run: | - python -m http.server 8080 & - python -m http.server 8081 & - python -m http.server 8082 & - python -m http.server 8083 & - - - name: Run TestCafe tests - shell: bash - working-directory: apps/demos - env: - CHANGEDFILEINFOSPATH: changed-files.json - BROWSERS: chrome:headless --window-size=1200,800 --disable-gpu --no-sandbox --disable-dev-shm-usage --disable-partial-raster --disable-skia-runtime-opts --run-all-compositor-stages-before-draw --disable-new-content-rendering-timeout --disable-threaded-animation --disable-threaded-scrolling --disable-checker-imaging --disable-image-animation-resync --use-gl=swiftshader --disable-features=PaintHolding --js-flags=--random-seed=2147483647 --font-render-hinting=none --disable-font-subpixel-positioning - # DEBUG: hammerhead:*,testcafe:* - CONCURRENCY: 1 - CONSTEL: ${{ matrix.CONSTEL }} - THEME: ${{ matrix.THEME }} - # DISABLE_DEMO_TEST_SETTINGS: all # Uncomment to ignore all the visualtestrc.json settings - # DISABLE_DEMO_TEST_SETTINGS: ignore # Uncomment to ignore the `ignore` field - # DISABLE_DEMO_TEST_SETTINGS: comparison-options # Uncomment to ignore the `comparison-options` field - CI_ENV: true # The `ignore` field in the visualtestrc.json should be disabled when running test locally - run: pnpm exec nx test-testcafe - - - name: Sanitize job name - if: ${{ failure() }} - run: echo "JOB_NAME=$(echo "${{ matrix.CONSTEL }}-${{ matrix.THEME }}" | tr '/' '-')" >> $GITHUB_ENV - - - name: Copy screenshots artifacts - if: ${{ failure() }} - uses: actions/upload-artifact@v7 - with: - name: screenshots-${{ env.JOB_NAME }} - path: ${{ github.workspace }}/apps/demos/testing/artifacts/compared-screenshots/**/* - if-no-files-found: ignore - merge-artifacts: runs-on: ubuntu-latest - needs: [testcafe-jquery, testcafe-frameworks-all, testcafe-frameworks-changed] - if: ${{ !cancelled() && (needs.testcafe-jquery.result == 'failure' || needs.testcafe-frameworks-all.result == 'failure' || needs.testcafe-frameworks-changed.result == 'failure') }} + needs: [testcafe-jquery, testcafe-frameworks-all] + if: ${{ !cancelled() && (needs.testcafe-jquery.result == 'failure' || needs.testcafe-frameworks-all.result == 'failure') }} steps: - name: Merge jQuery screenshot artifacts @@ -1119,7 +766,7 @@ jobs: delete-merged: true - name: Merge React screenshot artifacts - if: needs.testcafe-frameworks-all.result == 'failure' || needs.testcafe-frameworks-changed.result == 'failure' + if: needs.testcafe-frameworks-all.result == 'failure' uses: actions/upload-artifact/merge@v7 continue-on-error: true with: @@ -1128,7 +775,7 @@ jobs: delete-merged: true - name: Merge Vue screenshot artifacts - if: needs.testcafe-frameworks-all.result == 'failure' || needs.testcafe-frameworks-changed.result == 'failure' + if: needs.testcafe-frameworks-all.result == 'failure' uses: actions/upload-artifact/merge@v7 continue-on-error: true with: @@ -1137,7 +784,7 @@ jobs: delete-merged: true - name: Merge Angular screenshot artifacts - if: needs.testcafe-frameworks-all.result == 'failure' || needs.testcafe-frameworks-changed.result == 'failure' + if: needs.testcafe-frameworks-all.result == 'failure' uses: actions/upload-artifact/merge@v7 continue-on-error: true with: