diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml new file mode 100644 index 00000000000..6a8a310e239 --- /dev/null +++ b/.github/workflows/validation.yml @@ -0,0 +1,597 @@ +name: Validation + +on: + pull_request: + branches: ['main', '25.*'] + merge_group: + workflow_dispatch: + inputs: + components: + description: 'Space-separated component names (e.g. "grid combo-box"), empty for all' + required: false + default: '' + shards: + description: 'Number of parallel IT shards' + required: false + default: '5' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.merge_group.head_ref || github.ref }} + cancel-in-progress: true + +env: + FORK_COUNT: 4 + +jobs: + build: + name: Build + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + contents: read + outputs: + skip: ${{ steps.skip-ci.outputs.skip }} + components: ${{ steps.components.outputs.elements }} + build-cache-key: ${{ steps.build-key.outputs.key }} + steps: + - name: Set Maven args + run: | + args="-ntp -B" + [ "${{ runner.debug }}" != "1" ] && args="$args -q" + echo "MAVEN_ARGS=$args" >> "$GITHUB_ENV" + + - uses: actions/checkout@v6 + with: + ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha || github.sha }} + fetch-depth: ${{ github.event_name == 'merge_group' && 50 || 1 }} + + - name: Check for skip-ci + id: skip-ci + if: github.event_name == 'pull_request' || github.event_name == 'merge_group' + env: + PR_TITLE: ${{ github.event.pull_request.title }} + run: | + if [ "${{ github.event_name }}" = "merge_group" ]; then + echo "skip=false" >> "$GITHUB_OUTPUT" + exit 0 + fi + if echo "$PR_TITLE" | grep -q '\[skip ci\]'; then + echo "skip=true" >> "$GITHUB_OUTPUT" + else + echo "skip=false" >> "$GITHUB_OUTPUT" + fi + + - name: Compute build cache key + id: build-key + if: steps.skip-ci.outputs.skip != 'true' + env: + KEY: ${{ runner.os }}-build-${{ hashFiles('**/pom.xml', '**/src/main/java/**', '**/src/main/resources/**', '!integration-tests/**', '!**/frontend/generated/**', 'vaadin-charts-flow-parent/vaadin-charts-flow-svg-generator/*.js') }} + run: echo "key=$KEY" >> "$GITHUB_OUTPUT" + + - name: Restore build cache + id: build-cache + if: steps.skip-ci.outputs.skip != 'true' + uses: actions/cache@v5 + with: + path: | + ~/.m2/repository/com/vaadin + vaadin-charts-flow-parent/vaadin-charts-flow-svg-generator/src/main/resources/META-INF/frontend/generated/ + key: ${{ steps.build-key.outputs.key }} + + - name: Setup JDK 21 + if: steps.skip-ci.outputs.skip != 'true' && steps.build-cache.outputs.cache-hit != 'true' + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'temurin' + cache: 'maven' + + - name: Setup Node + if: steps.skip-ci.outputs.skip != 'true' && steps.build-cache.outputs.cache-hit != 'true' + uses: actions/setup-node@v6 + with: + node-version: '20' + + - name: Show environment info + if: steps.skip-ci.outputs.skip != 'true' && steps.build-cache.outputs.cache-hit != 'true' + run: | + java -version + mvn -version + node --version + npm --version + google-chrome --version + chromedriver --version + + - name: Install artifacts + if: steps.skip-ci.outputs.skip != 'true' && steps.build-cache.outputs.cache-hit != 'true' + run: | + mvn install -Dmaven.test.skip=true -Drelease -T $FORK_COUNT $MAVEN_ARGS || { + echo "::warning::First attempt failed (Maven multi-thread race). Retrying..." + sleep 15 + mvn install -Dmaven.test.skip=true -Drelease -T $FORK_COUNT $MAVEN_ARGS + } + + - name: Detect modified components + id: components + if: steps.skip-ci.outputs.skip != 'true' + env: + GH_TOKEN: ${{ github.token }} + run: | + elements="${{ github.event.inputs.components || '' }}" + changed_files="" + if [ -n "$elements" ]; then + echo "elements=$elements" >> "$GITHUB_OUTPUT" + exit 0 + fi + if [ "${{ github.event_name }}" = "pull_request" ]; then + pr_number="${{ github.event.pull_request.number }}" + changed_files=$(gh api "repos/${{ github.repository }}/pulls/$pr_number/files" --jq '.[].filename') + elif [ "${{ github.event_name }}" = "merge_group" ]; then + changed_files=$(git diff --name-only "${{ github.event.merge_group.base_sha }}" "${{ github.event.merge_group.head_sha }}") + fi + if [ -n "$changed_files" ]; then + modified=$(echo "$changed_files" \ + | grep 'vaadin.*flow-parent' \ + | sed 's,^vaadin-\(.*\)-flow-parent.*,\1,' \ + | sort -u) + nmods=$(echo "$modified" | wc -w | tr -d ' ') + all_files=$(echo "$changed_files" | sort -u | tr -d '[:space:]') + component_files=$(echo "$changed_files" | grep 'vaadin.*flow-parent' | sort -u | tr -d '[:space:]') + if [ "$nmods" -lt 5 ] && [ ${#all_files} -eq ${#component_files} ]; then + elements=$(echo $modified | tr '\n' ' ') + echo "Running partial build for: $elements" + fi + fi + echo "elements=$elements" >> "$GITHUB_OUTPUT" + + fast-tests: + name: ${{ matrix.name }} + needs: build + if: needs.build.outputs.skip != 'true' + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + contents: read + outputs: + matrix: ${{ steps.shards.outputs.matrix }} + has-tests: ${{ steps.shards.outputs.has-tests }} + war-cache-key: ${{ steps.war-key.outputs.key }} + strategy: + fail-fast: true + matrix: + include: + - name: Unit tests + type: unit + - name: WTR tests + type: wtr + - name: Package WAR + type: war + steps: + - name: Set Maven args + run: | + args="-ntp -B" + [ "${{ runner.debug }}" != "1" ] && args="$args -q" + echo "MAVEN_ARGS=$args" >> "$GITHUB_ENV" + + - uses: actions/checkout@v6 + with: + ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha || github.sha }} + fetch-depth: 1 + + - name: Setup Node + if: matrix.type != 'unit' + uses: actions/setup-node@v6 + with: + node-version: '20' + + - name: npm install + if: matrix.type != 'unit' + run: npm ci --ignore-scripts + + - name: Merge ITs + if: matrix.type == 'war' + run: node scripts/mergeITs.js ${{ needs.build.outputs.components }} + + - name: Compute WAR cache key + if: matrix.type == 'war' + id: war-key + env: + KEY: ${{ runner.os }}-war-${{ hashFiles('**/pom.xml', '**/src/main/java/**', '**/src/main/resources/**', 'integration-tests/src/test/java/**') }} + run: echo "key=$KEY" >> "$GITHUB_OUTPUT" + + - name: Restore WAR cache + if: matrix.type == 'war' + id: war-cache + uses: actions/cache@v5 + with: + path: | + integration-tests/pom.xml + integration-tests/target + key: ${{ steps.war-key.outputs.key }} + + - name: Setup JDK 21 + if: steps.war-cache.outputs.cache-hit != 'true' + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'temurin' + cache: 'maven' + + - name: Install TestBench license + if: env.TB_LICENSE != '' && steps.war-cache.outputs.cache-hit != 'true' + env: + TB_LICENSE: ${{ secrets.TB_LICENSE }} + run: | + mkdir -p ~/.vaadin + user="${TB_LICENSE%%/*}" + key="${TB_LICENSE#*/}" + echo "{\"username\":\"${user}\",\"proKey\":\"${key}\"}" > ~/.vaadin/proKey + + - name: Restore build cache + if: steps.war-cache.outputs.cache-hit != 'true' + id: build-cache + uses: actions/cache@v5 + with: + path: | + ~/.m2/repository/com/vaadin + vaadin-charts-flow-parent/vaadin-charts-flow-svg-generator/src/main/resources/META-INF/frontend/generated/ + key: ${{ needs.build.outputs.build-cache-key }} + fail-on-cache-miss: true + + - name: Run unit tests + if: matrix.type == 'unit' + run: mvn test -Drelease -T $FORK_COUNT -DskipSvgChartsBuild $MAVEN_ARGS + + - name: Upload unit test reports + if: always() && matrix.type == 'unit' + uses: actions/upload-artifact@v6 + with: + name: surefire-reports + path: '**/target/surefire-reports/TEST-*.xml' + retention-days: 1 + if-no-files-found: ignore + + - name: Run WTR tests + if: matrix.type == 'wtr' + run: node scripts/wtr.js ${{ needs.build.outputs.components }} + + - name: Upload WTR reports + if: always() && matrix.type == 'wtr' + uses: actions/upload-artifact@v6 + with: + name: wtr-reports + path: '**/wtr-results.xml' + retention-days: 1 + if-no-files-found: ignore + + - name: Package integration-tests WAR + if: matrix.type == 'war' && steps.war-cache.outputs.cache-hit != 'true' + run: | + mvn package -pl integration-tests \ + -Dvaadin.pnpm.enable -Drun-it -Drelease \ + -Dvaadin.productionMode -Dvaadin.force.production.build=true \ + -Dmaven.test.skip=true -DskipJetty $MAVEN_ARGS + + - name: Compile IT test sources + if: matrix.type == 'war' && steps.war-cache.outputs.cache-hit != 'true' + run: mvn test-compile -pl integration-tests -Drun-it -DskipFrontend -DskipJetty -DskipUnitTests $MAVEN_ARGS + + - name: Compute IT shards + if: matrix.type == 'war' + id: shards + env: + SHARDS: ${{ github.event.inputs.shards || '0' }} + TARGET_PER_SHARD: 35 + MAX_SHARDS: 10 + run: | + mapfile -t its < <(find integration-tests/src/test/java -name '*IT.java' -printf '%P\n' | sed -e 's|/|.|g' -e 's|\.java$||' | sort) + count=${#its[@]} + echo "Found $count IT classes" + if [ "$count" -eq 0 ]; then + echo "has-tests=false" >> "$GITHUB_OUTPUT" + echo 'matrix={"include":[]}' >> "$GITHUB_OUTPUT" + exit 0 + fi + n=$SHARDS + if [ "$n" -eq 0 ]; then + n=$(( (count + TARGET_PER_SHARD - 1) / TARGET_PER_SHARD )) + [ "$n" -lt 1 ] && n=1 + [ "$n" -gt "$MAX_SHARDS" ] && n=$MAX_SHARDS + fi + if [ "$n" -gt "$count" ]; then n=$count; fi + echo "$n shards for $count classes (~$(( count / n )) per shard)" + declare -a buckets + for i in $(seq 1 $n); do buckets[$i]=""; done + i=1 + for t in "${its[@]}"; do + if [ -n "${buckets[$i]}" ]; then buckets[$i]+=","; fi + buckets[$i]+="$t" + i=$((i+1)) + [ $i -gt $n ] && i=1 + done + json='{"include":[' + for k in $(seq 1 $n); do + [ $k -gt 1 ] && json+=',' + json+='{"shard":"'"$k"'","tests":"'"${buckets[$k]}"'"}' + done + json+=']}' + echo "$json" + echo "matrix=$json" >> "$GITHUB_OUTPUT" + echo "has-tests=true" >> "$GITHUB_OUTPUT" + + its: + name: ITs (${{ matrix.shard }}) + needs: [build, fast-tests] + if: needs.fast-tests.outputs.has-tests == 'true' + runs-on: ubuntu-latest + timeout-minutes: 60 + permissions: + contents: read + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.fast-tests.outputs.matrix) }} + steps: + - name: Set Maven args + run: | + args="-ntp -B" + [ "${{ runner.debug }}" != "1" ] && args="$args -q" + echo "MAVEN_ARGS=$args" >> "$GITHUB_ENV" + + - uses: actions/checkout@v6 + with: + ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha || github.sha }} + fetch-depth: 1 + + - name: Setup JDK 21 + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'temurin' + cache: 'maven' + + - name: Install TestBench license + if: env.TB_LICENSE != '' + env: + TB_LICENSE: ${{ secrets.TB_LICENSE }} + run: | + mkdir -p ~/.vaadin + user="${TB_LICENSE%%/*}" + key="${TB_LICENSE#*/}" + echo "{\"username\":\"${user}\",\"proKey\":\"${key}\"}" > ~/.vaadin/proKey + + - name: Restore build cache + uses: actions/cache@v5 + with: + path: | + ~/.m2/repository/com/vaadin + vaadin-charts-flow-parent/vaadin-charts-flow-svg-generator/src/main/resources/META-INF/frontend/generated/ + key: ${{ needs.build.outputs.build-cache-key }} + fail-on-cache-miss: true + + - name: Restore WAR cache + uses: actions/cache@v5 + with: + path: | + integration-tests/pom.xml + integration-tests/target + key: ${{ needs.fast-tests.outputs.war-cache-key }} + fail-on-cache-miss: true + + - name: Run integration tests (shard ${{ matrix.shard }}) + env: + SHARD_TESTS: ${{ matrix.tests }} + TESTBENCH_CHROME_EXTRA_ARGS: --no-sandbox --disable-dev-shm-usage + run: | + mvn -pl integration-tests -Drun-it \ + jetty:start-war failsafe:integration-test jetty:stop failsafe:verify \ + -Dvaadin.productionMode \ + -DskipFrontend \ + -Dfailsafe.forkCount=$FORK_COUNT \ + -Dcom.vaadin.testbench.Parameters.testsInParallel=1 \ + -Dfailsafe.rerunFailingTestsCount=2 \ + -Dmaven.test.redirectTestOutputToFile=true \ + -DchromeOptions="--no-sandbox,--disable-dev-shm-usage" \ + -Dit.test="$SHARD_TESTS" \ + -B + + - name: Upload error screenshots + if: failure() + uses: actions/upload-artifact@v6 + with: + name: error-screenshots-${{ matrix.shard }} + path: integration-tests/error-screenshots/ + retention-days: 5 + if-no-files-found: ignore + + - name: Upload failsafe reports + if: always() + uses: actions/upload-artifact@v6 + with: + name: failsafe-reports-${{ matrix.shard }} + path: integration-tests/target/failsafe-reports/ + retention-days: 1 + if-no-files-found: ignore + + results: + name: Collect tests + needs: [build, fast-tests, its] + if: always() && needs.build.result == 'success' + runs-on: ubuntu-latest + permissions: + contents: read + checks: write + actions: write + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ github.event.pull_request.head.sha || github.event.merge_group.head_sha || github.sha }} + fetch-depth: 1 + + - uses: actions/download-artifact@v8 + continue-on-error: true + with: + name: surefire-reports + path: surefire-reports + + - uses: actions/download-artifact@v8 + continue-on-error: true + with: + pattern: failsafe-reports-* + merge-multiple: true + path: failsafe-reports + + - uses: actions/download-artifact@v8 + continue-on-error: true + with: + name: wtr-reports + path: wtr-reports + + - name: Remove passing test reports + run: | + # Detect real failures via testsuite attributes (flaky retries leave + # tags but keep failures="0" errors="0" on the suite). + has_failures=false + for dir in surefire-reports failsafe-reports wtr-reports; do + [ -d "$dir" ] || continue + if find "$dir" -name '*.xml' | xargs grep -lE 'failures="[1-9]|errors="[1-9]' 2>/dev/null | grep -q .; then + has_failures=true + break + fi + done + echo "has_failures=$has_failures" >> $GITHUB_ENV + # Red build: keep only failing reports so dorny focuses on failures. + # Green build: keep all reports so every suite shows as passed. + if [ "$has_failures" = "true" ]; then + for dir in surefire-reports failsafe-reports wtr-reports; do + [ -d "$dir" ] || continue + find "$dir" -name '*.xml' | while read -r f; do + grep -qE 'failures="[1-9]|errors="[1-9]' "$f" || rm -f "$f" + done + done + fi + + - name: Check for unit test reports + id: unit-check + run: | + count=$(find surefire-reports -name 'TEST-*.xml' 2>/dev/null | wc -l | tr -d ' ') + echo "count=$count" >> $GITHUB_OUTPUT + + - name: Unit Tests header + if: steps.unit-check.outputs.count != '0' + run: echo "## Unit Tests" >> $GITHUB_STEP_SUMMARY + + - name: Publish unit test results + id: unit-dorny + if: steps.unit-check.outputs.count != '0' + uses: dorny/test-reporter@a43b3a5f7366b97d083190328d2c652e1a8b6aa2 + with: + name: Unit Tests + path: surefire-reports/**/TEST-*.xml + reporter: java-junit + list-tests: ${{ env.has_failures == 'true' && 'failed' || 'all' }} + list-suites: ${{ env.has_failures == 'true' && 'failed' || 'all' }} + fail-on-error: 'false' + + - name: Unit test compilation error + if: steps.unit-check.outputs.count == '0' && needs.fast-tests.result == 'failure' + run: | + echo ":x: Compilation failed. Check the **Unit tests** job for details." >> $GITHUB_STEP_SUMMARY + + - name: Check for IT reports + id: it-check + run: | + count=$(find failsafe-reports -name 'TEST-*.xml' 2>/dev/null | wc -l | tr -d ' ') + echo "count=$count" >> $GITHUB_OUTPUT + + - name: Integration Tests header + if: steps.it-check.outputs.count != '0' + run: echo "## Integration Tests" >> $GITHUB_STEP_SUMMARY + + - name: Publish integration test results + id: it-dorny + if: steps.it-check.outputs.count != '0' + uses: dorny/test-reporter@a43b3a5f7366b97d083190328d2c652e1a8b6aa2 + with: + name: Integration Tests + path: failsafe-reports/TEST-*.xml + reporter: java-junit + list-tests: ${{ env.has_failures == 'true' && 'failed' || 'all' }} + list-suites: ${{ env.has_failures == 'true' && 'failed' || 'all' }} + fail-on-error: 'false' + + - name: IT compilation error + if: steps.it-check.outputs.count == '0' && needs.fast-tests.result == 'failure' + run: | + echo ":x: Compilation failed. Check the **Package WAR** job for details." >> $GITHUB_STEP_SUMMARY + + - name: Check for WTR reports + id: wtr-check + run: | + count=$(find wtr-reports -name 'wtr-results.xml' 2>/dev/null | wc -l | tr -d ' ') + echo "count=$count" >> $GITHUB_OUTPUT + + - name: WTR Tests header + if: steps.wtr-check.outputs.count != '0' + run: echo "## WTR Tests" >> $GITHUB_STEP_SUMMARY + + - name: Publish WTR results + id: wtr-dorny + if: steps.wtr-check.outputs.count != '0' + uses: dorny/test-reporter@a43b3a5f7366b97d083190328d2c652e1a8b6aa2 + with: + name: WTR Tests + path: wtr-reports/**/wtr-results.xml + reporter: java-junit + list-tests: ${{ env.has_failures == 'true' && 'failed' || 'all' }} + list-suites: ${{ env.has_failures == 'true' && 'failed' || 'all' }} + fail-on-error: 'false' + + - name: WTR setup error + if: steps.wtr-check.outputs.count == '0' && needs.fast-tests.result == 'failure' + run: | + echo ":x: WTR setup or compilation failed. Check the **WTR tests** job for details." >> $GITHUB_STEP_SUMMARY + + - uses: actions/download-artifact@v8 + if: needs.its.result != 'success' + continue-on-error: true + with: + pattern: error-screenshots-* + merge-multiple: true + path: error-screenshots + + - name: Upload merged error screenshots + if: needs.its.result != 'success' + uses: actions/upload-artifact@v6 + with: + name: error-screenshots + path: error-screenshots/ + retention-days: 5 + if-no-files-found: ignore + + - name: Delete intermediate artifacts + if: always() + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + RUN_ID: ${{ github.run_id }} + run: | + gh api --paginate "repos/$GH_REPO/actions/runs/$RUN_ID/artifacts" \ + --jq '.artifacts[] | select( + (.name | startswith("error-screenshots-")) or + (.name | startswith("failsafe-reports-")) or + .name == "wtr-reports" or + .name == "surefire-reports" + ) | "\(.id) \(.name)"' \ + | while read -r id name; do + echo "Deleting artifact $name (id=$id)" + gh api -X DELETE "repos/$GH_REPO/actions/artifacts/$id" || true + done + + - name: Fail if any test failed + if: always() + run: | + failed=false + [[ "${{ steps.unit-dorny.outputs.conclusion }}" == "failure" ]] && failed=true + [[ "${{ steps.wtr-dorny.outputs.conclusion }}" == "failure" ]] && failed=true + [[ "${{ steps.it-dorny.outputs.conclusion }}" == "failure" ]] && failed=true + [[ "$failed" == "true" ]] && exit 1 || exit 0 diff --git a/.gitignore b/.gitignore index 518cf97b21d..994c46bcbbb 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,9 @@ vite.generated.ts /vite.config.ts node_modules .driver -package*json +**/package*json +!/package.json +!/package-lock.json pnpm* .npmrc .pnpmfile.cjs diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000000..11adfb53464 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,521 @@ +{ + "name": "vaadin-flow-components", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "vaadin-flow-components", + "version": "1.0.0", + "license": "APACHE", + "devDependencies": { + "replace-in-file": "6.1.0", + "xml2js": "^0.6.2" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/replace-in-file": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/replace-in-file/-/replace-in-file-6.1.0.tgz", + "integrity": "sha512-URzjyF3nucvejuY13HFd7O+Q6tFJRLKGHLYVvSh+LiZj3gFXzSYGnIkQflnJJulCAI2/RTZaZkpOtdVdW0EhQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "glob": "^7.1.6", + "yargs": "^15.3.1" + }, + "bin": { + "replace-in-file": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true, + "license": "ISC" + }, + "node_modules/sax": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", + "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC" + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "dev": true, + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + } + } +} diff --git a/package.json b/package.json index a77258905c0..2bcad45c4ce 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "devDependencies": { "replace-in-file": "6.1.0", - "xml2js": "^0.4.23" + "xml2js": "^0.6.2" }, "license": "APACHE" } diff --git a/pom.xml b/pom.xml index cade5ef814d..91db87ac4e0 100644 --- a/pom.xml +++ b/pom.xml @@ -416,12 +416,16 @@ - - + org.apache.maven.surefire - surefire-junit4 - ${maven.surefire.plugin.version} + surefire-junit47 + ${maven.failsafe.plugin.version} @@ -601,6 +605,35 @@ + + + ci-chrome-options + + + chromeOptions + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + ${chromeOptions} + + + + + + + merged-it diff --git a/scripts/build.sh b/scripts/build.sh deleted file mode 100755 index 5a364ea8983..00000000000 --- a/scripts/build.sh +++ /dev/null @@ -1,236 +0,0 @@ -#!/bin/bash - -## Read Arguments -if [ -n "$1" ] -then - for i in "$@" - do - case $i in - processors=*) - FORK_COUNT=`echo $i | cut -d = -f2`;; - parallel=*) - TESTS_IN_PARALLEL=`echo $i | cut -d = -f2`;; - pr=*) - PR=`echo $i | cut -d = -f2`;; - quiet) - quiet="-q";; - hub=*) - TBHUB=`echo $i | cut -d = -f2`;; - image=*) - SELENIUM_IMAGE=`echo $i | cut -d = -f2`;; - *) - modules="vaadin-$i-flow-parent/vaadin-$i-flow-integration-tests,$modules" - elements="$elements $i" - ;; - esac - done -fi - -args="$args -ntp -B $quiet" -verify="verify -Dvaadin.pnpm.enable" - -## compute modules that were modified in this PR -if [ -z "$modules" -a -n "$PR" ] -then - title=`curl -s "https://api.github.com/repos/vaadin/flow-components/pulls/$PR" | jq -r '. | .title'` - ## need to check whether changes in the root or not - modifiedAll=`curl -s "https://api.github.com/repos/vaadin/flow-components/pulls/$PR/files" \ - | jq -r '.[] | .filename' | sort -u | tr -d '[:space:]'` - modifiedComponent=`curl -s "https://api.github.com/repos/vaadin/flow-components/pulls/$PR/files" \ - | jq -r '.[] | .filename' | grep 'vaadin.*flow-parent' | sort -u | tr -d '[:space:]'` - modified=`curl -s "https://api.github.com/repos/vaadin/flow-components/pulls/$PR/files" \ - | jq -r '.[] | .filename' | grep 'vaadin.*flow-parent' | perl -pe 's,^vaadin-(.*)-flow-parent.*,$1,g' | sort -u` - - nmods=`echo "$modified" | wc -w` - [ "$nmods" -eq 1 ] && echo "$title" | grep -q " vaadin-$modified-flow " && partial=yes - [ -z "$partial" ] && [ $nmods -lt 5 ] && [ `echo ${#modifiedAll}` = `echo ${#modifiedComponent}` ] && partial=yes - - if [ -n "$partial" ] - then - for i in $modified - do - modules="vaadin-$i-flow-parent/vaadin-$i-flow-integration-tests,$modules" - elements="$elements $i" - done - fi -fi - -tcMsg() ( - echo "##teamcity[$1]" -) -# open a block in the TC tree output -tcLog() { - [ -n "$inblock" ] && tcMsg "blockClosed name='$inblock'" - inblock="$1" - tcMsg "blockOpened name='$inblock'" -} -# log in TC -tcStatus() { - [ "$1" = "0" ] && status=SUCCESS || status=FAILURE - [ "$1" = "0" ] && text="$3" || text="$2" - tcMsg "buildStatus status='$status' text='$text'" - exit $1 -} - -saveFailedTests() { - try=$1 - failedMethods=`egrep '<<< ERROR!$|<<< FAILURE!$' integration-tests/target/failsafe-reports/*txt | perl -pe 's,.*(com.vaadin[\.\w\d]+).*,$1,g' | sort -u` - failed=$(echo "$failedMethods" | perl -pe 's,.*(com\.vaadin[.\w\d]+)\.[\w\d]+,$1,g') - nfailed=`echo "$failed" | wc -w` - ### collect tests numbers for TC status - ncompleted=`grep 'Tests run: ' vaadin*/*flow/target/surefire-reports/*.txt integration-tests/target/failsafe-reports/*txt | awk '{SUM+=$3} END { print SUM }'` - nskipped=`grep 'Tests run: ' vaadin*/*flow/target/surefire-reports/*.txt integration-tests/target/failsafe-reports/*txt | awk '{SUM+=$9} END { print SUM }'` - if [ "$nfailed" -ge 1 ] - then - mkdir -p integration-tests/error-screenshots/$try - mv integration-tests/error-screenshots/*.png integration-tests/error-screenshots/$try - for i in $failed - do - cp integration-tests/target/failsafe-reports/$i.txt integration-tests/error-screenshots/$try - done - fi -} - -computeFastBuild() { - [ -z "$PR" ] && return 1 - ghUrl="https://api.github.com/repos/vaadin/flow-components/pulls/$PR" - prTitle=`curl -s $ghUrl | jq -r .title` - echo "$prTitle" | grep -v '\[skip ci\]' >/dev/null || return 0 - prMessages=`curl -s $ghUrl/commits | jq -r '.[] | .commit.message'` - echo "$prMessages" | grep -v '\[skip ci\]' >/dev/null || return 0 - return 1 -} - -## Set default build paramters -[ -z "$TESTS_IN_PARALLEL" ] && TESTS_IN_PARALLEL=1 -[ -z "$FORK_COUNT" ] && FORK_COUNT="5" -[ -z "$SELENIUM_IMAGE" ] && SELENIUM_IMAGE="latest" - -## Show info about environment -tcLog "Show info (forks=$FORK_COUNT parallel=$TESTS_IN_PARALLEL)" -echo $SHELL -type java && java -version -type mvn && mvn -version -type node 2>/dev/null && node --version -type npm 2>/dev/null && npm --version -type pnpm 2>/dev/null && pnpm --version -uname -a -[ -n "$elements" ] && echo "Run: $elements" || echo "Run all" - -## Compile all java files including tests in ITs modules -cmd="mvn clean test-compile -DskipFrontend $args" -tcLog "Compiling flow components - $cmd" -$cmd || tcStatus 1 "Compilation failed" - -## Notify TC that we are going to run maven tests -tcLog "Running report watcher for Tests " -tcMsg "importData type='surefire' path='**/*-reports/TEST*xml'"; - -## Compile and install all modules excluding ITs -cmd="mvn install -Drelease -T $FORK_COUNT $args" -tcLog "Unit-Testing and Installing flow components - $cmd" -if ! $cmd -then - ## Some times install fails because of maven multithread race condition - ## running a second time it is mitigated - tcLog "Unit-Testing and Installing flow components (2nd try) - $cmd" - sleep 15 - $cmd || tcStatus 1 "Unit-Testing failed" -fi - -## Skip IT's if developer passed [skip ci] labels in commit messages -tcLog "Checking for skip-ci labels" -if computeFastBuild -then - echo "$prTitle" - echo "$prMessages" - tcStatus 0 "" "Success - skip-ci" -fi - -## Install node modules used for merging ITs -cmd="npm install --silent --quiet --no-progress" -tcLog "Install NPM packages - $cmd" -$cmd || exit 1 - -## Create the integration-tests by coping all module ITs -cmd="node scripts/mergeITs.js "`echo $elements` -tcLog "Merge IT modules - $cmd" -$cmd || tcStatus 1 "Merging ITs failed" - -## Compute variable to run tests -[ -n "$TBLICENSE" ] && args="$args -Dvaadin.testbench.developer.license=$TBLICENSE" -[ -n "$TBHUB" ] && args="$args -Dtest.use.hub=true -Dcom.vaadin.testbench.Parameters.hubHostname=$TBHUB" -if [ -n "$SAUCE_USER" ] -then - test -n "$SAUCE_ACCESS_KEY" || { echo "\$SAUCE_ACCESS_KEY needs to be defined to use Saucelabs" >&2 ; exit 1; } - args="$args -P saucelabs -Dtest.use.hub=true -Dsauce.user=$SAUCE_USER -Dsauce.sauceAccessKey=$SAUCE_ACCESS_KEY" -fi - -args="$args -Dfailsafe.rerunFailingTestsCount=2 -Dmaven.test.redirectTestOutputToFile=true" - -## Install a selenium hub in local host to run tests against chrome -if [ "$TBHUB" = "localhost" ] -then - DOCKER_CONTAINER_NAME="selenium-container" - [ -n "$SELENIUM_DOCKER_IMAGE" ] || SELENIUM_DOCKER_IMAGE="selenium/standalone-chrome:$SELENIUM_IMAGE" - tcLog "Starting docker container using the $SELENIUM_DOCKER_IMAGE image" - set -x - trap "echo Terminating docker; docker stop $DOCKER_CONTAINER_NAME" EXIT - docker pull "$SELENIUM_DOCKER_IMAGE" || exit 1 - docker image prune -f || exit 1 - docker run --name "$DOCKER_CONTAINER_NAME" --net=host --rm -d -v /dev/shm:/dev/shm "$SELENIUM_DOCKER_IMAGE" || exit 1 - set +x -fi - -## Run web-test-runner tests -cmd="node scripts/wtr.js" -tcLog "Running web-test-runner tests - $cmd" -$cmd || exit 1 - -if [ -n "$modules" ] && [ -z "$USE_MERGED_MODULE" ] -then - ### Run IT's in original modules - cmd="mvn clean $verify -Dfailsafe.forkCount=$FORK_COUNT $args -pl $modules -DskipUnitTests" - tcLog "Running module ITs ($elements) - mvn clean $verify -pl ..." - echo $cmd - $cmd -else - mode="-Dfailsafe.forkCount=$FORK_COUNT -Dcom.vaadin.testbench.Parameters.testsInParallel=$TESTS_IN_PARALLEL" - ### Run IT's in merged module - cmd="mvn $verify -Drun-it -Drelease -Dvaadin.productionMode -Dfailsafe.rerunFailingTestsCount=2 $mode $args -pl integration-tests -DskipUnitTests" - tcLog "Running merged ITs - mvn $verify -B -Drun-it -Drelease -pl integration-tests ..." - echo $cmd - $cmd - error=$? - - [ ! -d integration-tests/target/failsafe-reports ] && exit 1 - saveFailedTests run-1 - - if [ "$nfailed" -gt 0 ] - then - ## Give a second try to failed tests - tcLog "There were $nfailed failed IT classes in first round. (error=$error)" - echo "$failedMethods" - - rerunFailed=$nfailed - if [ "$nfailed" -le 15 ] - then - failed=`echo "$failed" | tr '\n' ','` - mode="-Dfailsafe.forkCount=2 -Dcom.vaadin.testbench.Parameters.testsInParallel=3" - cmd="mvn $verify -Drun-it -Drelease -Dvaadin.productionMode -DskipFrontend $mode $args -pl integration-tests -DskipUnitTests -Dit.test=$failed" - tcLog "Re-Running $nfailed failed IT classes ..." - echo $cmd - $cmd - error=$? - saveFailedTests run-2 - - tcLog "There where $nfailed failed IT classes in second round. (error=$error)" - echo "$failedMethods" - - tcStatus $error "(IT2)Test failed: $nfailed" "(IT2)Tests passed: $ncompleted ($rerunFailed retried, $nfailed failed), ignored: $nskipped" - else - tcStatus $error "(IT1)Test failed: $nfailed" "(IT1)Tests passed: $ncompleted (more than 15 failed), ignored: $nskipped" - fi - fi - exit $error -fi diff --git a/scripts/wtr.js b/scripts/wtr.js index 122558cbb55..7a30a428238 100755 --- a/scripts/wtr.js +++ b/scripts/wtr.js @@ -53,7 +53,7 @@ function runTests() { }); // Install dependencies required to run the web-test-runner tests - execSync(`npm install @open-wc/testing @web/dev-server-esbuild @web/test-runner @web/test-runner-playwright @types/mocha sinon @vaadin/testing-helpers --save-dev --legacy-peer-deps`, { + execSync(`npm install --ignore-scripts @open-wc/testing @web/dev-server-esbuild @web/test-runner @web/test-runner-playwright @web/test-runner-junit-reporter @types/mocha sinon @vaadin/testing-helpers --save-dev --legacy-peer-deps`, { cwd: itFolder, stdio: 'inherit' }); @@ -64,12 +64,29 @@ function runTests() { stdio: 'inherit' }); + // Generate a CI config that adds the JUnit reporter on top of the existing config + const hasBaseConfig = fs.existsSync(`${itFolder}/web-test-runner.config.mjs`); + const ciConfigPath = `${itFolder}/wtr-ci.config.mjs`; + fs.writeFileSync(ciConfigPath, [ + `import { defaultReporter, summaryReporter } from '@web/test-runner';`, + `import { junitReporter } from '@web/test-runner-junit-reporter';`, + hasBaseConfig ? `import baseConfig from './web-test-runner.config.mjs';` : '', + `export default {`, + hasBaseConfig ? ` ...baseConfig,` : '', + ` reporters: [defaultReporter(), summaryReporter(), junitReporter({ outputPath: 'wtr-results.xml', reportLogs: true })],`, + `};`, + ].filter(Boolean).join('\n')); + // Run the tests console.log(`Running tests in ${itFolder}`); - execSync(`npx web-test-runner --playwright ${wtrTestsFolderName}/**/*.test.ts --node-resolve`, { - cwd: itFolder, - stdio: 'inherit' - }); + try { + execSync(`npx web-test-runner --playwright ${wtrTestsFolderName}/**/*.test.ts --node-resolve --config wtr-ci.config.mjs`, { + cwd: itFolder, + stdio: 'inherit' + }); + } finally { + fs.unlinkSync(ciConfigPath); + } } } } diff --git a/vaadin-charts-flow-parent/vaadin-charts-flow-integration-tests/src/test/java/com/vaadin/flow/component/charts/tests/AbstractChartIT.java b/vaadin-charts-flow-parent/vaadin-charts-flow-integration-tests/src/test/java/com/vaadin/flow/component/charts/tests/AbstractChartIT.java new file mode 100644 index 00000000000..2b6a5935470 --- /dev/null +++ b/vaadin-charts-flow-parent/vaadin-charts-flow-integration-tests/src/test/java/com/vaadin/flow/component/charts/tests/AbstractChartIT.java @@ -0,0 +1,43 @@ +/** + * Copyright 2000-2026 Vaadin Ltd. + * + * This program is available under Vaadin Commercial License and Service Terms. + * + * See {@literal } for the full + * license. + */ +package com.vaadin.flow.component.charts.tests; + +import com.vaadin.flow.component.charts.testbench.ChartElement; +import com.vaadin.testbench.ElementQuery; +import com.vaadin.testbench.TestBenchElement; +import com.vaadin.tests.AbstractComponentIT; + +public abstract class AbstractChartIT extends AbstractComponentIT { + + @Override + public void setup() throws Exception { + super.setup(); + open(); + } + + protected ChartElement getChartElement() { + return $(ChartElement.class).waitForFirst(); + } + + protected TestBenchElement getElementFromShadowRoot( + TestBenchElement shadowRootOwner, String selector) { + return shadowRootOwner.$(selector).first(); + } + + protected TestBenchElement getElementFromShadowRoot( + TestBenchElement shadowRootOwner, String selector, int index) { + ElementQuery elements = shadowRootOwner.$(selector); + if (elements.all().size() > index) { + return elements.get(index); + } + + throw new AssertionError( + "Could not find required element in the shadowRoot"); + } +} diff --git a/vaadin-charts-flow-parent/vaadin-charts-flow-svg-generator/pom.xml b/vaadin-charts-flow-parent/vaadin-charts-flow-svg-generator/pom.xml index 0ce9c21ce96..6dc6e4f9974 100644 --- a/vaadin-charts-flow-parent/vaadin-charts-flow-svg-generator/pom.xml +++ b/vaadin-charts-flow-parent/vaadin-charts-flow-svg-generator/pom.xml @@ -56,6 +56,7 @@ install + ${skipSvgChartsBuild} @@ -70,6 +71,7 @@ run build + ${skipSvgChartsBuild} @@ -83,7 +85,7 @@ test - ${skipTests} + ${skipSvgChartsBuild} diff --git a/vaadin-flow-components-shared-parent/vaadin-flow-components-test-util/src/main/java/com/vaadin/tests/AbstractComponentIT.java b/vaadin-flow-components-shared-parent/vaadin-flow-components-test-util/src/main/java/com/vaadin/tests/AbstractComponentIT.java index 8d794ea2ce7..d0b94b25dd2 100644 --- a/vaadin-flow-components-shared-parent/vaadin-flow-components-test-util/src/main/java/com/vaadin/tests/AbstractComponentIT.java +++ b/vaadin-flow-components-shared-parent/vaadin-flow-components-test-util/src/main/java/com/vaadin/tests/AbstractComponentIT.java @@ -15,6 +15,8 @@ */ package com.vaadin.tests; +import org.openqa.selenium.chrome.ChromeOptions; + public abstract class AbstractComponentIT extends com.vaadin.flow.testutil.AbstractComponentIT { @@ -22,10 +24,22 @@ protected int getDeploymentPort() { return 8080; } + @Override + protected void updateHeadlessChromeOptions(ChromeOptions chromeOptions) { + String extraArgs = System.getenv("TESTBENCH_CHROME_EXTRA_ARGS"); + if (extraArgs != null && !extraArgs.isBlank()) { + chromeOptions.addArguments(extraArgs.split("\\s+")); + } + + String chromeBinary = System.getenv("TESTBENCH_CHROME_BINARY"); + if (chromeBinary != null && !chromeBinary.isBlank()) { + chromeOptions.setBinary(chromeBinary); + } + } + @Override public void setup() throws Exception { super.setup(); - // Set a default window size testBench().resizeViewPortTo(1024, 800); }