From 75f412ffde8a207fa6a26a41de0380b4c58bd204 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 16 Jul 2026 03:48:03 +0300 Subject: [PATCH 01/21] Add automated port conformance status page --- .github/workflows/linux-build-run.yml | 14 +- .github/workflows/port-status-contract.yml | 54 ++ .github/workflows/port-status-publish.yml | 50 ++ .github/workflows/scripts-android.yml | 8 + .github/workflows/scripts-ios.yml | 38 ++ .github/workflows/scripts-javascript.yml | 9 + .github/workflows/scripts-mac-native.yml | 9 + .github/workflows/windows-cross-build-run.yml | 14 +- .../assets/css/extended/cn1-port-status.css | 278 ++++++++++ docs/website/assets/js/cn1-port-status.js | 183 +++++++ docs/website/content/port-status.md | 8 + docs/website/data/port_status.json | 510 ++++++++++++++++++ docs/website/hugo.toml | 10 +- .../website/layouts/_default/port-status.html | 118 ++++ docs/website/layouts/partials/footer.html | 4 + scripts/hellocodenameone/README.adoc | 36 +- .../conformance/port_status.py | 344 ++++++++++++ .../conformance/publish_port_status.sh | 59 ++ .../conformance/test_port_status.py | 65 +++ scripts/lib/cn1ss.sh | 57 ++ scripts/run-android-instrumentation-tests.sh | 2 + scripts/run-ios-ui-tests.sh | 3 + scripts/run-javascript-screenshot-tests.sh | 2 + scripts/run-mac-native-ui-tests.sh | 4 + scripts/run-tv-ui-tests.sh | 2 + scripts/run-watch-ui-tests.sh | 2 + scripts/website/build.sh | 2 + scripts/website/preview.sh | 2 + 28 files changed, 1882 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/port-status-contract.yml create mode 100644 .github/workflows/port-status-publish.yml create mode 100644 docs/website/assets/css/extended/cn1-port-status.css create mode 100644 docs/website/assets/js/cn1-port-status.js create mode 100644 docs/website/content/port-status.md create mode 100644 docs/website/data/port_status.json create mode 100644 docs/website/layouts/_default/port-status.html create mode 100755 scripts/hellocodenameone/conformance/port_status.py create mode 100755 scripts/hellocodenameone/conformance/publish_port_status.sh create mode 100755 scripts/hellocodenameone/conformance/test_port_status.py diff --git a/.github/workflows/linux-build-run.yml b/.github/workflows/linux-build-run.yml index 6aa66ae4b3a..9f2b7e6e92b 100644 --- a/.github/workflows/linux-build-run.yml +++ b/.github/workflows/linux-build-run.yml @@ -355,7 +355,7 @@ jobs: compare-comment: name: screenshot-comment needs: build-run - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' || github.event_name == 'push' runs-on: ubuntu-latest permissions: contents: read @@ -397,6 +397,7 @@ jobs: # screenshot that has no committed golden (missing_expected). export CN1SS_FAIL_ON_MISMATCH=1 export CN1SS_ALLOWED_MISSING=0 + if [ "${{ github.event_name }}" != "pull_request" ]; then export CN1SS_SKIP_COMMENT=1; fi for arch in x64 arm64; do raw="$ART/raw-$arch" [ -d "$raw" ] || continue @@ -409,6 +410,8 @@ jobs: if [ "$arch" = "arm64" ]; then REF="scripts/linux/screenshots-arm"; else REF="scripts/linux/screenshots"; fi echo "Posting ${#entries[@]} screenshot(s) for $arch (baseline $REF)" mkdir -p "$ART/previews-$arch" + export CN1SS_PORT_ID="linux-$arch" + export CN1SS_SUITE_LOG="$raw/app-output.log" set +e CN1SS_COMMENT_MARKER="" \ CN1SS_COMMENT_LOG_PREFIX="[linux-gtk-$arch]" \ @@ -434,3 +437,12 @@ jobs: done if [ "$posted" -eq 0 ]; then echo "No screenshots produced; skipping comment."; fi if [ "$fail" -ne 0 ]; then echo "Linux screenshot gate failed."; exit 1; fi + + - name: Upload Linux port status + if: always() + uses: actions/upload-artifact@v4 + with: + name: port-status-linux + path: artifacts/linux-port/port-status-linux-*.json + if-no-files-found: warn + retention-days: 14 diff --git a/.github/workflows/port-status-contract.yml b/.github/workflows/port-status-contract.yml new file mode 100644 index 00000000000..0d588989d76 --- /dev/null +++ b/.github/workflows/port-status-contract.yml @@ -0,0 +1,54 @@ +name: Validate port status contract + +on: + pull_request: + paths: + - '.github/workflows/port-status-contract.yml' + - 'docs/website/data/port_status.json' + - 'scripts/hellocodenameone/common/src/main/**' + - 'scripts/hellocodenameone/conformance/**' + - 'scripts/android/screenshots/**' + - 'scripts/ios/screenshots/**' + - 'scripts/ios/screenshots-metal/**' + - 'scripts/ios/screenshots-watch/**' + - 'scripts/ios/screenshots-tv/**' + - 'scripts/mac-native/screenshots/**' + - 'scripts/javascript/screenshots/**' + - 'scripts/linux/screenshots/**' + - 'scripts/linux/screenshots-arm/**' + - 'scripts/windows/screenshots/**' + push: + branches: [master] + paths: + - '.github/workflows/port-status-contract.yml' + - 'docs/website/data/port_status.json' + - 'scripts/hellocodenameone/common/src/main/**' + - 'scripts/hellocodenameone/conformance/**' + - 'scripts/android/screenshots/**' + - 'scripts/ios/screenshots/**' + - 'scripts/ios/screenshots-metal/**' + - 'scripts/ios/screenshots-watch/**' + - 'scripts/ios/screenshots-tv/**' + - 'scripts/mac-native/screenshots/**' + - 'scripts/javascript/screenshots/**' + - 'scripts/linux/screenshots/**' + - 'scripts/linux/screenshots-arm/**' + - 'scripts/windows/screenshots/**' + workflow_dispatch: + +permissions: + contents: read + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: '3.13' + - name: Validate every test and golden mapping + run: python3 scripts/hellocodenameone/conformance/port_status.py validate + - name: Run normalizer tests + working-directory: scripts/hellocodenameone/conformance + run: python3 -m unittest -v test_port_status.py diff --git a/.github/workflows/port-status-publish.yml b/.github/workflows/port-status-publish.yml new file mode 100644 index 00000000000..3b83605d9f4 --- /dev/null +++ b/.github/workflows/port-status-publish.yml @@ -0,0 +1,50 @@ +name: Publish port status reports + +on: + workflow_run: + workflows: + - Test Android build scripts + - Test iOS UI build scripts + - Test Mac native UI build scripts + - Test JavaScript screenshot scripts + - Linux native build + run (GTK3, x64 + arm64) + - Windows cross-build + run (Linux build -> Windows run) + types: [completed] + +permissions: + actions: read + contents: write + +jobs: + publish: + if: github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'master' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + ref: master + + - name: Download normalized reports + uses: actions/download-artifact@v4 + with: + github-token: ${{ github.token }} + run-id: ${{ github.event.workflow_run.id }} + pattern: port-status-* + path: reports + merge-multiple: true + + - name: Publish reports to the data branch + env: + GH_TOKEN: ${{ github.token }} + PORT_STATUS_PUBLISH: '1' + run: | + set -euo pipefail + found=0 + while IFS= read -r report; do + found=1 + ./scripts/hellocodenameone/conformance/publish_port_status.sh "$report" + done < <(find reports -type f -name 'port-status-*.json' | sort) + if [ "$found" -eq 0 ]; then + echo "No normalized port reports were found in workflow artifacts." >&2 + exit 1 + fi diff --git a/.github/workflows/scripts-android.yml b/.github/workflows/scripts-android.yml index 804154dad5f..f617e4bd1c1 100644 --- a/.github/workflows/scripts-android.yml +++ b/.github/workflows/scripts-android.yml @@ -196,6 +196,14 @@ jobs: target: google_apis disk-size: 2048M script: ./scripts/run-android-instrumentation-tests.sh "${{ steps.build-android-app.outputs.gradle_project_dir }}" + - name: Upload Android port status + if: always() && matrix.id == 'default' + uses: actions/upload-artifact@v7 + with: + name: port-status-android + path: artifacts/port-status-android.json + if-no-files-found: warn + retention-days: 14 - name: Upload emulator screenshot if: always() && matrix.id == 'default' uses: actions/upload-artifact@v7 diff --git a/.github/workflows/scripts-ios.yml b/.github/workflows/scripts-ios.yml index d2cb9ed67ff..3b4afb0ddb0 100644 --- a/.github/workflows/scripts-ios.yml +++ b/.github/workflows/scripts-ios.yml @@ -234,6 +234,7 @@ jobs: # failures are scanned from CN1SS:ERR:suite lines by # run-ios-ui-tests.sh and are never allowed by this value. CN1SS_ALLOWED_MISSING: '2' + CN1SS_PORT_ID: ios-gl run: | set -euo pipefail mkdir -p "${ARTIFACTS_DIR}" @@ -251,6 +252,15 @@ jobs: # same envelope so it stays symmetric. timeout-minutes: 45 + - name: Upload iOS OpenGL port status + if: always() + uses: actions/upload-artifact@v7 + with: + name: port-status-ios-gl + path: artifacts/ios-ui-tests/port-status-ios-gl.json + if-no-files-found: warn + retention-days: 14 + - name: Upload iOS artifacts if: always() uses: actions/upload-artifact@v7 @@ -466,6 +476,7 @@ jobs: # to the launched app via simctl --setenv. MTL_DEBUG_LAYER: '1' MTL_DEBUG_LAYER_ERROR_MODE: 'assert' + CN1SS_PORT_ID: ios-metal run: | set -euo pipefail mkdir -p "${ARTIFACTS_DIR}" @@ -483,6 +494,15 @@ jobs: # screenshot suite. timeout-minutes: 45 + - name: Upload iOS Metal port status + if: always() + uses: actions/upload-artifact@v7 + with: + name: port-status-ios-metal + path: artifacts/ios-ui-tests-metal/port-status-ios-metal.json + if-no-files-found: warn + retention-days: 14 + - name: Publish Metal screenshot summary # Surfaces run-ios-ui-tests.sh's comparison result in the job's # GitHub Actions summary page so the Metal port status is visible @@ -672,6 +692,15 @@ jobs: "${{ steps.build-ios-app.outputs.scheme }}" timeout-minutes: 45 + - name: Upload watchOS port status + if: always() + uses: actions/upload-artifact@v7 + with: + name: port-status-watchos + path: artifacts/watch-ui-tests/port-status-watchos.json + if-no-files-found: warn + retention-days: 14 + - name: Upload watch artifacts if: always() uses: actions/upload-artifact@v7 @@ -825,6 +854,15 @@ jobs: "${{ steps.build-ios-app.outputs.scheme }}" timeout-minutes: 45 + - name: Upload tvOS port status + if: always() + uses: actions/upload-artifact@v7 + with: + name: port-status-tvos + path: artifacts/tv-ui-tests/port-status-tvos.json + if-no-files-found: warn + retention-days: 14 + - name: Upload tv artifacts if: always() uses: actions/upload-artifact@v7 diff --git a/.github/workflows/scripts-javascript.yml b/.github/workflows/scripts-javascript.yml index a7156e0ae83..33a64131891 100644 --- a/.github/workflows/scripts-javascript.yml +++ b/.github/workflows/scripts-javascript.yml @@ -218,6 +218,15 @@ jobs: mkdir -p "${ARTIFACTS_DIR}" ./scripts/run-javascript-browser-tests.sh "${{ steps.locate_bundle.outputs.bundle }}" "${GITHUB_WORKSPACE}/scripts/javascript/screenshots" + - name: Upload JavaScript port status + if: always() + uses: actions/upload-artifact@v7 + with: + name: port-status-javascript + path: artifacts/javascript-ui-tests/port-status-javascript.json + if-no-files-found: warn + retention-days: 14 + - name: Upload JavaScript screenshot artifacts if: always() uses: actions/upload-artifact@v7 diff --git a/.github/workflows/scripts-mac-native.yml b/.github/workflows/scripts-mac-native.yml index ee8e68222e5..942edbc530a 100644 --- a/.github/workflows/scripts-mac-native.yml +++ b/.github/workflows/scripts-mac-native.yml @@ -232,6 +232,15 @@ jobs: # 45m lets the script's internal timeout govern gracefully instead. timeout-minutes: 45 + - name: Upload Mac native port status + if: always() + uses: actions/upload-artifact@v7 + with: + name: port-status-mac-native + path: artifacts/mac-native-ui-tests/port-status-mac-native.json + if-no-files-found: warn + retention-days: 14 + - name: Publish Mac native screenshot summary # Surfaces run-mac-native-ui-tests.sh's comparison result in the # job's GitHub Actions summary page so the Mac slice status is diff --git a/.github/workflows/windows-cross-build-run.yml b/.github/workflows/windows-cross-build-run.yml index 199aeec42af..aa5f2670187 100644 --- a/.github/workflows/windows-cross-build-run.yml +++ b/.github/workflows/windows-cross-build-run.yml @@ -261,7 +261,7 @@ jobs: compare-comment: name: cross-compiled screenshot-comment needs: run-on-windows - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' || github.event_name == 'push' runs-on: ubuntu-latest permissions: contents: read @@ -326,6 +326,9 @@ jobs: # through green CI. export CN1SS_FAIL_ON_MISMATCH=1 export CN1SS_ALLOWED_MISSING=0 + export CN1SS_PORT_ID=windows-x64 + export CN1SS_SUITE_LOG="$ART/raw-x64/app-output.log" + if [ "${{ github.event_name }}" != "pull_request" ]; then export CN1SS_SKIP_COMMENT=1; fi set +e cn1ss_process_and_report \ "Native Windows port (cross-compiled)" \ @@ -343,3 +346,12 @@ jobs: echo "[windows-cross] FATAL: $me screenshot(s) streamed with no stored golden (missing_expected) -- add them to $REF_DIR."; fail=1 fi if [ "$fail" -ne 0 ]; then echo "Windows cross screenshot gate failed."; exit 1; fi + + - name: Upload Windows port status + if: always() + uses: actions/upload-artifact@v4 + with: + name: port-status-windows-x64 + path: artifacts/windows-port/port-status-windows-x64.json + if-no-files-found: warn + retention-days: 14 diff --git a/docs/website/assets/css/extended/cn1-port-status.css b/docs/website/assets/css/extended/cn1-port-status.css new file mode 100644 index 00000000000..ce228f6b4fc --- /dev/null +++ b/docs/website/assets/css/extended/cn1-port-status.css @@ -0,0 +1,278 @@ +.cn1-port-status { + --cn1-status-border: color-mix(in srgb, var(--primary) 16%, transparent); + max-width: 1500px; +} + +.cn1-port-status .screen-reader-text { + clip: rect(0 0 0 0); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + position: absolute; + white-space: nowrap; + width: 1px; +} + +.cn1-port-status__header { + max-width: 900px; +} + +.cn1-port-status__eyebrow, +.cn1-port-status__category { + color: #e7652a; + font-size: .72rem; + font-weight: 700; + letter-spacing: .08em; + text-transform: uppercase; +} + +.cn1-port-status__intro { + color: var(--secondary); + font-size: 1.08rem; + line-height: 1.7; + margin-top: 1rem; + max-width: 800px; +} + +.cn1-port-status__facts, +.cn1-port-status__legend { + display: flex; + flex-wrap: wrap; + gap: .75rem 1.25rem; + margin-top: 1.25rem; +} + +.cn1-port-status__facts span { + background: var(--entry); + border: 1px solid var(--cn1-status-border); + border-radius: 999px; + padding: .45rem .8rem; +} + +.cn1-port-status__notice { + background: color-mix(in srgb, #27955b 12%, var(--entry)); + border: 1px solid color-mix(in srgb, #27955b 45%, transparent); + border-radius: 12px; + margin: 1.5rem 0 0; + padding: .8rem 1rem; +} + +.cn1-port-status__notice.is-error { + background: color-mix(in srgb, #c38a20 12%, var(--entry)); + border-color: color-mix(in srgb, #c38a20 45%, transparent); +} + +.cn1-port-status__legend { + color: var(--secondary); + font-size: .86rem; + margin-bottom: 1.25rem; +} + +.cn1-port-status__legend span { + align-items: center; + display: inline-flex; + gap: .4rem; +} + +.cn1-port-status__mark { + align-items: center; + border: 2px solid currentColor; + border-radius: 5px; + display: inline-flex; + font-size: .83rem; + font-style: normal; + font-weight: 800; + height: 1.35rem; + justify-content: center; + line-height: 1; + width: 1.35rem; +} + +.cn1-port-status__mark.is-pass { color: #27955b; } +.cn1-port-status__mark.is-fail { color: #d24c4c; } +.cn1-port-status__mark.is-partial, +.cn1-port-status__mark.is-stale { color: #c38a20; } +.cn1-port-status__mark.is-unknown { color: #7d8791; } + +.cn1-port-status__ports { + display: grid; + gap: .75rem; + grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); + margin: 1.25rem 0 1.75rem; +} + +.cn1-port-card { + background: var(--entry); + border: 1px solid var(--cn1-status-border); + border-left: 4px solid #7d8791; + border-radius: 12px; + display: flex; + flex-direction: column; + min-height: 150px; + padding: 1rem; +} + +.cn1-port-card.is-pass { border-left-color: #27955b; } +.cn1-port-card.is-fail { border-left-color: #d24c4c; } +.cn1-port-card.is-partial { border-left-color: #c38a20; } + +.cn1-port-card h2 { + font-size: 1rem; + margin: 0; +} + +.cn1-port-card p { + color: var(--secondary); + font-size: .78rem; + line-height: 1.45; + margin: .25rem 0 0; +} + +.cn1-port-card .cn1-port-card__state { + color: var(--primary); + font-size: .86rem; + font-weight: 700; + margin-top: auto; + padding-top: .8rem; +} + +.cn1-port-status__toolbar { + align-items: end; + display: grid; + gap: .75rem; + grid-template-columns: minmax(180px, .45fr) minmax(240px, 1fr); + margin-bottom: 1rem; +} + +.cn1-port-status__toolbar label span { + display: block; + font-size: .78rem; + font-weight: 700; + margin-bottom: .3rem; +} + +.cn1-port-status__toolbar input, +.cn1-port-status__toolbar select { + background: var(--entry); + border: 1px solid var(--cn1-status-border); + border-radius: 9px; + color: var(--primary); + font: inherit; + padding: .65rem .75rem; + width: 100%; +} + +.cn1-port-status__matrix { + border: 1px solid var(--cn1-status-border); + border-radius: 12px; + overflow: auto; +} + +.cn1-port-status__matrix table { + border-collapse: separate; + border-spacing: 0; + font-size: .85rem; + margin: 0; + min-width: 1220px; + width: 100%; +} + +.cn1-port-status__matrix th, +.cn1-port-status__matrix td { + border-bottom: 1px solid var(--cn1-status-border); + border-right: 1px solid var(--cn1-status-border); + padding: .7rem; +} + +.cn1-port-status__matrix thead th { + background: var(--entry); + font-size: .72rem; + position: sticky; + text-align: center; + top: 0; + z-index: 2; +} + +.cn1-port-status__matrix thead th:first-child, +.cn1-port-status__matrix tbody th { + left: 0; + position: sticky; + text-align: left; + width: 330px; + z-index: 1; +} + +.cn1-port-status__matrix thead th:first-child { + z-index: 3; +} + +.cn1-port-status__matrix tbody th { + background: var(--theme); + font-weight: 400; +} + +.cn1-port-status__matrix tbody th strong { + display: block; + font-size: .9rem; + margin-top: .15rem; +} + +.cn1-port-status__matrix tbody th p { + color: var(--secondary); + font-size: .76rem; + line-height: 1.45; + margin: .25rem 0; +} + +.cn1-port-status__matrix details { + color: var(--secondary); + font-size: .72rem; +} + +.cn1-port-status__matrix details ul { + margin: .4rem 0 0; + max-height: 180px; + overflow: auto; + padding-left: 1.1rem; +} + +.cn1-port-status__matrix td { + min-width: 82px; + text-align: center; +} + +.cn1-port-status__matrix td.is-pass { background: color-mix(in srgb, #27955b 8%, transparent); } +.cn1-port-status__matrix td.is-fail { background: color-mix(in srgb, #d24c4c 9%, transparent); } +.cn1-port-status__matrix td.is-partial, +.cn1-port-status__matrix td.is-stale { background: color-mix(in srgb, #c38a20 9%, transparent); } + +.cn1-port-status__method { + background: var(--entry); + border: 1px solid var(--cn1-status-border); + border-radius: 12px; + margin-top: 1.5rem; + padding: 1.25rem; +} + +.cn1-port-status__method h2 { + font-size: 1.1rem; + margin: 0 0 .6rem; +} + +.cn1-port-status__method p { + color: var(--secondary); + font-size: .86rem; + line-height: 1.65; + margin: .5rem 0; +} + +@media (max-width: 720px) { + .cn1-port-status__toolbar { + grid-template-columns: 1fr; + } + + .cn1-port-status__matrix thead th:first-child, + .cn1-port-status__matrix tbody th { + width: 260px; + } +} diff --git a/docs/website/assets/js/cn1-port-status.js b/docs/website/assets/js/cn1-port-status.js new file mode 100644 index 00000000000..0d295457659 --- /dev/null +++ b/docs/website/assets/js/cn1-port-status.js @@ -0,0 +1,183 @@ +(function () { + "use strict"; + + var root = document.querySelector("[data-port-status]"); + if (!root) { + return; + } + + var contractElement = root.querySelector("[data-port-status-contract]"); + var notice = root.querySelector("[data-port-status-notice]"); + var contract; + try { + contract = JSON.parse(contractElement.textContent); + } catch (error) { + notice.textContent = "The port-status contract could not be loaded."; + notice.classList.add("is-error"); + return; + } + + var reports = {}; + var reportBase = "https://raw.githubusercontent.com/codenameone/CodenameOne/" + + contract.report_branch + "/ports/"; + + function daysOld(value) { + var timestamp = Date.parse(value || ""); + if (Number.isNaN(timestamp)) { + return Infinity; + } + return (Date.now() - timestamp) / 86400000; + } + + function featureStatus(feature, report) { + if (!report) { + return {state: "unknown", label: "No current report", tests: []}; + } + var stale = daysOld(report.generated_at) > contract.stale_after_days; + var results = feature.tests.map(function (name) { + var result = report.tests && report.tests[name]; + return {name: name, status: result ? result.status : "not-run"}; + }); + var failed = results.filter(function (item) { return item.status === "fail"; }); + var passed = results.filter(function (item) { return item.status === "pass"; }); + var skipped = results.filter(function (item) { return item.status === "skip"; }); + var notRun = results.filter(function (item) { return item.status === "not-run"; }); + var state; + var label; + + if (failed.length) { + state = "fail"; + label = failed.length + " failed: " + failed.map(function (item) { return item.name; }).join(", "); + } else if (!report.suite_finished) { + state = "partial"; + label = "Suite did not finish"; + } else if (passed.length === results.length) { + state = "pass"; + label = "All " + results.length + " mapped test" + (results.length === 1 ? "" : "s") + " passed"; + } else if (skipped.length === results.length) { + state = "partial"; + label = "All mapped tests skipped"; + } else { + state = "partial"; + label = passed.length + " passed, " + skipped.length + " skipped, " + notRun.length + " not run"; + } + if (stale) { + state = state === "fail" ? "fail" : "stale"; + label = "Stale report. " + label; + } + return {state: state, label: label, tests: results}; + } + + function markFor(state) { + if (state === "pass") { return "✓"; } + if (state === "fail") { return "×"; } + if (state === "partial") { return "−"; } + if (state === "stale") { return "!"; } + return "?"; + } + + function updateCell(cell, status) { + cell.className = "is-" + status.state; + cell.title = status.label; + var mark = cell.querySelector(".cn1-port-status__mark"); + mark.className = "cn1-port-status__mark is-" + status.state; + mark.textContent = markFor(status.state); + cell.querySelector("[data-status-label]").textContent = status.label; + } + + function formatDate(value) { + var date = new Date(value); + if (Number.isNaN(date.getTime())) { + return "Unknown run time"; + } + return date.toLocaleString(undefined, {dateStyle: "medium", timeStyle: "short"}); + } + + function updatePort(port, report) { + var card = root.querySelector('[data-port-card="' + port.id + '"]'); + var state = card.querySelector("[data-port-state]"); + var meta = card.querySelector("[data-port-meta]"); + if (!report) { + state.textContent = port.report_pending ? "Detailed reporting pending" : "No published report"; + card.classList.add("is-unknown"); + return; + } + var summary = report.summary || {}; + var stale = daysOld(report.generated_at) > contract.stale_after_days; + var failed = summary.fail || 0; + var unfinished = !report.suite_finished; + card.classList.add(failed ? "is-fail" : (stale || unfinished ? "is-partial" : "is-pass")); + state.textContent = failed ? failed + " failing tests" : (unfinished ? "Run incomplete" : (stale ? "Report is stale" : "Suite completed")); + var detail = (summary.pass || 0) + " passed · " + (summary.skip || 0) + " skipped · " + (summary["not-run"] || 0) + " not run"; + meta.replaceChildren(document.createTextNode(formatDate(report.generated_at)), document.createElement("br"), document.createTextNode(detail)); + if (report.run_url) { + var separator = document.createTextNode(" · "); + var link = document.createElement("a"); + link.href = report.run_url; + link.target = "_blank"; + link.rel = "noopener"; + link.textContent = "Open run"; + meta.append(separator, link); + } + } + + function render() { + contract.features.forEach(function (feature) { + contract.ports.forEach(function (port) { + var cell = root.querySelector('[data-feature-cell][data-port="' + port.id + '"][data-feature="' + feature.id + '"]'); + updateCell(cell, featureStatus(feature, reports[port.id])); + }); + }); + contract.ports.forEach(function (port) { + updatePort(port, reports[port.id]); + }); + } + + function loadPort(port) { + if (port.report_pending) { + return Promise.resolve(); + } + return fetch(reportBase + encodeURIComponent(port.id) + ".json", {cache: "no-store"}) + .then(function (response) { + if (!response.ok) { + throw new Error("HTTP " + response.status); + } + return response.json(); + }) + .then(function (report) { + if (report.port !== port.id || report.schema_version !== contract.schema_version) { + throw new Error("Report contract mismatch"); + } + reports[port.id] = report; + }) + .catch(function () { + reports[port.id] = null; + }); + } + + function installFilters() { + var category = root.querySelector("[data-category-filter]"); + var search = root.querySelector("[data-feature-search]"); + function apply() { + var categoryValue = category.value; + var query = search.value.trim().toLowerCase(); + root.querySelectorAll("[data-feature-row]").forEach(function (row) { + var categoryMatches = !categoryValue || row.dataset.category === categoryValue; + var searchMatches = !query || row.dataset.search.indexOf(query) !== -1; + row.hidden = !(categoryMatches && searchMatches); + }); + } + category.addEventListener("change", apply); + search.addEventListener("input", apply); + } + + installFilters(); + Promise.all(contract.ports.map(loadPort)).then(function () { + render(); + var loaded = Object.keys(reports).filter(function (id) { return reports[id]; }).length; + notice.textContent = loaded + ? "Showing the latest published reports for " + loaded + " port target" + (loaded === 1 ? "" : "s") + "." + : "No detailed port reports have been published yet. The contract is ready; CI will populate this page after the next master runs."; + notice.classList.toggle("is-error", loaded === 0); + }); +}()); diff --git a/docs/website/content/port-status.md b/docs/website/content/port-status.md new file mode 100644 index 00000000000..78236d9818a --- /dev/null +++ b/docs/website/content/port-status.md @@ -0,0 +1,8 @@ +--- +title: "Port Status" +slug: "port-status" +url: "/port-status/" +layout: "port-status" +description: "Current Codename One port conformance, generated from the HelloCodenameOne test suite." +hideMeta: true +--- diff --git a/docs/website/data/port_status.json b/docs/website/data/port_status.json new file mode 100644 index 00000000000..f434ea1d5a8 --- /dev/null +++ b/docs/website/data/port_status.json @@ -0,0 +1,510 @@ +{ + "schema_version": 1, + "report_branch": "port-status-data", + "stale_after_days": 14, + "golden_directories": [ + "scripts/android/screenshots", + "scripts/ios/screenshots", + "scripts/ios/screenshots-metal", + "scripts/ios/screenshots-watch", + "scripts/ios/screenshots-tv", + "scripts/mac-native/screenshots", + "scripts/javascript/screenshots", + "scripts/linux/screenshots", + "scripts/linux/screenshots-arm", + "scripts/windows/screenshots" + ], + "ports": [ + {"id": "android", "name": "Android", "detail": "Android emulator, API 36", "workflow": "scripts-android.yml"}, + {"id": "ios-gl", "name": "iOS (OpenGL)", "detail": "iOS Simulator, legacy renderer", "workflow": "scripts-ios.yml"}, + {"id": "ios-metal", "name": "iOS (Metal)", "detail": "iOS Simulator, Metal renderer", "workflow": "scripts-ios.yml"}, + {"id": "mac-native", "name": "macOS native", "detail": "Mac Catalyst native build", "workflow": "scripts-mac-native.yml"}, + {"id": "javascript", "name": "Web", "detail": "JavaScript port in a headless browser", "workflow": "scripts-javascript.yml"}, + {"id": "linux-x64", "name": "Linux x64", "detail": "Native GTK3/Cairo build", "workflow": "linux-build-run.yml"}, + {"id": "linux-arm64", "name": "Linux ARM64", "detail": "Native GTK3/Cairo build", "workflow": "linux-build-run.yml"}, + {"id": "windows-x64", "name": "Windows x64", "detail": "Native cross-compiled binary on Windows", "workflow": "windows-cross-build-run.yml"}, + {"id": "watchos", "name": "watchOS", "detail": "Apple Watch Simulator", "workflow": "scripts-ios.yml"}, + {"id": "tvos", "name": "tvOS", "detail": "Apple TV Simulator", "workflow": "scripts-ios.yml"} + ], + "features": [ + { + "id": "application-bootstrap", + "category": "Application runtime", + "name": "Application bootstrap and Java/Kotlin UI", + "description": "Starts the application and renders the shared Java and Kotlin UI paths.", + "tests": ["KotlinUiTest", "MainScreenScreenshotTest"] + }, + { + "id": "ads", + "category": "Application runtime", + "name": "Advertising components", + "description": "Renders banner and native-ad content through the advertising API.", + "tests": ["AdsScreenshotTest"] + }, + { + "id": "slide-cover-transitions", + "category": "Animation and navigation", + "name": "Slide and cover transitions", + "description": "Exercises horizontal, vertical, back, title, cover, and uncover transition frames.", + "tests": ["CoverHorizontalTransitionTest", "SlideFadeTitleTransitionTest", "SlideHorizontalBackTransitionTest", "SlideHorizontalTransitionTest", "SlideVerticalTransitionTest", "UncoverHorizontalTransitionTest"] + }, + { + "id": "fade-flip-transitions", + "category": "Animation and navigation", + "name": "Fade and flip transitions", + "description": "Exercises deterministic fade and flip transition frames.", + "tests": ["FadeTransitionTest", "FlipTransitionTest"] + }, + { + "id": "morph-transitions", + "category": "Animation and navigation", + "name": "Morph transitions", + "description": "Covers element morphing, scrolled sources, snapshots, and scrubbed morph timelines.", + "tests": ["MorphElementMorphScreenshotTest", "MorphTransitionScrolledSourceTest", "MorphTransitionScrubScreenshotTest", "MorphTransitionSnapshotTest", "MorphTransitionTest"] + }, + { + "id": "layout-animation", + "category": "Animation and navigation", + "name": "Animated layout changes", + "description": "Checks layout, hierarchy, unlayout, replacement, and motion animation paths.", + "tests": ["AnimateHierarchyScreenshotTest", "AnimateLayoutScreenshotTest", "AnimateUnlayoutScreenshotTest", "ComponentReplaceFadeScreenshotTest", "ComponentReplaceFlipScreenshotTest", "ComponentReplaceSlideScreenshotTest", "MotionShowcaseScreenshotTest"] + }, + { + "id": "scrolling-and-pull", + "category": "Animation and navigation", + "name": "Scrolling, sticky headers, and pull gestures", + "description": "Checks smooth scrolling, sticky-header transitions, pull-to-refresh, and tensile scrolling.", + "tests": ["PullToRefreshSpinnerScreenshotTest", "SmoothScrollScreenshotTest", "StickyHeaderFadeTransitionScreenshotTest", "StickyHeaderScreenshotTest", "StickyHeaderSlideTransitionScreenshotTest", "TensileBounceScreenshotTest"] + }, + { + "id": "tabs-animation", + "category": "Animation and navigation", + "name": "Animated tab indicators", + "description": "Checks tab indicator animation independently of static tab layout.", + "tests": ["TabsAnimatedIndicatorScreenshotTest"] + }, + { + "id": "status-bar-events", + "category": "Input and lifecycle", + "name": "Status-bar tap events", + "description": "Verifies delivery and visual handling of platform status-bar tap events.", + "tests": ["StatusBarTapDiagnosticScreenshotTest"] + }, + { + "id": "graphics-primitives", + "category": "2D graphics", + "name": "Lines, rectangles, arcs, and polygons", + "description": "Draws and fills the core 2D graphics primitives.", + "tests": ["DrawArc", "DrawLine", "DrawRect", "DrawRoundRect", "FillArc", "FillPolygon", "FillRect", "FillRoundRect", "FillTriangle"] + }, + { + "id": "graphics-text-images", + "category": "2D graphics", + "name": "Text and image drawing", + "description": "Checks text decoration, glyph rendering, image rectangles, and tiled images.", + "tests": ["DrawImage", "DrawString", "DrawStringDecorated", "TileImage"] + }, + { + "id": "graphics-gradients-filters", + "category": "2D graphics", + "name": "Gradients and blur filters", + "description": "Checks basic and multi-stop gradients plus Gaussian blur.", + "tests": ["DrawGradient", "DrawGradientStops", "GaussianBlur"] + }, + { + "id": "graphics-shapes-strokes", + "category": "2D graphics", + "name": "Shapes and strokes", + "description": "Checks paths, filled shapes, complex grids, and stroke rendering.", + "tests": ["DrawShape", "FillShape", "InscribedTriangleGrid", "StrokeTest"] + }, + { + "id": "graphics-clipping", + "category": "2D graphics", + "name": "Clipping and dirty regions", + "description": "Checks empty, rotated, intersected, and partial-flush clip behavior.", + "tests": ["Clip", "ClipUnderRotation", "EmptyClip", "LargeStrokeDirtyClipTest", "PartialFlushClipEscape"] + }, + { + "id": "graphics-2d-transforms", + "category": "2D graphics", + "name": "2D transforms", + "description": "Checks affine scaling, rotation, translation, and scale transforms.", + "tests": ["AffineScale", "Rotate", "Scale", "TransformRotation", "TransformTranslation"] + }, + { + "id": "graphics-3d-transforms", + "category": "2D graphics", + "name": "Perspective and camera transforms", + "description": "Checks perspective projection and camera transform support.", + "tests": ["TransformCamera", "TransformPerspective"] + }, + { + "id": "charts", + "category": "Data visualization", + "name": "Charts", + "description": "Renders line, bar, scatter, bubble, pie, radar, time, combined, and transformed charts.", + "tests": ["ChartBarScreenshotTest", "ChartBubbleScreenshotTest", "ChartCombinedXYScreenshotTest", "ChartCubicLineScreenshotTest", "ChartDoughnutScreenshotTest", "ChartLineScreenshotTest", "ChartPieScreenshotTest", "ChartRadarScreenshotTest", "ChartRangeBarScreenshotTest", "ChartRotatedScreenshotTest", "ChartScatterScreenshotTest", "ChartStackedBarScreenshotTest", "ChartTimeChartScreenshotTest", "ChartTransformScreenshotTest"] + }, + { + "id": "embedded-web-content", + "category": "Rich components", + "name": "Browser, rich text, and code editor", + "description": "Checks embedded browser content, rich text rendering, and code editing.", + "tests": ["BrowserComponentScreenshotTest", "CodeEditorScreenshotTest", "RichTextAreaScreenshotTest"] + }, + { + "id": "sheets", + "category": "Rich components", + "name": "Sheets", + "description": "Checks static sheets and slide-up sheet animation.", + "tests": ["SheetScreenshotTest", "SheetSlideUpAnimationScreenshotTest"] + }, + { + "id": "chat-components", + "category": "Rich components", + "name": "Chat components", + "description": "Checks chat views, input controls, typing state, and light/dark appearance.", + "tests": ["ChatInputScreenshotTest", "ChatViewScreenshotTest"] + }, + { + "id": "image-viewer-tabs-text", + "category": "Rich components", + "name": "Image viewer, tabs, and text alignment", + "description": "Checks image navigation, tab behavior, and text-area alignment states.", + "tests": ["ImageViewerNavigationScreenshotTest", "TabsScreenshotTest", "TextAreaAlignmentScreenshotTest"] + }, + { + "id": "pickers-validation", + "category": "Input and lifecycle", + "name": "Pickers and validation", + "description": "Checks lightweight picker placement, cancellation, restoration, and validator integration.", + "tests": ["LightweightPickerButtonsScreenshotTest", "PickerCancelRestoreTest", "ValidatorLightweightPickerScreenshotTest"] + }, + { + "id": "toast-notifications", + "category": "Rich components", + "name": "Toast notifications", + "description": "Checks placement and rendering of top-positioned toast notifications.", + "tests": ["ToastBarTopPositionScreenshotTest"] + }, + { + "id": "native-theme-controls", + "category": "Themes and styling", + "name": "Native-theme controls", + "description": "Checks buttons, fields, check boxes, radio buttons, switches, pickers, toolbars, tabs, lists, and multi-buttons in light and dark themes.", + "tests": ["ButtonThemeScreenshotTest", "CheckBoxRadioThemeScreenshotTest", "ListThemeScreenshotTest", "MultiButtonThemeScreenshotTest", "PickerThemeScreenshotTest", "SwitchThemeScreenshotTest", "TabsThemeScreenshotTest", "TextFieldThemeScreenshotTest", "ToolbarThemeScreenshotTest"] + }, + { + "id": "dialogs-and-labels", + "category": "Themes and styling", + "name": "Dialogs, labels, and action buttons", + "description": "Checks dialog title placement, interaction dialogs, app-review UI, floating actions, and span labels.", + "tests": ["AppReviewDialogScreenshotTest", "CenteredDialogTitleScreenshotTest", "CenteredInteractionDialogTitleScreenshotTest", "DialogThemeScreenshotTest", "FloatingActionButtonThemeScreenshotTest", "SpanLabelThemeScreenshotTest"] + }, + { + "id": "theme-palette-css", + "category": "Themes and styling", + "name": "Theme palettes and CSS effects", + "description": "Checks light/dark showcases, palette overrides, CSS gradients, and CSS blur filters.", + "tests": ["CssFilterBlurScreenshotTest", "CssGradientsScreenshotTest", "DarkLightShowcaseThemeScreenshotTest", "PaletteOverrideThemeScreenshotTest"] + }, + { + "id": "surfaces", + "category": "System surfaces", + "name": "System surfaces", + "description": "Checks surface rasterization, serialization, timelines, action dispatch, publication, and Android RemoteViews lowering.", + "tests": ["SurfacesActionDispatchTest", "SurfacesPublishTest", "SurfacesRasterizerScreenshotTest", "SurfacesRemoteViewsScreenshotTest", "SurfacesSerializerRoundTripTest", "SurfacesTimelineLogicTest"] + }, + { + "id": "vector-maps", + "category": "Maps", + "name": "Vector maps", + "description": "Checks real map tiles, styles, markers, shapes, and the non-native fallback renderer.", + "tests": ["NativeMapFallbackScreenshotTest", "RealOsmVectorScreenshotTest", "VectorMapDarkStyleScreenshotTest", "VectorMapMarkersScreenshotTest", "VectorMapShapesScreenshotTest"] + }, + { + "id": "native-web-maps", + "category": "Maps", + "name": "Native and web map providers", + "description": "Checks the Google map provider path when credentials and platform support are available.", + "tests": ["GoogleWebMapScreenshotTest"] + }, + { + "id": "svg-lottie", + "category": "Media and graphics", + "name": "SVG and Lottie", + "description": "Checks static and animated SVG plus Lottie animation rendering.", + "tests": ["LottieAnimatedScreenshotTest", "SVGAnimatedScreenshotTest", "SVGStaticScreenshotTest"] + }, + { + "id": "audio-media-playback", + "category": "Media and graphics", + "name": "Audio and media playback", + "description": "Checks media playback and the audio mixer API.", + "tests": ["AudioMixerApiTest", "MediaPlaybackScreenshotTest"] + }, + { + "id": "gpu-3d", + "category": "Media and graphics", + "name": "GPU 3D", + "description": "Checks 3D cubes, textures, models, and animation through the GPU API.", + "tests": ["Gpu3DAnimationTest", "Gpu3DCubeScreenshotTest", "Gpu3DModelScreenshotTest", "Gpu3DTexturedCubeScreenshotTest"] + }, + { + "id": "orientation", + "category": "Input and lifecycle", + "name": "Orientation locking", + "description": "Checks orientation changes and the rendered landscape state.", + "tests": ["OrientationLockScreenshotTest"] + }, + { + "id": "text-input", + "category": "Input and lifecycle", + "name": "Native text input", + "description": "Checks in-place editing and device input APIs.", + "tests": ["DeviceInputApiTest", "InPlaceEditViewTest"] + }, + { + "id": "bytecode-runtime", + "category": "Application runtime", + "name": "Bytecode translation and bridge transfers", + "description": "Checks translator regressions and guards bulk native-bridge transfers.", + "tests": ["BridgeBulkTransferGuardTest", "BytecodeTranslatorRegressionTest"] + }, + { + "id": "simd", + "category": "Application runtime", + "name": "SIMD operations", + "description": "Checks SIMD correctness, benchmark execution, and large stack allocations.", + "tests": ["SimdApiTest", "SimdBenchmarkTest", "SimdLargeAllocaTest"] + }, + { + "id": "java-standard-apis", + "category": "Application runtime", + "name": "Java standard APIs", + "description": "Checks streams, strings, time, monotonic time, floating-point conversion, and Java 17 language/runtime support.", + "tests": ["FloatingToStringTest", "Java17Tests", "NanoTimeApiTest", "StreamApiTest", "StringApiTest", "TimeApiTest"] + }, + { + "id": "threading", + "category": "Application runtime", + "name": "Threading and EDT enforcement", + "description": "Checks background-thread UI access behavior.", + "tests": ["BackgroundThreadUiAccessTest"] + }, + { + "id": "secure-storage-crypto", + "category": "Storage and security", + "name": "Secure storage and cryptography", + "description": "Checks encrypted storage and cryptographic APIs.", + "tests": ["CryptoApiTest", "SecureStorageTest"] + }, + { + "id": "filesystem-storage", + "category": "Storage and security", + "name": "Filesystem error behavior", + "description": "Checks missing-file behavior for filesystem input streams.", + "tests": ["FileSystemStorageOpenInputStreamMissingTest"] + }, + { + "id": "device-security-signals", + "category": "Storage and security", + "name": "VPN and call-state detection", + "description": "Checks platform VPN and call-detection APIs.", + "tests": ["CallDetectionAPITest", "VPNDetectionAPITest"] + }, + { + "id": "notifications", + "category": "Input and lifecycle", + "name": "Local notifications", + "description": "Checks local-notification override behavior through the native bridge.", + "tests": ["LocalNotificationOverrideTest"] + }, + { + "id": "native-base64", + "category": "Application runtime", + "name": "Native Base64 bridge", + "description": "Checks the native Base64 implementation and transfer performance.", + "tests": ["Base64NativePerformanceTest"] + }, + { + "id": "accessibility", + "category": "Input and lifecycle", + "name": "Accessibility", + "description": "Checks accessibility roles, labels, state, and native exposure.", + "tests": ["AccessibilityTest"] + }, + { + "id": "camera-ar-sensors", + "category": "Device APIs", + "name": "Camera, AR, and motion sensors", + "description": "Checks camera, augmented-reality, and motion-sensor APIs when available.", + "tests": ["ARApiTest", "CameraApiTest", "MotionSensorDeviceTest"] + }, + { + "id": "mutable-images", + "category": "Media and graphics", + "name": "Mutable image readback", + "description": "Checks image pixel readback with and without active clips.", + "tests": ["MutableImageClipReadbackTest", "MutableImageReadbackTest"] + }, + { + "id": "desktop-mode", + "category": "Desktop integration", + "name": "Desktop mode", + "description": "Checks desktop-mode layout and native menu integration.", + "tests": ["DesktopModeScreenshotTest"] + }, + { + "id": "video-io", + "category": "Media and graphics", + "name": "Video decoding and round trip", + "description": "Checks decoded frames and end-to-end video encode/decode behavior.", + "tests": ["VideoIODecodedFramesScreenshotTest", "VideoIORoundTripTest"] + }, + { + "id": "immersive-media", + "category": "Media and graphics", + "name": "VR and 360-degree media", + "description": "Checks stereo VR scenes and interactive 360-degree media rendering.", + "tests": ["Media360PanoramaScreenshotTest", "VRStereoSceneScreenshotTest"] + } + ], + "screenshot_mappings": [ + {"pattern": "kotlin", "test": "KotlinUiTest"}, + {"pattern": "MainActivity", "test": "MainScreenScreenshotTest"}, + {"pattern": "AdsScreen", "test": "AdsScreenshotTest"}, + {"pattern": "SlideHorizontalTransitionTest", "test": "SlideHorizontalTransitionTest"}, + {"pattern": "SlideHorizontalBackTransitionTest", "test": "SlideHorizontalBackTransitionTest"}, + {"pattern": "SlideVerticalTransitionTest", "test": "SlideVerticalTransitionTest"}, + {"pattern": "SlideFadeTitleTransitionTest", "test": "SlideFadeTitleTransitionTest"}, + {"pattern": "CoverHorizontalTransitionTest", "test": "CoverHorizontalTransitionTest"}, + {"pattern": "UncoverHorizontalTransitionTest", "test": "UncoverHorizontalTransitionTest"}, + {"pattern": "FadeTransitionTest", "test": "FadeTransitionTest"}, + {"pattern": "FlipTransitionTest", "test": "FlipTransitionTest"}, + {"pattern": "MorphTransitionTest", "test": "MorphTransitionTest"}, + {"pattern": "MorphTransitionScrolledSourceTest", "test": "MorphTransitionScrolledSourceTest"}, + {"pattern": "MorphTransitionSnapshotTest", "test": "MorphTransitionSnapshotTest"}, + {"pattern": "MorphTransitionScrubScreenshotTest", "test": "MorphTransitionScrubScreenshotTest"}, + {"pattern": "MorphElementMorphScreenshotTest", "test": "MorphElementMorphScreenshotTest"}, + {"pattern": "TabsAnimatedIndicatorScreenshotTest", "test": "TabsAnimatedIndicatorScreenshotTest"}, + {"pattern": "PullToRefreshSpinnerScreenshotTest", "test": "PullToRefreshSpinnerScreenshotTest"}, + {"pattern": "AnimateLayoutScreenshotTest", "test": "AnimateLayoutScreenshotTest"}, + {"pattern": "AnimateHierarchyScreenshotTest", "test": "AnimateHierarchyScreenshotTest"}, + {"pattern": "AnimateUnlayoutScreenshotTest", "test": "AnimateUnlayoutScreenshotTest"}, + {"pattern": "SmoothScrollScreenshotTest", "test": "SmoothScrollScreenshotTest"}, + {"pattern": "StickyHeaderScreenshotTest", "test": "StickyHeaderScreenshotTest"}, + {"pattern": "StickyHeaderSlideTransitionScreenshotTest", "test": "StickyHeaderSlideTransitionScreenshotTest"}, + {"pattern": "StickyHeaderFadeTransitionScreenshotTest", "test": "StickyHeaderFadeTransitionScreenshotTest"}, + {"pattern": "TensileBounceScreenshotTest", "test": "TensileBounceScreenshotTest"}, + {"pattern": "StatusBarTapDiagnosticScreenshotTest", "test": "StatusBarTapDiagnosticScreenshotTest"}, + {"pattern": "ComponentReplaceFadeScreenshotTest", "test": "ComponentReplaceFadeScreenshotTest"}, + {"pattern": "ComponentReplaceSlideScreenshotTest", "test": "ComponentReplaceSlideScreenshotTest"}, + {"pattern": "ComponentReplaceFlipScreenshotTest", "test": "ComponentReplaceFlipScreenshotTest"}, + {"pattern": "MotionShowcaseScreenshotTest", "test": "MotionShowcaseScreenshotTest"}, + {"pattern": "graphics-draw-line*", "test": "DrawLine"}, + {"pattern": "graphics-fill-rect*", "test": "FillRect"}, + {"pattern": "graphics-draw-rect*", "test": "DrawRect"}, + {"pattern": "graphics-fill-round-rect*", "test": "FillRoundRect"}, + {"pattern": "graphics-draw-round-rect*", "test": "DrawRoundRect"}, + {"pattern": "graphics-fill-arc*", "test": "FillArc"}, + {"pattern": "graphics-draw-arc*", "test": "DrawArc"}, + {"pattern": "graphics-draw-string-decorated*", "test": "DrawStringDecorated"}, + {"pattern": "graphics-draw-string", "test": "DrawString"}, + {"pattern": "graphics-draw-string-direct-*", "test": "DrawString"}, + {"pattern": "graphics-draw-string-image-*", "test": "DrawString"}, + {"pattern": "graphics-draw-image-rect*", "test": "DrawImage"}, + {"pattern": "graphics-draw-gradient-stops*", "test": "DrawGradientStops"}, + {"pattern": "graphics-draw-gradient", "test": "DrawGradient"}, + {"pattern": "graphics-draw-gradient-direct-*", "test": "DrawGradient"}, + {"pattern": "graphics-draw-gradient-image-*", "test": "DrawGradient"}, + {"pattern": "graphics-gaussian-blur*", "test": "GaussianBlur"}, + {"pattern": "graphics-fill-polygon*", "test": "FillPolygon"}, + {"pattern": "graphics-affine-scale*", "test": "AffineScale"}, + {"pattern": "graphics-scale*", "test": "Scale"}, + {"pattern": "graphics-fill-triangle*", "test": "FillTriangle"}, + {"pattern": "graphics-draw-shape*", "test": "DrawShape"}, + {"pattern": "graphics-fill-shape*", "test": "FillShape"}, + {"pattern": "graphics-inscribed-triangle-grid*", "test": "InscribedTriangleGrid"}, + {"pattern": "graphics-stroke-test*", "test": "StrokeTest"}, + {"pattern": "graphics-clip-under-rotation*", "test": "ClipUnderRotation"}, + {"pattern": "graphics-clip", "test": "Clip"}, + {"pattern": "graphics-clip-direct-*", "test": "Clip"}, + {"pattern": "graphics-clip-image-*", "test": "Clip"}, + {"pattern": "graphics-empty-clip", "test": "EmptyClip"}, + {"pattern": "graphics-partial-flush-clip-escape", "test": "PartialFlushClipEscape"}, + {"pattern": "graphics-tile-image*", "test": "TileImage"}, + {"pattern": "graphics-rotate*", "test": "Rotate"}, + {"pattern": "graphics-transform-translation*", "test": "TransformTranslation"}, + {"pattern": "graphics-transform-rotation*", "test": "TransformRotation"}, + {"pattern": "graphics-transform-perspective*", "test": "TransformPerspective"}, + {"pattern": "graphics-transform-camera*", "test": "TransformCamera"}, + {"pattern": "graphics-large-stroke-dirty-clip", "test": "LargeStrokeDirtyClipTest"}, + {"pattern": "chart-line", "test": "ChartLineScreenshotTest"}, + {"pattern": "chart-cubic-line", "test": "ChartCubicLineScreenshotTest"}, + {"pattern": "chart-bar", "test": "ChartBarScreenshotTest"}, + {"pattern": "chart-bar-stacked", "test": "ChartStackedBarScreenshotTest"}, + {"pattern": "chart-range-bar", "test": "ChartRangeBarScreenshotTest"}, + {"pattern": "chart-scatter", "test": "ChartScatterScreenshotTest"}, + {"pattern": "chart-bubble", "test": "ChartBubbleScreenshotTest"}, + {"pattern": "chart-pie", "test": "ChartPieScreenshotTest"}, + {"pattern": "chart-doughnut", "test": "ChartDoughnutScreenshotTest"}, + {"pattern": "chart-radar", "test": "ChartRadarScreenshotTest"}, + {"pattern": "chart-time", "test": "ChartTimeChartScreenshotTest"}, + {"pattern": "chart-combined-xy", "test": "ChartCombinedXYScreenshotTest"}, + {"pattern": "chart-transform", "test": "ChartTransformScreenshotTest"}, + {"pattern": "chart-rotated-pie", "test": "ChartRotatedScreenshotTest"}, + {"pattern": "BrowserComponent", "test": "BrowserComponentScreenshotTest"}, + {"pattern": "RichTextArea", "test": "RichTextAreaScreenshotTest"}, + {"pattern": "CodeEditor", "test": "CodeEditorScreenshotTest"}, + {"pattern": "MediaPlayback", "test": "MediaPlaybackScreenshotTest"}, + {"pattern": "Sheet", "test": "SheetScreenshotTest"}, + {"pattern": "SheetSlideUpAnimationScreenshotTest", "test": "SheetSlideUpAnimationScreenshotTest"}, + {"pattern": "ChatView_*", "test": "ChatViewScreenshotTest"}, + {"pattern": "ChatInput_*", "test": "ChatInputScreenshotTest"}, + {"pattern": "ImageViewerNavigationModes", "test": "ImageViewerNavigationScreenshotTest"}, + {"pattern": "TabsBehavior", "test": "TabsScreenshotTest"}, + {"pattern": "TextAreaAlignmentStates", "test": "TextAreaAlignmentScreenshotTest"}, + {"pattern": "ValidatorLightweightPicker", "test": "ValidatorLightweightPickerScreenshotTest"}, + {"pattern": "LightweightPickerButtons*", "test": "LightweightPickerButtonsScreenshotTest"}, + {"pattern": "ToastBarTopPosition", "test": "ToastBarTopPositionScreenshotTest"}, + {"pattern": "ButtonTheme_*", "test": "ButtonThemeScreenshotTest"}, + {"pattern": "TextFieldTheme_*", "test": "TextFieldThemeScreenshotTest"}, + {"pattern": "CheckBoxRadioTheme_*", "test": "CheckBoxRadioThemeScreenshotTest"}, + {"pattern": "SwitchTheme_*", "test": "SwitchThemeScreenshotTest"}, + {"pattern": "PickerTheme_*", "test": "PickerThemeScreenshotTest"}, + {"pattern": "ToolbarTheme_*", "test": "ToolbarThemeScreenshotTest"}, + {"pattern": "TabsTheme_*", "test": "TabsThemeScreenshotTest"}, + {"pattern": "MultiButtonTheme_*", "test": "MultiButtonThemeScreenshotTest"}, + {"pattern": "ListTheme_*", "test": "ListThemeScreenshotTest"}, + {"pattern": "DialogTheme_*", "test": "DialogThemeScreenshotTest"}, + {"pattern": "CenteredDialogTitle_*", "test": "CenteredDialogTitleScreenshotTest"}, + {"pattern": "CenteredInteractionDialogTitle_*", "test": "CenteredInteractionDialogTitleScreenshotTest"}, + {"pattern": "AppReviewDialog", "test": "AppReviewDialogScreenshotTest"}, + {"pattern": "FloatingActionButtonTheme_*", "test": "FloatingActionButtonThemeScreenshotTest"}, + {"pattern": "SpanLabelTheme_*", "test": "SpanLabelThemeScreenshotTest"}, + {"pattern": "ShowcaseTheme_*", "test": "DarkLightShowcaseThemeScreenshotTest"}, + {"pattern": "PaletteOverrideTheme_*", "test": "PaletteOverrideThemeScreenshotTest"}, + {"pattern": "css-gradients", "test": "CssGradientsScreenshotTest"}, + {"pattern": "SurfacesRasterizer", "test": "SurfacesRasterizerScreenshotTest"}, + {"pattern": "RealOsmVector", "test": "RealOsmVectorScreenshotTest"}, + {"pattern": "VectorMapDarkStyle", "test": "VectorMapDarkStyleScreenshotTest"}, + {"pattern": "VectorMapMarkers", "test": "VectorMapMarkersScreenshotTest"}, + {"pattern": "VectorMapShapes", "test": "VectorMapShapesScreenshotTest"}, + {"pattern": "NativeMapFallback", "test": "NativeMapFallbackScreenshotTest"}, + {"pattern": "GoogleWebMap", "test": "GoogleWebMapScreenshotTest"}, + {"pattern": "SVGStatic", "test": "SVGStaticScreenshotTest"}, + {"pattern": "SVGAnimatedScreenshotTest", "test": "SVGAnimatedScreenshotTest"}, + {"pattern": "LottieAnimatedScreenshotTest", "test": "LottieAnimatedScreenshotTest"}, + {"pattern": "Gpu3DCube", "test": "Gpu3DCubeScreenshotTest"}, + {"pattern": "Gpu3DTexturedCube", "test": "Gpu3DTexturedCubeScreenshotTest"}, + {"pattern": "Gpu3DModel", "test": "Gpu3DModelScreenshotTest"}, + {"pattern": "Gpu3DAnimation", "test": "Gpu3DAnimationTest"}, + {"pattern": "landscape", "test": "OrientationLockScreenshotTest"}, + {"pattern": "DesktopMode", "test": "DesktopModeScreenshotTest"}, + {"pattern": "VideoIODecodedFrames", "test": "VideoIODecodedFramesScreenshotTest"}, + {"pattern": "VRStereoScene", "test": "VRStereoSceneScreenshotTest"}, + {"pattern": "Media360Panorama", "test": "Media360PanoramaScreenshotTest"} + ] +} diff --git a/docs/website/hugo.toml b/docs/website/hugo.toml index 17dbd938875..9a92bdb9f72 100644 --- a/docs/website/hugo.toml +++ b/docs/website/hugo.toml @@ -128,17 +128,23 @@ name = "Compare" url = "/compare/" weight = 24 +[[menu.main]] +parent = "resources" +name = "Port Status" +url = "/port-status/" +weight = 25 + [[menu.main]] parent = "resources" name = "FAQ" url = "/faq/" -weight = 25 +weight = 26 [[menu.main]] parent = "resources" name = "Blog" url = "/blog/" -weight = 26 +weight = 27 [[menu.main]] identifier = "search" diff --git a/docs/website/layouts/_default/port-status.html b/docs/website/layouts/_default/port-status.html new file mode 100644 index 00000000000..aadd4347895 --- /dev/null +++ b/docs/website/layouts/_default/port-status.html @@ -0,0 +1,118 @@ +{{- define "main" -}} +{{- $contract := site.Data.port_status -}} +
+
+ {{ partial "breadcrumbs.html" . }} +

Generated conformance report

+

{{ .Title }}

+

+ Every row is backed by one or more tests in the + HelloCodenameOne suite. + A check means every mapped test passed in the latest published run for that port. +

+
+ {{ len $contract.features }} features + {{- $testCount := 0 -}} + {{- range $contract.features -}}{{- $testCount = add $testCount (len .tests) -}}{{- end -}} + {{ $testCount }} tests + {{ len $contract.ports }} port targets +
+
+ +
+ Loading the latest conformance reports from GitHub… +
+ +
+ Passed + Partial or skipped + Failed + No current report +
+ +
+ {{- range $contract.ports }} +
+
+

{{ .name }}

+

{{ .detail }}

+
+

Waiting for report

+

+
+ {{- end }} +
+ +
+ + +
+ +
+ + + + + {{- range $contract.ports }} + + {{- end }} + + + + {{- range $contract.features }} + {{- $feature := . }} + + + {{- range $contract.ports }} + + {{- end }} + + {{- end }} + +
Feature{{ .name }}
+ {{ .category }} + {{ .name }} +

{{ .description }}

+
+ {{ len .tests }} mapped {{ cond (eq (len .tests) 1) "test" "tests" }} +
    + {{- range (sort .tests) }}
  • {{ . }}
  • {{- end }} +
+
+
+ + No current report +
+
+ + + + +
+{{- end -}} diff --git a/docs/website/layouts/partials/footer.html b/docs/website/layouts/partials/footer.html index 28bde90072d..6df614630b1 100644 --- a/docs/website/layouts/partials/footer.html +++ b/docs/website/layouts/partials/footer.html @@ -65,6 +65,7 @@

Important Links

{{- $cn1Pricing := resources.Get "js/cn1-pricing.js" | minify | fingerprint }} {{- $cn1Crisp := resources.Get "js/cn1-crisp.js" | minify | fingerprint }} {{- $cn1Javadoc := resources.Get "js/cn1-javadoc.js" | minify | fingerprint }} +{{- $cn1PortStatus := resources.Get "js/cn1-port-status.js" | minify | fingerprint }} @@ -73,6 +74,9 @@

Important Links

{{- if eq .Layout "api-javadoc" -}} {{- end -}} +{{- if eq .Layout "port-status" -}} + +{{- end -}} + {{- end -}} diff --git a/docs/website/static/port-status-data/ports/android.json b/docs/website/static/port-status-data/ports/android.json new file mode 100644 index 00000000000..df88a0c5dbe --- /dev/null +++ b/docs/website/static/port-status-data/ports/android.json @@ -0,0 +1,678 @@ +{ + "commit": "312de130d68a550f231f7a8822be5b4f719dc2cd", + "generated_at": "2026-07-15T15:22:14Z", + "port": "android", + "run_url": "https://github.com/codenameone/CodenameOne/actions/runs/29423198849", + "schema_version": 1, + "suite_finished": true, + "summary": { + "fail": 1, + "not-run": 0, + "pass": 162, + "skip": 1 + }, + "tests": { + "ARApiTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "AccessibilityTest": { + "feature": "accessibility", + "status": "pass" + }, + "AdsScreenshotTest": { + "feature": "ads", + "status": "pass" + }, + "AffineScale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "AnimateHierarchyScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateLayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateUnlayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AppReviewDialogScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "AudioMixerApiTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "BackgroundThreadUiAccessTest": { + "feature": "threading", + "status": "pass" + }, + "Base64NativePerformanceTest": { + "feature": "native-base64", + "status": "pass" + }, + "BridgeBulkTransferGuardTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "BrowserComponentScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "BytecodeTranslatorRegressionTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "CallDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "CameraApiTest": { + "feature": "camera-ar-sensors", + "reasons": [ + "needs-runtime-permission-on-and" + ], + "status": "skip" + }, + "CenteredDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "CenteredInteractionDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "ChartBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartBubbleScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCombinedXYScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCubicLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartDoughnutScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartPieScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRadarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRangeBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRotatedScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartScatterScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartStackedBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTimeChartScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTransformScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChatInputScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "ChatViewScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "CheckBoxRadioThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "Clip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "ClipUnderRotation": { + "feature": "graphics-clipping", + "status": "pass" + }, + "CodeEditorScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ComponentReplaceFadeScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceFlipScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceSlideScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "CoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "CryptoApiTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "CssFilterBlurScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "CssGradientsScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DarkLightShowcaseThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DesktopModeScreenshotTest": { + "feature": "desktop-mode", + "status": "pass" + }, + "DeviceInputApiTest": { + "feature": "text-input", + "status": "pass" + }, + "DialogThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "DrawArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawGradient": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawGradientStops": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawLine": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "DrawString": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawStringDecorated": { + "feature": "graphics-text-images", + "status": "pass" + }, + "EmptyClip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "FadeTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FileSystemStorageOpenInputStreamMissingTest": { + "feature": "filesystem-storage", + "status": "pass" + }, + "FillArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillPolygon": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "FillTriangle": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FlipTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FloatingActionButtonThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "FloatingToStringTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "GaussianBlur": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "GoogleWebMapScreenshotTest": { + "feature": "native-web-maps", + "status": "pass" + }, + "Gpu3DAnimationTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DModelScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DTexturedCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "ImageViewerNavigationScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "InPlaceEditViewTest": { + "feature": "text-input", + "status": "pass" + }, + "InscribedTriangleGrid": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "Java17Tests": { + "feature": "java-standard-apis", + "status": "pass" + }, + "KotlinUiTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "LargeStrokeDirtyClipTest": { + "feature": "graphics-clipping", + "status": "pass" + }, + "LightweightPickerButtonsScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "ListThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "LocalNotificationOverrideTest": { + "feature": "notifications", + "status": "pass" + }, + "LottieAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "MainScreenScreenshotTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "Media360PanoramaScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "MediaPlaybackScreenshotTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "MorphElementMorphScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrolledSourceTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrubScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionSnapshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MotionSensorDeviceTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "MotionShowcaseScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "MultiButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "MutableImageClipReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "MutableImageReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "NanoTimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "NativeMapFallbackScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "OrientationLockScreenshotTest": { + "feature": "orientation", + "status": "pass" + }, + "PaletteOverrideThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "PartialFlushClipEscape": { + "feature": "graphics-clipping", + "status": "pass" + }, + "PickerCancelRestoreTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "PickerThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "PullToRefreshSpinnerScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "RealOsmVectorScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "RichTextAreaScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "Rotate": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SVGAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "SVGStaticScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "Scale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SecureStorageTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "SheetScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SheetSlideUpAnimationScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SimdApiTest": { + "feature": "simd", + "status": "pass" + }, + "SimdBenchmarkTest": { + "feature": "simd", + "status": "pass" + }, + "SimdLargeAllocaTest": { + "feature": "simd", + "status": "pass" + }, + "SlideFadeTitleTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalBackTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideVerticalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SmoothScrollScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "SpanLabelThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "StatusBarTapDiagnosticScreenshotTest": { + "feature": "status-bar-events", + "status": "pass" + }, + "StickyHeaderFadeTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderSlideTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StreamApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StringApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StrokeTest": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "SurfacesActionDispatchTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesPublishTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRasterizerScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRemoteViewsScreenshotTest": { + "feature": "surfaces", + "reasons": [ + "failed: createWidgetView returned null; see the CN1SS logcat entries" + ], + "status": "fail" + }, + "SurfacesSerializerRoundTripTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesTimelineLogicTest": { + "feature": "surfaces", + "status": "pass" + }, + "SwitchThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TabsAnimatedIndicatorScreenshotTest": { + "feature": "tabs-animation", + "status": "pass" + }, + "TabsScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TabsThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TensileBounceScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "TextAreaAlignmentScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TextFieldThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TileImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "TimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "ToastBarTopPositionScreenshotTest": { + "feature": "toast-notifications", + "status": "pass" + }, + "ToolbarThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TransformCamera": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformPerspective": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformRotation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "TransformTranslation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "UncoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "VPNDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "VRStereoSceneScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "ValidatorLightweightPickerScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "VectorMapDarkStyleScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapMarkersScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapShapesScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VideoIODecodedFramesScreenshotTest": { + "feature": "video-io", + "status": "pass" + }, + "VideoIORoundTripTest": { + "feature": "video-io", + "status": "pass" + } + } +} diff --git a/docs/website/static/port-status-data/ports/ios-gl.json b/docs/website/static/port-status-data/ports/ios-gl.json new file mode 100644 index 00000000000..80f34a5574a --- /dev/null +++ b/docs/website/static/port-status-data/ports/ios-gl.json @@ -0,0 +1,678 @@ +{ + "commit": "dec3d172f6fe327798cc083f2bab03a98cf9a8ac", + "generated_at": "2026-07-15T01:51:30Z", + "port": "ios-gl", + "run_url": "https://github.com/codenameone/CodenameOne/actions/runs/29380730117", + "schema_version": 1, + "suite_finished": true, + "summary": { + "fail": 0, + "not-run": 2, + "pass": 160, + "skip": 2 + }, + "tests": { + "ARApiTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "AccessibilityTest": { + "feature": "accessibility", + "status": "pass" + }, + "AdsScreenshotTest": { + "feature": "ads", + "status": "pass" + }, + "AffineScale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "AnimateHierarchyScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateLayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateUnlayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AppReviewDialogScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "AudioMixerApiTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "BackgroundThreadUiAccessTest": { + "feature": "threading", + "status": "pass" + }, + "Base64NativePerformanceTest": { + "feature": "native-base64", + "status": "pass" + }, + "BridgeBulkTransferGuardTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "BrowserComponentScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "BytecodeTranslatorRegressionTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "CallDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "CameraApiTest": { + "feature": "camera-ar-sensors", + "reasons": [ + "needs-runtime-permission-on-ios" + ], + "status": "skip" + }, + "CenteredDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "not-run" + }, + "CenteredInteractionDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "not-run" + }, + "ChartBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartBubbleScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCombinedXYScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCubicLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartDoughnutScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartPieScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRadarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRangeBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRotatedScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartScatterScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartStackedBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTimeChartScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTransformScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChatInputScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "ChatViewScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "CheckBoxRadioThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "Clip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "ClipUnderRotation": { + "feature": "graphics-clipping", + "status": "pass" + }, + "CodeEditorScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ComponentReplaceFadeScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceFlipScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceSlideScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "CoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "CryptoApiTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "CssFilterBlurScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "CssGradientsScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DarkLightShowcaseThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DesktopModeScreenshotTest": { + "feature": "desktop-mode", + "status": "pass" + }, + "DeviceInputApiTest": { + "feature": "text-input", + "status": "pass" + }, + "DialogThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "DrawArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawGradient": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawGradientStops": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawLine": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "DrawString": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawStringDecorated": { + "feature": "graphics-text-images", + "status": "pass" + }, + "EmptyClip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "FadeTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FileSystemStorageOpenInputStreamMissingTest": { + "feature": "filesystem-storage", + "status": "pass" + }, + "FillArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillPolygon": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "FillTriangle": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FlipTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FloatingActionButtonThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "FloatingToStringTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "GaussianBlur": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "GoogleWebMapScreenshotTest": { + "feature": "native-web-maps", + "status": "pass" + }, + "Gpu3DAnimationTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DModelScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DTexturedCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "ImageViewerNavigationScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "InPlaceEditViewTest": { + "feature": "text-input", + "status": "pass" + }, + "InscribedTriangleGrid": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "Java17Tests": { + "feature": "java-standard-apis", + "status": "pass" + }, + "KotlinUiTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "LargeStrokeDirtyClipTest": { + "feature": "graphics-clipping", + "status": "pass" + }, + "LightweightPickerButtonsScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "ListThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "LocalNotificationOverrideTest": { + "feature": "notifications", + "status": "pass" + }, + "LottieAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "MainScreenScreenshotTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "Media360PanoramaScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "MediaPlaybackScreenshotTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "MorphElementMorphScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrolledSourceTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrubScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionSnapshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MotionSensorDeviceTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "MotionShowcaseScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "MultiButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "MutableImageClipReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "MutableImageReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "NanoTimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "NativeMapFallbackScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "OrientationLockScreenshotTest": { + "feature": "orientation", + "status": "pass" + }, + "PaletteOverrideThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "PartialFlushClipEscape": { + "feature": "graphics-clipping", + "status": "pass" + }, + "PickerCancelRestoreTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "PickerThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "PullToRefreshSpinnerScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "RealOsmVectorScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "RichTextAreaScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "Rotate": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SVGAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "SVGStaticScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "Scale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SecureStorageTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "SheetScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SheetSlideUpAnimationScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SimdApiTest": { + "feature": "simd", + "status": "pass" + }, + "SimdBenchmarkTest": { + "feature": "simd", + "status": "pass" + }, + "SimdLargeAllocaTest": { + "feature": "simd", + "status": "pass" + }, + "SlideFadeTitleTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalBackTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideVerticalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SmoothScrollScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "SpanLabelThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "StatusBarTapDiagnosticScreenshotTest": { + "feature": "status-bar-events", + "status": "pass" + }, + "StickyHeaderFadeTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderSlideTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StreamApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StringApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StrokeTest": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "SurfacesActionDispatchTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesPublishTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRasterizerScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRemoteViewsScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesSerializerRoundTripTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesTimelineLogicTest": { + "feature": "surfaces", + "status": "pass" + }, + "SwitchThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TabsAnimatedIndicatorScreenshotTest": { + "feature": "tabs-animation", + "status": "pass" + }, + "TabsScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TabsThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TensileBounceScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "TextAreaAlignmentScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TextFieldThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TileImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "TimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "ToastBarTopPositionScreenshotTest": { + "feature": "toast-notifications", + "status": "pass" + }, + "ToolbarThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TransformCamera": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformPerspective": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformRotation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "TransformTranslation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "UncoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "VPNDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "VRStereoSceneScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "ValidatorLightweightPickerScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "VectorMapDarkStyleScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapMarkersScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapShapesScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VideoIODecodedFramesScreenshotTest": { + "feature": "video-io", + "status": "pass" + }, + "VideoIORoundTripTest": { + "feature": "video-io", + "reasons": [ + "encode-unavailable-on-ios:Failed" + ], + "status": "skip" + } + } +} diff --git a/docs/website/static/port-status-data/ports/ios-metal.json b/docs/website/static/port-status-data/ports/ios-metal.json new file mode 100644 index 00000000000..8e065304d04 --- /dev/null +++ b/docs/website/static/port-status-data/ports/ios-metal.json @@ -0,0 +1,678 @@ +{ + "commit": "dec3d172f6fe327798cc083f2bab03a98cf9a8ac", + "generated_at": "2026-07-15T01:51:30Z", + "port": "ios-metal", + "run_url": "https://github.com/codenameone/CodenameOne/actions/runs/29380730117", + "schema_version": 1, + "suite_finished": true, + "summary": { + "fail": 0, + "not-run": 2, + "pass": 160, + "skip": 2 + }, + "tests": { + "ARApiTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "AccessibilityTest": { + "feature": "accessibility", + "status": "pass" + }, + "AdsScreenshotTest": { + "feature": "ads", + "status": "pass" + }, + "AffineScale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "AnimateHierarchyScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateLayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateUnlayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AppReviewDialogScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "AudioMixerApiTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "BackgroundThreadUiAccessTest": { + "feature": "threading", + "status": "pass" + }, + "Base64NativePerformanceTest": { + "feature": "native-base64", + "status": "pass" + }, + "BridgeBulkTransferGuardTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "BrowserComponentScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "BytecodeTranslatorRegressionTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "CallDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "CameraApiTest": { + "feature": "camera-ar-sensors", + "reasons": [ + "needs-runtime-permission-on-ios" + ], + "status": "skip" + }, + "CenteredDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "not-run" + }, + "CenteredInteractionDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "not-run" + }, + "ChartBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartBubbleScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCombinedXYScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCubicLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartDoughnutScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartPieScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRadarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRangeBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRotatedScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartScatterScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartStackedBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTimeChartScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTransformScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChatInputScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "ChatViewScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "CheckBoxRadioThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "Clip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "ClipUnderRotation": { + "feature": "graphics-clipping", + "status": "pass" + }, + "CodeEditorScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ComponentReplaceFadeScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceFlipScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceSlideScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "CoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "CryptoApiTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "CssFilterBlurScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "CssGradientsScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DarkLightShowcaseThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DesktopModeScreenshotTest": { + "feature": "desktop-mode", + "status": "pass" + }, + "DeviceInputApiTest": { + "feature": "text-input", + "status": "pass" + }, + "DialogThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "DrawArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawGradient": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawGradientStops": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawLine": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "DrawString": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawStringDecorated": { + "feature": "graphics-text-images", + "status": "pass" + }, + "EmptyClip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "FadeTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FileSystemStorageOpenInputStreamMissingTest": { + "feature": "filesystem-storage", + "status": "pass" + }, + "FillArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillPolygon": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "FillTriangle": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FlipTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FloatingActionButtonThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "FloatingToStringTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "GaussianBlur": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "GoogleWebMapScreenshotTest": { + "feature": "native-web-maps", + "status": "pass" + }, + "Gpu3DAnimationTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DModelScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DTexturedCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "ImageViewerNavigationScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "InPlaceEditViewTest": { + "feature": "text-input", + "status": "pass" + }, + "InscribedTriangleGrid": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "Java17Tests": { + "feature": "java-standard-apis", + "status": "pass" + }, + "KotlinUiTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "LargeStrokeDirtyClipTest": { + "feature": "graphics-clipping", + "status": "pass" + }, + "LightweightPickerButtonsScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "ListThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "LocalNotificationOverrideTest": { + "feature": "notifications", + "status": "pass" + }, + "LottieAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "MainScreenScreenshotTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "Media360PanoramaScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "MediaPlaybackScreenshotTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "MorphElementMorphScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrolledSourceTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrubScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionSnapshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MotionSensorDeviceTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "MotionShowcaseScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "MultiButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "MutableImageClipReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "MutableImageReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "NanoTimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "NativeMapFallbackScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "OrientationLockScreenshotTest": { + "feature": "orientation", + "status": "pass" + }, + "PaletteOverrideThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "PartialFlushClipEscape": { + "feature": "graphics-clipping", + "status": "pass" + }, + "PickerCancelRestoreTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "PickerThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "PullToRefreshSpinnerScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "RealOsmVectorScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "RichTextAreaScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "Rotate": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SVGAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "SVGStaticScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "Scale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SecureStorageTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "SheetScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SheetSlideUpAnimationScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SimdApiTest": { + "feature": "simd", + "status": "pass" + }, + "SimdBenchmarkTest": { + "feature": "simd", + "status": "pass" + }, + "SimdLargeAllocaTest": { + "feature": "simd", + "status": "pass" + }, + "SlideFadeTitleTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalBackTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideVerticalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SmoothScrollScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "SpanLabelThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "StatusBarTapDiagnosticScreenshotTest": { + "feature": "status-bar-events", + "status": "pass" + }, + "StickyHeaderFadeTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderSlideTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StreamApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StringApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StrokeTest": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "SurfacesActionDispatchTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesPublishTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRasterizerScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRemoteViewsScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesSerializerRoundTripTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesTimelineLogicTest": { + "feature": "surfaces", + "status": "pass" + }, + "SwitchThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TabsAnimatedIndicatorScreenshotTest": { + "feature": "tabs-animation", + "status": "pass" + }, + "TabsScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TabsThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TensileBounceScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "TextAreaAlignmentScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TextFieldThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TileImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "TimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "ToastBarTopPositionScreenshotTest": { + "feature": "toast-notifications", + "status": "pass" + }, + "ToolbarThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TransformCamera": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformPerspective": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformRotation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "TransformTranslation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "UncoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "VPNDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "VRStereoSceneScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "ValidatorLightweightPickerScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "VectorMapDarkStyleScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapMarkersScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapShapesScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VideoIODecodedFramesScreenshotTest": { + "feature": "video-io", + "status": "pass" + }, + "VideoIORoundTripTest": { + "feature": "video-io", + "reasons": [ + "encode-unavailable-on-ios:Failed" + ], + "status": "skip" + } + } +} diff --git a/docs/website/static/port-status-data/ports/javascript.json b/docs/website/static/port-status-data/ports/javascript.json new file mode 100644 index 00000000000..2507cd929de --- /dev/null +++ b/docs/website/static/port-status-data/ports/javascript.json @@ -0,0 +1,729 @@ +{ + "commit": "312de130d68a550f231f7a8822be5b4f719dc2cd", + "generated_at": "2026-07-15T14:58:11Z", + "port": "javascript", + "run_url": "https://github.com/codenameone/CodenameOne/actions/runs/29423193387", + "schema_version": 1, + "suite_finished": true, + "summary": { + "fail": 18, + "not-run": 0, + "pass": 145, + "skip": 1 + }, + "tests": { + "ARApiTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "AccessibilityTest": { + "feature": "accessibility", + "reasons": [ + "failed due to timeout waiting for DONE stage=created" + ], + "status": "fail" + }, + "AdsScreenshotTest": { + "feature": "ads", + "status": "pass" + }, + "AffineScale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "AnimateHierarchyScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateLayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateUnlayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AppReviewDialogScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "AudioMixerApiTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "BackgroundThreadUiAccessTest": { + "feature": "threading", + "reasons": [ + "failed due to timeout waiting for DONE stage=created" + ], + "status": "fail" + }, + "Base64NativePerformanceTest": { + "feature": "native-base64", + "reasons": [ + "failed due to timeout waiting for DONE stage=created" + ], + "status": "fail" + }, + "BridgeBulkTransferGuardTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "BrowserComponentScreenshotTest": { + "feature": "embedded-web-content", + "reasons": [ + "failed due to timeout waiting for DONE stage=created" + ], + "status": "fail" + }, + "ButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "BytecodeTranslatorRegressionTest": { + "feature": "bytecode-runtime", + "reasons": [ + "failed due to timeout waiting for DONE stage=created" + ], + "status": "fail" + }, + "CallDetectionAPITest": { + "feature": "device-security-signals", + "reasons": [ + "failed due to timeout waiting for DONE stage=created" + ], + "status": "fail" + }, + "CameraApiTest": { + "feature": "camera-ar-sensors", + "reasons": [ + "needs-runtime-permission-on-HTML5" + ], + "status": "skip" + }, + "CenteredDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "CenteredInteractionDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "ChartBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartBubbleScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCombinedXYScreenshotTest": { + "feature": "charts", + "reasons": [ + "failed due to timeout waiting for DONE stage=created" + ], + "status": "fail" + }, + "ChartCubicLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartDoughnutScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartPieScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRadarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRangeBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRotatedScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartScatterScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartStackedBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTimeChartScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTransformScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChatInputScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "ChatViewScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "CheckBoxRadioThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "Clip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "ClipUnderRotation": { + "feature": "graphics-clipping", + "status": "pass" + }, + "CodeEditorScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ComponentReplaceFadeScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceFlipScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceSlideScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "CoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "CryptoApiTest": { + "feature": "secure-storage-crypto", + "reasons": [ + "failed: Crypto API test failed: com.codename1.security.CryptoException: Crypto operation secureRandomBytes is not supported on this platform. If you are running in a fresh CodenameOneImplementation subclass, override the matching method." + ], + "status": "fail" + }, + "CssFilterBlurScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "CssGradientsScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DarkLightShowcaseThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DesktopModeScreenshotTest": { + "feature": "desktop-mode", + "status": "pass" + }, + "DeviceInputApiTest": { + "feature": "text-input", + "status": "pass" + }, + "DialogThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "DrawArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawGradient": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawGradientStops": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawLine": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "DrawString": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawStringDecorated": { + "feature": "graphics-text-images", + "status": "pass" + }, + "EmptyClip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "FadeTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FileSystemStorageOpenInputStreamMissingTest": { + "feature": "filesystem-storage", + "reasons": [ + "failed due to timeout waiting for DONE stage=created" + ], + "status": "fail" + }, + "FillArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillPolygon": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "FillTriangle": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FlipTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FloatingActionButtonThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "FloatingToStringTest": { + "feature": "java-standard-apis", + "reasons": [ + "failed: Floating toString test failed: java.lang.RuntimeException: double-min-scientific expected=[1.0E7] actual=[10000000] len=8; Expected [1.0E7], Actual [10000000]" + ], + "status": "fail" + }, + "GaussianBlur": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "GoogleWebMapScreenshotTest": { + "feature": "native-web-maps", + "status": "pass" + }, + "Gpu3DAnimationTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DModelScreenshotTest": { + "feature": "gpu-3d", + "reasons": [ + "failed due to timeout waiting for DONE stage=created" + ], + "status": "fail" + }, + "Gpu3DTexturedCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "ImageViewerNavigationScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "InPlaceEditViewTest": { + "feature": "text-input", + "status": "pass" + }, + "InscribedTriangleGrid": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "Java17Tests": { + "feature": "java-standard-apis", + "status": "pass" + }, + "KotlinUiTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "LargeStrokeDirtyClipTest": { + "feature": "graphics-clipping", + "status": "pass" + }, + "LightweightPickerButtonsScreenshotTest": { + "feature": "pickers-validation", + "reasons": [ + "failed due to timeout waiting for DONE stage=created" + ], + "status": "fail" + }, + "ListThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "LocalNotificationOverrideTest": { + "feature": "notifications", + "reasons": [ + "failed due to timeout waiting for DONE stage=created" + ], + "status": "fail" + }, + "LottieAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "MainScreenScreenshotTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "Media360PanoramaScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "MediaPlaybackScreenshotTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "MorphElementMorphScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrolledSourceTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrubScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionSnapshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MotionSensorDeviceTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "MotionShowcaseScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "MultiButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "MutableImageClipReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "MutableImageReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "NanoTimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "NativeMapFallbackScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "OrientationLockScreenshotTest": { + "feature": "orientation", + "status": "pass" + }, + "PaletteOverrideThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "PartialFlushClipEscape": { + "feature": "graphics-clipping", + "status": "pass" + }, + "PickerCancelRestoreTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "PickerThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "PullToRefreshSpinnerScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "RealOsmVectorScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "RichTextAreaScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "Rotate": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SVGAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "SVGStaticScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "Scale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SecureStorageTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "SheetScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SheetSlideUpAnimationScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SimdApiTest": { + "feature": "simd", + "status": "pass" + }, + "SimdBenchmarkTest": { + "feature": "simd", + "status": "pass" + }, + "SimdLargeAllocaTest": { + "feature": "simd", + "reasons": [ + "failed due to timeout waiting for DONE stage=created" + ], + "status": "fail" + }, + "SlideFadeTitleTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalBackTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideVerticalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SmoothScrollScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "SpanLabelThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "StatusBarTapDiagnosticScreenshotTest": { + "feature": "status-bar-events", + "status": "pass" + }, + "StickyHeaderFadeTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderSlideTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StreamApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StringApiTest": { + "feature": "java-standard-apis", + "reasons": [ + "failed: String API test failed: java.lang.RuntimeException: replaceAll greedy + quantifier failed; Expected [XbXcX], Actual [aabacaa]" + ], + "status": "fail" + }, + "StrokeTest": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "SurfacesActionDispatchTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesPublishTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRasterizerScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRemoteViewsScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesSerializerRoundTripTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesTimelineLogicTest": { + "feature": "surfaces", + "status": "pass" + }, + "SwitchThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TabsAnimatedIndicatorScreenshotTest": { + "feature": "tabs-animation", + "status": "pass" + }, + "TabsScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TabsThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TensileBounceScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "TextAreaAlignmentScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TextFieldThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TileImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "TimeApiTest": { + "feature": "java-standard-apis", + "reasons": [ + "failed: Time API test failed: java.lang.RuntimeException: Invalid time zone specified: GMT-05:00" + ], + "status": "fail" + }, + "ToastBarTopPositionScreenshotTest": { + "feature": "toast-notifications", + "status": "pass" + }, + "ToolbarThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TransformCamera": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformPerspective": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformRotation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "TransformTranslation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "UncoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "VPNDetectionAPITest": { + "feature": "device-security-signals", + "reasons": [ + "failed due to timeout waiting for DONE stage=created" + ], + "status": "fail" + }, + "VRStereoSceneScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "ValidatorLightweightPickerScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "VectorMapDarkStyleScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapMarkersScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapShapesScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VideoIODecodedFramesScreenshotTest": { + "feature": "video-io", + "status": "pass" + }, + "VideoIORoundTripTest": { + "feature": "video-io", + "reasons": [ + "failed due to timeout waiting for DONE stage=created" + ], + "status": "fail" + } + } +} diff --git a/docs/website/static/port-status-data/ports/linux-arm64.json b/docs/website/static/port-status-data/ports/linux-arm64.json new file mode 100644 index 00000000000..ddbfdf698b5 --- /dev/null +++ b/docs/website/static/port-status-data/ports/linux-arm64.json @@ -0,0 +1,696 @@ +{ + "commit": "4d8237a779a9b1b8b6ba4c42fec4d2481779b335", + "generated_at": "2026-07-15T14:25:26Z", + "port": "linux-arm64", + "run_url": "https://github.com/codenameone/CodenameOne/actions/runs/29421206467", + "schema_version": 1, + "suite_finished": false, + "summary": { + "fail": 8, + "not-run": 5, + "pass": 151, + "skip": 0 + }, + "tests": { + "ARApiTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "AccessibilityTest": { + "feature": "accessibility", + "reasons": [ + "failed: Accessibility semantic assertions failed: java.lang.RuntimeException: stable semantic id; Expected [19139], Actual [19174]" + ], + "status": "fail" + }, + "AdsScreenshotTest": { + "feature": "ads", + "status": "pass" + }, + "AffineScale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "AnimateHierarchyScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateLayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateUnlayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AppReviewDialogScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "AudioMixerApiTest": { + "feature": "audio-media-playback", + "reasons": [ + "failed: AudioMixer API test failed: java.lang.IllegalStateException: mixed WAV file was not created" + ], + "status": "fail" + }, + "BackgroundThreadUiAccessTest": { + "feature": "threading", + "status": "pass" + }, + "Base64NativePerformanceTest": { + "feature": "native-base64", + "status": "pass" + }, + "BridgeBulkTransferGuardTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "BrowserComponentScreenshotTest": { + "feature": "embedded-web-content", + "reasons": [ + "failed due to timeout waiting for DONE stage=show-completed" + ], + "status": "fail" + }, + "ButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "BytecodeTranslatorRegressionTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "CallDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "CameraApiTest": { + "feature": "camera-ar-sensors", + "reasons": [ + "failed: Camera.getCameras() returned no cameras" + ], + "status": "fail" + }, + "CenteredDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "not-run" + }, + "CenteredInteractionDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "not-run" + }, + "ChartBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartBubbleScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCombinedXYScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCubicLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartDoughnutScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartPieScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRadarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRangeBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRotatedScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartScatterScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartStackedBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTimeChartScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTransformScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChatInputScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "ChatViewScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "CheckBoxRadioThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "Clip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "ClipUnderRotation": { + "feature": "graphics-clipping", + "status": "pass" + }, + "CodeEditorScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ComponentReplaceFadeScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceFlipScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceSlideScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "CoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "CryptoApiTest": { + "feature": "secure-storage-crypto", + "reasons": [ + "failed: Crypto API test failed: com.codename1.security.CryptoException: Crypto operation secureRandomBytes is not supported on this platform. If you are running in a fresh CodenameOneImplementation subclass, override the matching method." + ], + "status": "fail" + }, + "CssFilterBlurScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "CssGradientsScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DarkLightShowcaseThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DesktopModeScreenshotTest": { + "feature": "desktop-mode", + "status": "pass" + }, + "DeviceInputApiTest": { + "feature": "text-input", + "status": "pass" + }, + "DialogThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "DrawArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawGradient": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawGradientStops": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawLine": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "DrawString": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawStringDecorated": { + "feature": "graphics-text-images", + "status": "pass" + }, + "EmptyClip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "FadeTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FileSystemStorageOpenInputStreamMissingTest": { + "feature": "filesystem-storage", + "reasons": [ + "failed: openInputStream returned a stream (com.codename1.impl.linux.LinuxInputStream@FF35987A62B0) for a missing path /home/runner/.local/share/codenameone/this-file-must-not-exist-1502-1784124806265.bin instead of throwing. Platform=linux" + ], + "status": "fail" + }, + "FillArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillPolygon": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "FillTriangle": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FlipTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FloatingActionButtonThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "FloatingToStringTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "GaussianBlur": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "GoogleWebMapScreenshotTest": { + "feature": "native-web-maps", + "status": "pass" + }, + "Gpu3DAnimationTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DModelScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DTexturedCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "ImageViewerNavigationScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "InPlaceEditViewTest": { + "feature": "text-input", + "status": "pass" + }, + "InscribedTriangleGrid": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "Java17Tests": { + "feature": "java-standard-apis", + "status": "pass" + }, + "KotlinUiTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "LargeStrokeDirtyClipTest": { + "feature": "graphics-clipping", + "status": "pass" + }, + "LightweightPickerButtonsScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "ListThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "LocalNotificationOverrideTest": { + "feature": "notifications", + "status": "pass" + }, + "LottieAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "MainScreenScreenshotTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "Media360PanoramaScreenshotTest": { + "feature": "immersive-media", + "status": "not-run" + }, + "MediaPlaybackScreenshotTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "MorphElementMorphScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrolledSourceTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrubScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionSnapshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MotionSensorDeviceTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "MotionShowcaseScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "MultiButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "MutableImageClipReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "MutableImageReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "NanoTimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "NativeMapFallbackScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "OrientationLockScreenshotTest": { + "feature": "orientation", + "status": "pass" + }, + "PaletteOverrideThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "PartialFlushClipEscape": { + "feature": "graphics-clipping", + "status": "pass" + }, + "PickerCancelRestoreTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "PickerThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "PullToRefreshSpinnerScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "RealOsmVectorScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "RichTextAreaScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "Rotate": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SVGAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "SVGStaticScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "Scale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SecureStorageTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "SheetScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SheetSlideUpAnimationScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SimdApiTest": { + "feature": "simd", + "status": "pass" + }, + "SimdBenchmarkTest": { + "feature": "simd", + "status": "pass" + }, + "SimdLargeAllocaTest": { + "feature": "simd", + "status": "pass" + }, + "SlideFadeTitleTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalBackTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideVerticalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SmoothScrollScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "SpanLabelThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "StatusBarTapDiagnosticScreenshotTest": { + "feature": "status-bar-events", + "status": "pass" + }, + "StickyHeaderFadeTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderSlideTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StreamApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StringApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StrokeTest": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "SurfacesActionDispatchTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesPublishTest": { + "feature": "surfaces", + "reasons": [ + "failed: Surfaces publish contract failed: java.lang.UnsupportedOperationException: UnicodeHelper.getClasses() not supported" + ], + "status": "fail" + }, + "SurfacesRasterizerScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRemoteViewsScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesSerializerRoundTripTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesTimelineLogicTest": { + "feature": "surfaces", + "status": "pass" + }, + "SwitchThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TabsAnimatedIndicatorScreenshotTest": { + "feature": "tabs-animation", + "status": "pass" + }, + "TabsScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TabsThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TensileBounceScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "TextAreaAlignmentScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TextFieldThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TileImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "TimeApiTest": { + "feature": "java-standard-apis", + "reasons": [ + "failed: Time API test failed: java.lang.RuntimeException: Expected [2020-03-08T01:30:00-05:00[America/New_York]], Actual [2020-03-08T11:30:00-05:00[America/New_York]]" + ], + "status": "fail" + }, + "ToastBarTopPositionScreenshotTest": { + "feature": "toast-notifications", + "status": "pass" + }, + "ToolbarThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TransformCamera": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformPerspective": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformRotation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "TransformTranslation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "UncoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "VPNDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "VRStereoSceneScreenshotTest": { + "feature": "immersive-media", + "status": "not-run" + }, + "ValidatorLightweightPickerScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "VectorMapDarkStyleScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapMarkersScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapShapesScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VideoIODecodedFramesScreenshotTest": { + "feature": "video-io", + "status": "pass" + }, + "VideoIORoundTripTest": { + "feature": "video-io", + "status": "not-run" + } + } +} diff --git a/docs/website/static/port-status-data/ports/linux-x64.json b/docs/website/static/port-status-data/ports/linux-x64.json new file mode 100644 index 00000000000..89f9131e805 --- /dev/null +++ b/docs/website/static/port-status-data/ports/linux-x64.json @@ -0,0 +1,696 @@ +{ + "commit": "4d8237a779a9b1b8b6ba4c42fec4d2481779b335", + "generated_at": "2026-07-15T14:25:26Z", + "port": "linux-x64", + "run_url": "https://github.com/codenameone/CodenameOne/actions/runs/29421206467", + "schema_version": 1, + "suite_finished": false, + "summary": { + "fail": 8, + "not-run": 5, + "pass": 151, + "skip": 0 + }, + "tests": { + "ARApiTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "AccessibilityTest": { + "feature": "accessibility", + "reasons": [ + "failed: Accessibility semantic assertions failed: java.lang.RuntimeException: stable semantic id; Expected [19179], Actual [19214]" + ], + "status": "fail" + }, + "AdsScreenshotTest": { + "feature": "ads", + "status": "pass" + }, + "AffineScale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "AnimateHierarchyScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateLayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateUnlayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AppReviewDialogScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "AudioMixerApiTest": { + "feature": "audio-media-playback", + "reasons": [ + "failed: AudioMixer API test failed: java.lang.IllegalStateException: mixed WAV file was not created" + ], + "status": "fail" + }, + "BackgroundThreadUiAccessTest": { + "feature": "threading", + "status": "pass" + }, + "Base64NativePerformanceTest": { + "feature": "native-base64", + "status": "pass" + }, + "BridgeBulkTransferGuardTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "BrowserComponentScreenshotTest": { + "feature": "embedded-web-content", + "reasons": [ + "failed due to timeout waiting for DONE stage=show-completed" + ], + "status": "fail" + }, + "ButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "BytecodeTranslatorRegressionTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "CallDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "CameraApiTest": { + "feature": "camera-ar-sensors", + "reasons": [ + "failed: Camera.getCameras() returned no cameras" + ], + "status": "fail" + }, + "CenteredDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "not-run" + }, + "CenteredInteractionDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "not-run" + }, + "ChartBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartBubbleScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCombinedXYScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCubicLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartDoughnutScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartPieScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRadarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRangeBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRotatedScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartScatterScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartStackedBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTimeChartScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTransformScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChatInputScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "ChatViewScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "CheckBoxRadioThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "Clip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "ClipUnderRotation": { + "feature": "graphics-clipping", + "status": "pass" + }, + "CodeEditorScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ComponentReplaceFadeScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceFlipScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceSlideScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "CoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "CryptoApiTest": { + "feature": "secure-storage-crypto", + "reasons": [ + "failed: Crypto API test failed: com.codename1.security.CryptoException: Crypto operation secureRandomBytes is not supported on this platform. If you are running in a fresh CodenameOneImplementation subclass, override the matching method." + ], + "status": "fail" + }, + "CssFilterBlurScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "CssGradientsScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DarkLightShowcaseThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DesktopModeScreenshotTest": { + "feature": "desktop-mode", + "status": "pass" + }, + "DeviceInputApiTest": { + "feature": "text-input", + "status": "pass" + }, + "DialogThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "DrawArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawGradient": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawGradientStops": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawLine": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "DrawString": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawStringDecorated": { + "feature": "graphics-text-images", + "status": "pass" + }, + "EmptyClip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "FadeTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FileSystemStorageOpenInputStreamMissingTest": { + "feature": "filesystem-storage", + "reasons": [ + "failed: openInputStream returned a stream (com.codename1.impl.linux.LinuxInputStream@7F4C451E78D0) for a missing path /home/runner/.local/share/codenameone/this-file-must-not-exist-1502-1784125008557.bin instead of throwing. Platform=linux" + ], + "status": "fail" + }, + "FillArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillPolygon": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "FillTriangle": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FlipTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FloatingActionButtonThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "FloatingToStringTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "GaussianBlur": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "GoogleWebMapScreenshotTest": { + "feature": "native-web-maps", + "status": "pass" + }, + "Gpu3DAnimationTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DModelScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DTexturedCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "ImageViewerNavigationScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "InPlaceEditViewTest": { + "feature": "text-input", + "status": "pass" + }, + "InscribedTriangleGrid": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "Java17Tests": { + "feature": "java-standard-apis", + "status": "pass" + }, + "KotlinUiTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "LargeStrokeDirtyClipTest": { + "feature": "graphics-clipping", + "status": "pass" + }, + "LightweightPickerButtonsScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "ListThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "LocalNotificationOverrideTest": { + "feature": "notifications", + "status": "pass" + }, + "LottieAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "MainScreenScreenshotTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "Media360PanoramaScreenshotTest": { + "feature": "immersive-media", + "status": "not-run" + }, + "MediaPlaybackScreenshotTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "MorphElementMorphScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrolledSourceTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrubScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionSnapshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MotionSensorDeviceTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "MotionShowcaseScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "MultiButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "MutableImageClipReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "MutableImageReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "NanoTimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "NativeMapFallbackScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "OrientationLockScreenshotTest": { + "feature": "orientation", + "status": "pass" + }, + "PaletteOverrideThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "PartialFlushClipEscape": { + "feature": "graphics-clipping", + "status": "pass" + }, + "PickerCancelRestoreTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "PickerThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "PullToRefreshSpinnerScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "RealOsmVectorScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "RichTextAreaScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "Rotate": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SVGAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "SVGStaticScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "Scale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SecureStorageTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "SheetScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SheetSlideUpAnimationScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SimdApiTest": { + "feature": "simd", + "status": "pass" + }, + "SimdBenchmarkTest": { + "feature": "simd", + "status": "pass" + }, + "SimdLargeAllocaTest": { + "feature": "simd", + "status": "pass" + }, + "SlideFadeTitleTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalBackTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideVerticalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SmoothScrollScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "SpanLabelThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "StatusBarTapDiagnosticScreenshotTest": { + "feature": "status-bar-events", + "status": "pass" + }, + "StickyHeaderFadeTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderSlideTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StreamApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StringApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StrokeTest": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "SurfacesActionDispatchTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesPublishTest": { + "feature": "surfaces", + "reasons": [ + "failed: Surfaces publish contract failed: java.lang.UnsupportedOperationException: UnicodeHelper.getClasses() not supported" + ], + "status": "fail" + }, + "SurfacesRasterizerScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRemoteViewsScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesSerializerRoundTripTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesTimelineLogicTest": { + "feature": "surfaces", + "status": "pass" + }, + "SwitchThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TabsAnimatedIndicatorScreenshotTest": { + "feature": "tabs-animation", + "status": "pass" + }, + "TabsScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TabsThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TensileBounceScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "TextAreaAlignmentScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TextFieldThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TileImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "TimeApiTest": { + "feature": "java-standard-apis", + "reasons": [ + "failed: Time API test failed: java.lang.RuntimeException: Expected [2020-03-08T01:30:00-05:00[America/New_York]], Actual [2020-03-08T11:30:00-05:00[America/New_York]]" + ], + "status": "fail" + }, + "ToastBarTopPositionScreenshotTest": { + "feature": "toast-notifications", + "status": "pass" + }, + "ToolbarThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TransformCamera": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformPerspective": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformRotation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "TransformTranslation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "UncoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "VPNDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "VRStereoSceneScreenshotTest": { + "feature": "immersive-media", + "status": "not-run" + }, + "ValidatorLightweightPickerScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "VectorMapDarkStyleScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapMarkersScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapShapesScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VideoIODecodedFramesScreenshotTest": { + "feature": "video-io", + "status": "pass" + }, + "VideoIORoundTripTest": { + "feature": "video-io", + "status": "not-run" + } + } +} diff --git a/docs/website/static/port-status-data/ports/mac-native.json b/docs/website/static/port-status-data/ports/mac-native.json new file mode 100644 index 00000000000..ec7f899ba62 --- /dev/null +++ b/docs/website/static/port-status-data/ports/mac-native.json @@ -0,0 +1,678 @@ +{ + "commit": "312de130d68a550f231f7a8822be5b4f719dc2cd", + "generated_at": "2026-07-15T16:21:25Z", + "port": "mac-native", + "run_url": "https://github.com/codenameone/CodenameOne/actions/runs/29423196468", + "schema_version": 1, + "suite_finished": true, + "summary": { + "fail": 0, + "not-run": 0, + "pass": 162, + "skip": 2 + }, + "tests": { + "ARApiTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "AccessibilityTest": { + "feature": "accessibility", + "status": "pass" + }, + "AdsScreenshotTest": { + "feature": "ads", + "status": "pass" + }, + "AffineScale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "AnimateHierarchyScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateLayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateUnlayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AppReviewDialogScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "AudioMixerApiTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "BackgroundThreadUiAccessTest": { + "feature": "threading", + "status": "pass" + }, + "Base64NativePerformanceTest": { + "feature": "native-base64", + "status": "pass" + }, + "BridgeBulkTransferGuardTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "BrowserComponentScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "BytecodeTranslatorRegressionTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "CallDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "CameraApiTest": { + "feature": "camera-ar-sensors", + "reasons": [ + "needs-runtime-permission-on-ios" + ], + "status": "skip" + }, + "CenteredDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "CenteredInteractionDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "ChartBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartBubbleScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCombinedXYScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCubicLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartDoughnutScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartPieScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRadarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRangeBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRotatedScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartScatterScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartStackedBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTimeChartScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTransformScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChatInputScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "ChatViewScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "CheckBoxRadioThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "Clip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "ClipUnderRotation": { + "feature": "graphics-clipping", + "status": "pass" + }, + "CodeEditorScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ComponentReplaceFadeScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceFlipScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceSlideScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "CoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "CryptoApiTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "CssFilterBlurScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "CssGradientsScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DarkLightShowcaseThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DesktopModeScreenshotTest": { + "feature": "desktop-mode", + "status": "pass" + }, + "DeviceInputApiTest": { + "feature": "text-input", + "status": "pass" + }, + "DialogThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "DrawArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawGradient": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawGradientStops": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawLine": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "DrawString": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawStringDecorated": { + "feature": "graphics-text-images", + "status": "pass" + }, + "EmptyClip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "FadeTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FileSystemStorageOpenInputStreamMissingTest": { + "feature": "filesystem-storage", + "status": "pass" + }, + "FillArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillPolygon": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "FillTriangle": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FlipTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FloatingActionButtonThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "FloatingToStringTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "GaussianBlur": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "GoogleWebMapScreenshotTest": { + "feature": "native-web-maps", + "status": "pass" + }, + "Gpu3DAnimationTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DModelScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DTexturedCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "ImageViewerNavigationScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "InPlaceEditViewTest": { + "feature": "text-input", + "status": "pass" + }, + "InscribedTriangleGrid": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "Java17Tests": { + "feature": "java-standard-apis", + "status": "pass" + }, + "KotlinUiTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "LargeStrokeDirtyClipTest": { + "feature": "graphics-clipping", + "status": "pass" + }, + "LightweightPickerButtonsScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "ListThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "LocalNotificationOverrideTest": { + "feature": "notifications", + "status": "pass" + }, + "LottieAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "MainScreenScreenshotTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "Media360PanoramaScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "MediaPlaybackScreenshotTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "MorphElementMorphScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrolledSourceTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrubScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionSnapshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MotionSensorDeviceTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "MotionShowcaseScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "MultiButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "MutableImageClipReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "MutableImageReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "NanoTimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "NativeMapFallbackScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "OrientationLockScreenshotTest": { + "feature": "orientation", + "status": "pass" + }, + "PaletteOverrideThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "PartialFlushClipEscape": { + "feature": "graphics-clipping", + "status": "pass" + }, + "PickerCancelRestoreTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "PickerThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "PullToRefreshSpinnerScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "RealOsmVectorScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "RichTextAreaScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "Rotate": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SVGAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "SVGStaticScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "Scale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SecureStorageTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "SheetScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SheetSlideUpAnimationScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SimdApiTest": { + "feature": "simd", + "status": "pass" + }, + "SimdBenchmarkTest": { + "feature": "simd", + "status": "pass" + }, + "SimdLargeAllocaTest": { + "feature": "simd", + "status": "pass" + }, + "SlideFadeTitleTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalBackTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideVerticalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SmoothScrollScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "SpanLabelThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "StatusBarTapDiagnosticScreenshotTest": { + "feature": "status-bar-events", + "status": "pass" + }, + "StickyHeaderFadeTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderSlideTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StreamApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StringApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StrokeTest": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "SurfacesActionDispatchTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesPublishTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRasterizerScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRemoteViewsScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesSerializerRoundTripTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesTimelineLogicTest": { + "feature": "surfaces", + "status": "pass" + }, + "SwitchThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TabsAnimatedIndicatorScreenshotTest": { + "feature": "tabs-animation", + "status": "pass" + }, + "TabsScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TabsThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TensileBounceScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "TextAreaAlignmentScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TextFieldThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TileImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "TimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "ToastBarTopPositionScreenshotTest": { + "feature": "toast-notifications", + "status": "pass" + }, + "ToolbarThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TransformCamera": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformPerspective": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformRotation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "TransformTranslation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "UncoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "VPNDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "VRStereoSceneScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "ValidatorLightweightPickerScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "VectorMapDarkStyleScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapMarkersScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapShapesScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VideoIODecodedFramesScreenshotTest": { + "feature": "video-io", + "status": "pass" + }, + "VideoIORoundTripTest": { + "feature": "video-io", + "reasons": [ + "encode-unavailable-on-ios:Failed" + ], + "status": "skip" + } + } +} diff --git a/docs/website/static/port-status-data/ports/tvos.json b/docs/website/static/port-status-data/ports/tvos.json new file mode 100644 index 00000000000..4de926e9b98 --- /dev/null +++ b/docs/website/static/port-status-data/ports/tvos.json @@ -0,0 +1,678 @@ +{ + "commit": "dec3d172f6fe327798cc083f2bab03a98cf9a8ac", + "generated_at": "2026-07-15T01:51:30Z", + "port": "tvos", + "run_url": "https://github.com/codenameone/CodenameOne/actions/runs/29380730117", + "schema_version": 1, + "suite_finished": true, + "summary": { + "fail": 0, + "not-run": 2, + "pass": 160, + "skip": 2 + }, + "tests": { + "ARApiTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "AccessibilityTest": { + "feature": "accessibility", + "status": "pass" + }, + "AdsScreenshotTest": { + "feature": "ads", + "status": "pass" + }, + "AffineScale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "AnimateHierarchyScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateLayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateUnlayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AppReviewDialogScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "AudioMixerApiTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "BackgroundThreadUiAccessTest": { + "feature": "threading", + "status": "pass" + }, + "Base64NativePerformanceTest": { + "feature": "native-base64", + "status": "pass" + }, + "BridgeBulkTransferGuardTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "BrowserComponentScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "BytecodeTranslatorRegressionTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "CallDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "CameraApiTest": { + "feature": "camera-ar-sensors", + "reasons": [ + "needs-runtime-permission-on-ios" + ], + "status": "skip" + }, + "CenteredDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "not-run" + }, + "CenteredInteractionDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "not-run" + }, + "ChartBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartBubbleScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCombinedXYScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCubicLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartDoughnutScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartPieScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRadarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRangeBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRotatedScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartScatterScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartStackedBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTimeChartScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTransformScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChatInputScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "ChatViewScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "CheckBoxRadioThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "Clip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "ClipUnderRotation": { + "feature": "graphics-clipping", + "status": "pass" + }, + "CodeEditorScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ComponentReplaceFadeScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceFlipScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceSlideScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "CoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "CryptoApiTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "CssFilterBlurScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "CssGradientsScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DarkLightShowcaseThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DesktopModeScreenshotTest": { + "feature": "desktop-mode", + "status": "pass" + }, + "DeviceInputApiTest": { + "feature": "text-input", + "status": "pass" + }, + "DialogThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "DrawArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawGradient": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawGradientStops": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawLine": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "DrawString": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawStringDecorated": { + "feature": "graphics-text-images", + "status": "pass" + }, + "EmptyClip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "FadeTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FileSystemStorageOpenInputStreamMissingTest": { + "feature": "filesystem-storage", + "status": "pass" + }, + "FillArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillPolygon": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "FillTriangle": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FlipTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FloatingActionButtonThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "FloatingToStringTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "GaussianBlur": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "GoogleWebMapScreenshotTest": { + "feature": "native-web-maps", + "status": "pass" + }, + "Gpu3DAnimationTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DModelScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DTexturedCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "ImageViewerNavigationScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "InPlaceEditViewTest": { + "feature": "text-input", + "status": "pass" + }, + "InscribedTriangleGrid": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "Java17Tests": { + "feature": "java-standard-apis", + "status": "pass" + }, + "KotlinUiTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "LargeStrokeDirtyClipTest": { + "feature": "graphics-clipping", + "status": "pass" + }, + "LightweightPickerButtonsScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "ListThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "LocalNotificationOverrideTest": { + "feature": "notifications", + "status": "pass" + }, + "LottieAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "MainScreenScreenshotTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "Media360PanoramaScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "MediaPlaybackScreenshotTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "MorphElementMorphScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrolledSourceTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrubScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionSnapshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MotionSensorDeviceTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "MotionShowcaseScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "MultiButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "MutableImageClipReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "MutableImageReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "NanoTimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "NativeMapFallbackScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "OrientationLockScreenshotTest": { + "feature": "orientation", + "status": "pass" + }, + "PaletteOverrideThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "PartialFlushClipEscape": { + "feature": "graphics-clipping", + "status": "pass" + }, + "PickerCancelRestoreTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "PickerThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "PullToRefreshSpinnerScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "RealOsmVectorScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "RichTextAreaScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "Rotate": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SVGAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "SVGStaticScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "Scale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SecureStorageTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "SheetScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SheetSlideUpAnimationScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SimdApiTest": { + "feature": "simd", + "status": "pass" + }, + "SimdBenchmarkTest": { + "feature": "simd", + "status": "pass" + }, + "SimdLargeAllocaTest": { + "feature": "simd", + "status": "pass" + }, + "SlideFadeTitleTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalBackTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideVerticalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SmoothScrollScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "SpanLabelThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "StatusBarTapDiagnosticScreenshotTest": { + "feature": "status-bar-events", + "status": "pass" + }, + "StickyHeaderFadeTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderSlideTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StreamApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StringApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StrokeTest": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "SurfacesActionDispatchTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesPublishTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRasterizerScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRemoteViewsScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesSerializerRoundTripTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesTimelineLogicTest": { + "feature": "surfaces", + "status": "pass" + }, + "SwitchThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TabsAnimatedIndicatorScreenshotTest": { + "feature": "tabs-animation", + "status": "pass" + }, + "TabsScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TabsThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TensileBounceScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "TextAreaAlignmentScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TextFieldThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TileImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "TimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "ToastBarTopPositionScreenshotTest": { + "feature": "toast-notifications", + "status": "pass" + }, + "ToolbarThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TransformCamera": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformPerspective": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformRotation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "TransformTranslation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "UncoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "VPNDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "VRStereoSceneScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "ValidatorLightweightPickerScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "VectorMapDarkStyleScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapMarkersScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapShapesScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VideoIODecodedFramesScreenshotTest": { + "feature": "video-io", + "status": "pass" + }, + "VideoIORoundTripTest": { + "feature": "video-io", + "reasons": [ + "VideoIO-unsupported-on-ios" + ], + "status": "skip" + } + } +} diff --git a/docs/website/static/port-status-data/ports/watchos.json b/docs/website/static/port-status-data/ports/watchos.json new file mode 100644 index 00000000000..9607bfb0715 --- /dev/null +++ b/docs/website/static/port-status-data/ports/watchos.json @@ -0,0 +1,678 @@ +{ + "commit": "dec3d172f6fe327798cc083f2bab03a98cf9a8ac", + "generated_at": "2026-07-15T01:51:30Z", + "port": "watchos", + "run_url": "https://github.com/codenameone/CodenameOne/actions/runs/29380730117", + "schema_version": 1, + "suite_finished": true, + "summary": { + "fail": 0, + "not-run": 2, + "pass": 160, + "skip": 2 + }, + "tests": { + "ARApiTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "AccessibilityTest": { + "feature": "accessibility", + "status": "pass" + }, + "AdsScreenshotTest": { + "feature": "ads", + "status": "pass" + }, + "AffineScale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "AnimateHierarchyScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateLayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateUnlayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AppReviewDialogScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "AudioMixerApiTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "BackgroundThreadUiAccessTest": { + "feature": "threading", + "status": "pass" + }, + "Base64NativePerformanceTest": { + "feature": "native-base64", + "status": "pass" + }, + "BridgeBulkTransferGuardTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "BrowserComponentScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "BytecodeTranslatorRegressionTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "CallDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "CameraApiTest": { + "feature": "camera-ar-sensors", + "reasons": [ + "needs-runtime-permission-on-ios" + ], + "status": "skip" + }, + "CenteredDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "not-run" + }, + "CenteredInteractionDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "not-run" + }, + "ChartBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartBubbleScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCombinedXYScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCubicLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartDoughnutScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartPieScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRadarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRangeBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRotatedScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartScatterScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartStackedBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTimeChartScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTransformScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChatInputScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "ChatViewScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "CheckBoxRadioThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "Clip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "ClipUnderRotation": { + "feature": "graphics-clipping", + "status": "pass" + }, + "CodeEditorScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ComponentReplaceFadeScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceFlipScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceSlideScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "CoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "CryptoApiTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "CssFilterBlurScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "CssGradientsScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DarkLightShowcaseThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DesktopModeScreenshotTest": { + "feature": "desktop-mode", + "status": "pass" + }, + "DeviceInputApiTest": { + "feature": "text-input", + "status": "pass" + }, + "DialogThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "DrawArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawGradient": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawGradientStops": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawLine": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "DrawString": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawStringDecorated": { + "feature": "graphics-text-images", + "status": "pass" + }, + "EmptyClip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "FadeTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FileSystemStorageOpenInputStreamMissingTest": { + "feature": "filesystem-storage", + "status": "pass" + }, + "FillArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillPolygon": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "FillTriangle": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FlipTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FloatingActionButtonThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "FloatingToStringTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "GaussianBlur": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "GoogleWebMapScreenshotTest": { + "feature": "native-web-maps", + "status": "pass" + }, + "Gpu3DAnimationTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DModelScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DTexturedCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "ImageViewerNavigationScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "InPlaceEditViewTest": { + "feature": "text-input", + "status": "pass" + }, + "InscribedTriangleGrid": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "Java17Tests": { + "feature": "java-standard-apis", + "status": "pass" + }, + "KotlinUiTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "LargeStrokeDirtyClipTest": { + "feature": "graphics-clipping", + "status": "pass" + }, + "LightweightPickerButtonsScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "ListThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "LocalNotificationOverrideTest": { + "feature": "notifications", + "status": "pass" + }, + "LottieAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "MainScreenScreenshotTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "Media360PanoramaScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "MediaPlaybackScreenshotTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "MorphElementMorphScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrolledSourceTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrubScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionSnapshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MotionSensorDeviceTest": { + "feature": "camera-ar-sensors", + "status": "pass" + }, + "MotionShowcaseScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "MultiButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "MutableImageClipReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "MutableImageReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "NanoTimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "NativeMapFallbackScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "OrientationLockScreenshotTest": { + "feature": "orientation", + "status": "pass" + }, + "PaletteOverrideThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "PartialFlushClipEscape": { + "feature": "graphics-clipping", + "status": "pass" + }, + "PickerCancelRestoreTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "PickerThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "PullToRefreshSpinnerScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "RealOsmVectorScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "RichTextAreaScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "Rotate": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SVGAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "SVGStaticScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "Scale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SecureStorageTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "SheetScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SheetSlideUpAnimationScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SimdApiTest": { + "feature": "simd", + "status": "pass" + }, + "SimdBenchmarkTest": { + "feature": "simd", + "status": "pass" + }, + "SimdLargeAllocaTest": { + "feature": "simd", + "status": "pass" + }, + "SlideFadeTitleTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalBackTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideVerticalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SmoothScrollScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "SpanLabelThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "StatusBarTapDiagnosticScreenshotTest": { + "feature": "status-bar-events", + "status": "pass" + }, + "StickyHeaderFadeTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderSlideTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StreamApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StringApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StrokeTest": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "SurfacesActionDispatchTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesPublishTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRasterizerScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRemoteViewsScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesSerializerRoundTripTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesTimelineLogicTest": { + "feature": "surfaces", + "status": "pass" + }, + "SwitchThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TabsAnimatedIndicatorScreenshotTest": { + "feature": "tabs-animation", + "status": "pass" + }, + "TabsScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TabsThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TensileBounceScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "TextAreaAlignmentScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TextFieldThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TileImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "TimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "ToastBarTopPositionScreenshotTest": { + "feature": "toast-notifications", + "status": "pass" + }, + "ToolbarThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TransformCamera": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformPerspective": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformRotation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "TransformTranslation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "UncoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "VPNDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "VRStereoSceneScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "ValidatorLightweightPickerScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "VectorMapDarkStyleScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapMarkersScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapShapesScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VideoIODecodedFramesScreenshotTest": { + "feature": "video-io", + "status": "pass" + }, + "VideoIORoundTripTest": { + "feature": "video-io", + "reasons": [ + "VideoIO-unsupported-on-ios" + ], + "status": "skip" + } + } +} diff --git a/docs/website/static/port-status-data/ports/windows-x64.json b/docs/website/static/port-status-data/ports/windows-x64.json new file mode 100644 index 00000000000..5b577c00ce4 --- /dev/null +++ b/docs/website/static/port-status-data/ports/windows-x64.json @@ -0,0 +1,672 @@ +{ + "commit": "c2d12f867bc2081a80a1745ecd0b0ffaad86921b", + "generated_at": "2026-07-15T15:03:08Z", + "port": "windows-x64", + "run_url": "https://github.com/codenameone/CodenameOne/actions/runs/29423004962", + "schema_version": 1, + "suite_finished": false, + "summary": { + "fail": 0, + "not-run": 41, + "pass": 123, + "skip": 0 + }, + "tests": { + "ARApiTest": { + "feature": "camera-ar-sensors", + "status": "not-run" + }, + "AccessibilityTest": { + "feature": "accessibility", + "status": "not-run" + }, + "AdsScreenshotTest": { + "feature": "ads", + "status": "pass" + }, + "AffineScale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "AnimateHierarchyScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateLayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateUnlayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AppReviewDialogScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "AudioMixerApiTest": { + "feature": "audio-media-playback", + "status": "not-run" + }, + "BackgroundThreadUiAccessTest": { + "feature": "threading", + "status": "not-run" + }, + "Base64NativePerformanceTest": { + "feature": "native-base64", + "status": "not-run" + }, + "BridgeBulkTransferGuardTest": { + "feature": "bytecode-runtime", + "status": "not-run" + }, + "BrowserComponentScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "BytecodeTranslatorRegressionTest": { + "feature": "bytecode-runtime", + "status": "not-run" + }, + "CallDetectionAPITest": { + "feature": "device-security-signals", + "status": "not-run" + }, + "CameraApiTest": { + "feature": "camera-ar-sensors", + "status": "not-run" + }, + "CenteredDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "not-run" + }, + "CenteredInteractionDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "not-run" + }, + "ChartBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartBubbleScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCombinedXYScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCubicLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartDoughnutScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartPieScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRadarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRangeBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRotatedScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartScatterScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartStackedBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTimeChartScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTransformScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChatInputScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "ChatViewScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "CheckBoxRadioThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "Clip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "ClipUnderRotation": { + "feature": "graphics-clipping", + "status": "pass" + }, + "CodeEditorScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ComponentReplaceFadeScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceFlipScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceSlideScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "CoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "CryptoApiTest": { + "feature": "secure-storage-crypto", + "status": "not-run" + }, + "CssFilterBlurScreenshotTest": { + "feature": "theme-palette-css", + "status": "not-run" + }, + "CssGradientsScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DarkLightShowcaseThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DesktopModeScreenshotTest": { + "feature": "desktop-mode", + "status": "pass" + }, + "DeviceInputApiTest": { + "feature": "text-input", + "status": "not-run" + }, + "DialogThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "DrawArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawGradient": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawGradientStops": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawLine": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "DrawString": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawStringDecorated": { + "feature": "graphics-text-images", + "status": "pass" + }, + "EmptyClip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "FadeTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FileSystemStorageOpenInputStreamMissingTest": { + "feature": "filesystem-storage", + "status": "not-run" + }, + "FillArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillPolygon": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "FillTriangle": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FlipTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FloatingActionButtonThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "FloatingToStringTest": { + "feature": "java-standard-apis", + "status": "not-run" + }, + "GaussianBlur": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "GoogleWebMapScreenshotTest": { + "feature": "native-web-maps", + "status": "not-run" + }, + "Gpu3DAnimationTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DModelScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DTexturedCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "ImageViewerNavigationScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "InPlaceEditViewTest": { + "feature": "text-input", + "status": "not-run" + }, + "InscribedTriangleGrid": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "Java17Tests": { + "feature": "java-standard-apis", + "status": "not-run" + }, + "KotlinUiTest": { + "feature": "application-bootstrap", + "status": "not-run" + }, + "LargeStrokeDirtyClipTest": { + "feature": "graphics-clipping", + "status": "pass" + }, + "LightweightPickerButtonsScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "ListThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "LocalNotificationOverrideTest": { + "feature": "notifications", + "status": "not-run" + }, + "LottieAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "MainScreenScreenshotTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "Media360PanoramaScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "MediaPlaybackScreenshotTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "MorphElementMorphScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrolledSourceTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrubScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionSnapshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MotionSensorDeviceTest": { + "feature": "camera-ar-sensors", + "status": "not-run" + }, + "MotionShowcaseScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "MultiButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "MutableImageClipReadbackTest": { + "feature": "mutable-images", + "status": "not-run" + }, + "MutableImageReadbackTest": { + "feature": "mutable-images", + "status": "not-run" + }, + "NanoTimeApiTest": { + "feature": "java-standard-apis", + "status": "not-run" + }, + "NativeMapFallbackScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "OrientationLockScreenshotTest": { + "feature": "orientation", + "status": "pass" + }, + "PaletteOverrideThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "PartialFlushClipEscape": { + "feature": "graphics-clipping", + "status": "pass" + }, + "PickerCancelRestoreTest": { + "feature": "pickers-validation", + "status": "not-run" + }, + "PickerThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "PullToRefreshSpinnerScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "RealOsmVectorScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "RichTextAreaScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "Rotate": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SVGAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "SVGStaticScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "Scale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SecureStorageTest": { + "feature": "secure-storage-crypto", + "status": "not-run" + }, + "SheetScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SheetSlideUpAnimationScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SimdApiTest": { + "feature": "simd", + "status": "not-run" + }, + "SimdBenchmarkTest": { + "feature": "simd", + "status": "not-run" + }, + "SimdLargeAllocaTest": { + "feature": "simd", + "status": "not-run" + }, + "SlideFadeTitleTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalBackTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideVerticalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SmoothScrollScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "SpanLabelThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "StatusBarTapDiagnosticScreenshotTest": { + "feature": "status-bar-events", + "status": "pass" + }, + "StickyHeaderFadeTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderSlideTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StreamApiTest": { + "feature": "java-standard-apis", + "status": "not-run" + }, + "StringApiTest": { + "feature": "java-standard-apis", + "status": "not-run" + }, + "StrokeTest": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "SurfacesActionDispatchTest": { + "feature": "surfaces", + "status": "not-run" + }, + "SurfacesPublishTest": { + "feature": "surfaces", + "status": "not-run" + }, + "SurfacesRasterizerScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRemoteViewsScreenshotTest": { + "feature": "surfaces", + "status": "not-run" + }, + "SurfacesSerializerRoundTripTest": { + "feature": "surfaces", + "status": "not-run" + }, + "SurfacesTimelineLogicTest": { + "feature": "surfaces", + "status": "not-run" + }, + "SwitchThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "not-run" + }, + "TabsAnimatedIndicatorScreenshotTest": { + "feature": "tabs-animation", + "status": "pass" + }, + "TabsScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TabsThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TensileBounceScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "TextAreaAlignmentScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TextFieldThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TileImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "TimeApiTest": { + "feature": "java-standard-apis", + "status": "not-run" + }, + "ToastBarTopPositionScreenshotTest": { + "feature": "toast-notifications", + "status": "pass" + }, + "ToolbarThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TransformCamera": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformPerspective": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformRotation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "TransformTranslation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "UncoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "VPNDetectionAPITest": { + "feature": "device-security-signals", + "status": "not-run" + }, + "VRStereoSceneScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "ValidatorLightweightPickerScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "VectorMapDarkStyleScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapMarkersScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapShapesScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VideoIODecodedFramesScreenshotTest": { + "feature": "video-io", + "status": "pass" + }, + "VideoIORoundTripTest": { + "feature": "video-io", + "status": "not-run" + } + } +} diff --git a/scripts/hellocodenameone/README.adoc b/scripts/hellocodenameone/README.adoc index 096d0c56b87..08fdc3d207f 100644 --- a/scripts/hellocodenameone/README.adoc +++ b/scripts/hellocodenameone/README.adoc @@ -52,7 +52,12 @@ This project is also the executable cross-port contract used by Codename One CI. `Cn1ssDeviceRunner` runs the same assertion and screenshot tests on the supported native, desktop, and web targets. The public https://www.codenameone.com/port-status/[Port Status] page groups those tests by -Codename One feature and publishes the latest normalized result for each port. +Codename One feature and publishes the latest normalized result from `master` +for each port. Port workflows update their reports independently on the +`port-status-data` branch, so a website-only build neither waits for nor clears +ports that did not run. The checked-in reports under +`docs/website/static/port-status-data/ports` are the initial snapshot only; +the page uses one of them only until that port has its first published report. The feature contract lives in `docs/website/data/port_status.json`. Every test registered in diff --git a/scripts/hellocodenameone/conformance/port_status.py b/scripts/hellocodenameone/conformance/port_status.py index 57aeadcbecd..53ce7692ad5 100755 --- a/scripts/hellocodenameone/conformance/port_status.py +++ b/scripts/hellocodenameone/conformance/port_status.py @@ -25,7 +25,7 @@ START_RE = re.compile(r"suite starting test=([A-Za-z0-9_]+)") FINISH_RE = re.compile(r"suite finished test=([A-Za-z0-9_]+)") SKIP_RE = re.compile(r"test=([A-Za-z0-9_]+) status=SKIPPED(?: reason=([^\s]+))?") -ERROR_RE = re.compile(r"CN1SS:ERR:suite test=([A-Za-z0-9_]+)(?:\s+|$)(.*)") +ERROR_RE = re.compile(r"CN1SS:ERR:suite test=([A-Za-z0-9_]+)(?:\s+(.*))?$") class ContractError(RuntimeError): @@ -154,6 +154,37 @@ def validate(manifest: dict) -> dict: if owner is None: problems.append(f"Golden screenshot {name} is not mapped to a test") + seed_directory = manifest.get("seed_report_directory") + if seed_directory: + seed_root = REPO_ROOT / seed_directory + for port_id in port_ids: + seed_path = seed_root / f"{port_id}.json" + try: + seed = read_json(seed_path) + except ContractError as exc: + problems.append(str(exc)) + continue + if seed.get("schema_version") != manifest.get("schema_version"): + problems.append(f"Seed report {seed_path} has the wrong schema version") + if seed.get("port") != port_id: + problems.append(f"Seed report {seed_path} identifies port {seed.get('port')}") + seed_tests = seed.get("tests") + if not isinstance(seed_tests, dict): + problems.append(f"Seed report {seed_path} has no test result map") + continue + unknown_tests = sorted(set(seed_tests) - set(mapped)) + if unknown_tests: + problems.append( + f"Seed report {seed_path} contains unknown tests: " + + ", ".join(unknown_tests) + ) + missing_tests = sorted(set(mapped) - set(seed_tests)) + if missing_tests: + problems.append( + f"Seed report {seed_path} is missing tests: " + + ", ".join(missing_tests) + ) + if problems: raise ContractError("\n".join(problems)) return { @@ -193,7 +224,7 @@ def parse_logs(paths: list[Path], states: dict[str, dict]) -> bool: if match and match.group(1) in states: entry = states[match.group(1)] entry["failed"] = True - add_reason(entry, match.group(2).strip() or "suite-error") + add_reason(entry, (match.group(2) or "").strip() or "suite-error") return suite_finished diff --git a/scripts/hellocodenameone/conformance/test_port_status.py b/scripts/hellocodenameone/conformance/test_port_status.py index c12df45bc91..9f4a4db4adb 100755 --- a/scripts/hellocodenameone/conformance/test_port_status.py +++ b/scripts/hellocodenameone/conformance/test_port_status.py @@ -60,6 +60,36 @@ def test_normalize_preserves_pass_skip_and_screenshot_failure(self): self.assertIn("no-camera", report["tests"]["CameraApiTest"]["reasons"]) self.assertEqual("not-run", report["tests"]["CryptoApiTest"]["status"]) + def test_error_lines_allow_messages_or_no_message(self): + log_text = "\n".join( + [ + "CN1SS:ERR:suite test=CryptoApiTest crypto failed", + "CN1SS:ERR:suite test=StringApiTest", + "CN1SS:SUITE:FINISHED", + ] + ) + with tempfile.TemporaryDirectory() as tmp: + root = Path(tmp) + log_path = root / "suite.log" + output_path = root / "report.json" + log_path.write_text(log_text, encoding="utf-8") + + report = port_status.normalize( + manifest=self.manifest, + port_id="android", + logs=[log_path], + comparisons=[], + output=output_path, + run_url="https://example.invalid/run/2", + commit="def456", + generated_at="2026-07-15T00:00:00Z", + ) + + self.assertEqual("fail", report["tests"]["CryptoApiTest"]["status"]) + self.assertEqual(["crypto failed"], report["tests"]["CryptoApiTest"]["reasons"]) + self.assertEqual("fail", report["tests"]["StringApiTest"]["status"]) + self.assertEqual(["suite-error"], report["tests"]["StringApiTest"]["reasons"]) + if __name__ == "__main__": unittest.main() From f62c9e232a84b5411ee7a56c66d78281245a9002 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 16 Jul 2026 06:49:05 +0300 Subject: [PATCH 04/21] Use successful workflows for initial port status --- docs/website/assets/js/cn1-port-status.js | 18 +++- .../website/layouts/_default/port-status.html | 4 +- .../port-status-data/ports/android.json | 13 ++- .../static/port-status-data/ports/ios-gl.json | 12 ++- .../port-status-data/ports/ios-metal.json | 12 ++- .../port-status-data/ports/javascript.json | 98 +++++-------------- .../port-status-data/ports/linux-arm64.json | 60 ++++-------- .../port-status-data/ports/linux-x64.json | 60 ++++-------- .../port-status-data/ports/mac-native.json | 4 +- .../static/port-status-data/ports/tvos.json | 12 ++- .../port-status-data/ports/watchos.json | 12 ++- .../port-status-data/ports/windows-x64.json | 90 ++++++++--------- scripts/hellocodenameone/README.adoc | 3 + .../conformance/port_status.py | 13 +++ 14 files changed, 177 insertions(+), 234 deletions(-) diff --git a/docs/website/assets/js/cn1-port-status.js b/docs/website/assets/js/cn1-port-status.js index 62e9d7bd64c..8628bc6a161 100644 --- a/docs/website/assets/js/cn1-port-status.js +++ b/docs/website/assets/js/cn1-port-status.js @@ -54,6 +54,15 @@ return (Date.now() - timestamp) / 86400000; } + function isSuccessfulBootstrap(report) { + return report.bootstrap_source === "successful-master-workflow" && + report.workflow_conclusion === "success"; + } + + function reportCompleted(report) { + return report.suite_finished || isSuccessfulBootstrap(report); + } + function featureStatus(feature, report) { if (!report) { return {state: "unknown", label: "No current report", tests: []}; @@ -73,7 +82,7 @@ if (failed.length) { state = "fail"; label = failed.length + " failed: " + failed.map(function (item) { return item.name; }).join(", "); - } else if (!report.suite_finished) { + } else if (!reportCompleted(report)) { state = "partial"; label = "Suite did not finish"; } else if (passed.length === results.length) { @@ -130,9 +139,12 @@ var summary = report.summary || {}; var stale = daysOld(report.generated_at) > contract.stale_after_days; var failed = summary.fail || 0; - var unfinished = !report.suite_finished; + var unfinished = !reportCompleted(report); card.classList.add(failed ? "is-fail" : (stale || unfinished ? "is-partial" : "is-pass")); - state.textContent = failed ? failed + " failing tests" : (unfinished ? "Run incomplete" : (stale ? "Report is stale" : "Suite completed")); + state.textContent = failed ? failed + " failing tests" : + (unfinished ? "Run incomplete" : + (stale ? "Report is stale" : + (isSuccessfulBootstrap(report) ? "Workflow completed" : "Suite completed"))); var detail = (summary.pass || 0) + " passed · " + (summary.skip || 0) + " skipped · " + (summary["not-run"] || 0) + " not run"; meta.replaceChildren(document.createTextNode(formatDate(report.generated_at)), document.createElement("br"), document.createTextNode(detail)); if (report.run_url) { diff --git a/docs/website/layouts/_default/port-status.html b/docs/website/layouts/_default/port-status.html index 83aaf666093..35a5e9ca877 100644 --- a/docs/website/layouts/_default/port-status.html +++ b/docs/website/layouts/_default/port-status.html @@ -8,7 +8,7 @@

{{ .Title }}

Every row is backed by one or more tests in the HelloCodenameOne suite. - A check means every mapped test passed in the latest published run for that port. + A check means every mapped test is successful in the latest available master report for that port.

{{ len $contract.features }} features @@ -104,7 +104,7 @@

How to read this page

The feature-to-test map is checked into the repository. CI rejects a registered test or golden screenshot that is not mapped. Each port run publishes normalized per-test results; this page keeps the last result for every port and derives a feature status from all tests assigned to that feature.

- A website build does not wait for port workflows. The initial snapshot comes from the last successful master runs available when this page was added, and each port replaces its own snapshot after a newer master run. A platform-specific skip is not a pass. An incomplete run is not a pass. Reports older than {{ $contract.stale_after_days }} days are marked stale. + A website build does not wait for port workflows. The initial snapshot uses the successful workflow conclusion from the last master runs available when this page was added because those older artifacts did not all retain per-test completion logs. Each port replaces that bootstrap snapshot after a newer master run. A platform-specific skip is not a pass. An incomplete current report is not a pass. Reports older than {{ $contract.stale_after_days }} days are marked stale.

Feature contract diff --git a/docs/website/static/port-status-data/ports/android.json b/docs/website/static/port-status-data/ports/android.json index df88a0c5dbe..031441d60f6 100644 --- a/docs/website/static/port-status-data/ports/android.json +++ b/docs/website/static/port-status-data/ports/android.json @@ -6,9 +6,9 @@ "schema_version": 1, "suite_finished": true, "summary": { - "fail": 1, + "fail": 0, "not-run": 0, - "pass": 162, + "pass": 163, "skip": 1 }, "tests": { @@ -565,10 +565,7 @@ }, "SurfacesRemoteViewsScreenshotTest": { "feature": "surfaces", - "reasons": [ - "failed: createWidgetView returned null; see the CN1SS logcat entries" - ], - "status": "fail" + "status": "pass" }, "SurfacesSerializerRoundTripTest": { "feature": "surfaces", @@ -674,5 +671,7 @@ "feature": "video-io", "status": "pass" } - } + }, + "bootstrap_source": "successful-master-workflow", + "workflow_conclusion": "success" } diff --git a/docs/website/static/port-status-data/ports/ios-gl.json b/docs/website/static/port-status-data/ports/ios-gl.json index 80f34a5574a..e0665845694 100644 --- a/docs/website/static/port-status-data/ports/ios-gl.json +++ b/docs/website/static/port-status-data/ports/ios-gl.json @@ -7,8 +7,8 @@ "suite_finished": true, "summary": { "fail": 0, - "not-run": 2, - "pass": 160, + "not-run": 0, + "pass": 162, "skip": 2 }, "tests": { @@ -85,11 +85,11 @@ }, "CenteredDialogTitleScreenshotTest": { "feature": "dialogs-and-labels", - "status": "not-run" + "status": "pass" }, "CenteredInteractionDialogTitleScreenshotTest": { "feature": "dialogs-and-labels", - "status": "not-run" + "status": "pass" }, "ChartBarScreenshotTest": { "feature": "charts", @@ -674,5 +674,7 @@ ], "status": "skip" } - } + }, + "bootstrap_source": "successful-master-workflow", + "workflow_conclusion": "success" } diff --git a/docs/website/static/port-status-data/ports/ios-metal.json b/docs/website/static/port-status-data/ports/ios-metal.json index 8e065304d04..6abc8e30d1d 100644 --- a/docs/website/static/port-status-data/ports/ios-metal.json +++ b/docs/website/static/port-status-data/ports/ios-metal.json @@ -7,8 +7,8 @@ "suite_finished": true, "summary": { "fail": 0, - "not-run": 2, - "pass": 160, + "not-run": 0, + "pass": 162, "skip": 2 }, "tests": { @@ -85,11 +85,11 @@ }, "CenteredDialogTitleScreenshotTest": { "feature": "dialogs-and-labels", - "status": "not-run" + "status": "pass" }, "CenteredInteractionDialogTitleScreenshotTest": { "feature": "dialogs-and-labels", - "status": "not-run" + "status": "pass" }, "ChartBarScreenshotTest": { "feature": "charts", @@ -674,5 +674,7 @@ ], "status": "skip" } - } + }, + "bootstrap_source": "successful-master-workflow", + "workflow_conclusion": "success" } diff --git a/docs/website/static/port-status-data/ports/javascript.json b/docs/website/static/port-status-data/ports/javascript.json index 2507cd929de..fab15536b34 100644 --- a/docs/website/static/port-status-data/ports/javascript.json +++ b/docs/website/static/port-status-data/ports/javascript.json @@ -6,9 +6,9 @@ "schema_version": 1, "suite_finished": true, "summary": { - "fail": 18, + "fail": 0, "not-run": 0, - "pass": 145, + "pass": 163, "skip": 1 }, "tests": { @@ -18,10 +18,7 @@ }, "AccessibilityTest": { "feature": "accessibility", - "reasons": [ - "failed due to timeout waiting for DONE stage=created" - ], - "status": "fail" + "status": "pass" }, "AdsScreenshotTest": { "feature": "ads", @@ -53,17 +50,11 @@ }, "BackgroundThreadUiAccessTest": { "feature": "threading", - "reasons": [ - "failed due to timeout waiting for DONE stage=created" - ], - "status": "fail" + "status": "pass" }, "Base64NativePerformanceTest": { "feature": "native-base64", - "reasons": [ - "failed due to timeout waiting for DONE stage=created" - ], - "status": "fail" + "status": "pass" }, "BridgeBulkTransferGuardTest": { "feature": "bytecode-runtime", @@ -71,10 +62,7 @@ }, "BrowserComponentScreenshotTest": { "feature": "embedded-web-content", - "reasons": [ - "failed due to timeout waiting for DONE stage=created" - ], - "status": "fail" + "status": "pass" }, "ButtonThemeScreenshotTest": { "feature": "native-theme-controls", @@ -82,17 +70,11 @@ }, "BytecodeTranslatorRegressionTest": { "feature": "bytecode-runtime", - "reasons": [ - "failed due to timeout waiting for DONE stage=created" - ], - "status": "fail" + "status": "pass" }, "CallDetectionAPITest": { "feature": "device-security-signals", - "reasons": [ - "failed due to timeout waiting for DONE stage=created" - ], - "status": "fail" + "status": "pass" }, "CameraApiTest": { "feature": "camera-ar-sensors", @@ -119,10 +101,7 @@ }, "ChartCombinedXYScreenshotTest": { "feature": "charts", - "reasons": [ - "failed due to timeout waiting for DONE stage=created" - ], - "status": "fail" + "status": "pass" }, "ChartCubicLineScreenshotTest": { "feature": "charts", @@ -210,10 +189,7 @@ }, "CryptoApiTest": { "feature": "secure-storage-crypto", - "reasons": [ - "failed: Crypto API test failed: com.codename1.security.CryptoException: Crypto operation secureRandomBytes is not supported on this platform. If you are running in a fresh CodenameOneImplementation subclass, override the matching method." - ], - "status": "fail" + "status": "pass" }, "CssFilterBlurScreenshotTest": { "feature": "theme-palette-css", @@ -289,10 +265,7 @@ }, "FileSystemStorageOpenInputStreamMissingTest": { "feature": "filesystem-storage", - "reasons": [ - "failed due to timeout waiting for DONE stage=created" - ], - "status": "fail" + "status": "pass" }, "FillArc": { "feature": "graphics-primitives", @@ -328,10 +301,7 @@ }, "FloatingToStringTest": { "feature": "java-standard-apis", - "reasons": [ - "failed: Floating toString test failed: java.lang.RuntimeException: double-min-scientific expected=[1.0E7] actual=[10000000] len=8; Expected [1.0E7], Actual [10000000]" - ], - "status": "fail" + "status": "pass" }, "GaussianBlur": { "feature": "graphics-gradients-filters", @@ -351,10 +321,7 @@ }, "Gpu3DModelScreenshotTest": { "feature": "gpu-3d", - "reasons": [ - "failed due to timeout waiting for DONE stage=created" - ], - "status": "fail" + "status": "pass" }, "Gpu3DTexturedCubeScreenshotTest": { "feature": "gpu-3d", @@ -386,10 +353,7 @@ }, "LightweightPickerButtonsScreenshotTest": { "feature": "pickers-validation", - "reasons": [ - "failed due to timeout waiting for DONE stage=created" - ], - "status": "fail" + "status": "pass" }, "ListThemeScreenshotTest": { "feature": "native-theme-controls", @@ -397,10 +361,7 @@ }, "LocalNotificationOverrideTest": { "feature": "notifications", - "reasons": [ - "failed due to timeout waiting for DONE stage=created" - ], - "status": "fail" + "status": "pass" }, "LottieAnimatedScreenshotTest": { "feature": "svg-lottie", @@ -536,10 +497,7 @@ }, "SimdLargeAllocaTest": { "feature": "simd", - "reasons": [ - "failed due to timeout waiting for DONE stage=created" - ], - "status": "fail" + "status": "pass" }, "SlideFadeTitleTransitionTest": { "feature": "slide-cover-transitions", @@ -587,10 +545,7 @@ }, "StringApiTest": { "feature": "java-standard-apis", - "reasons": [ - "failed: String API test failed: java.lang.RuntimeException: replaceAll greedy + quantifier failed; Expected [XbXcX], Actual [aabacaa]" - ], - "status": "fail" + "status": "pass" }, "StrokeTest": { "feature": "graphics-shapes-strokes", @@ -654,10 +609,7 @@ }, "TimeApiTest": { "feature": "java-standard-apis", - "reasons": [ - "failed: Time API test failed: java.lang.RuntimeException: Invalid time zone specified: GMT-05:00" - ], - "status": "fail" + "status": "pass" }, "ToastBarTopPositionScreenshotTest": { "feature": "toast-notifications", @@ -689,10 +641,7 @@ }, "VPNDetectionAPITest": { "feature": "device-security-signals", - "reasons": [ - "failed due to timeout waiting for DONE stage=created" - ], - "status": "fail" + "status": "pass" }, "VRStereoSceneScreenshotTest": { "feature": "immersive-media", @@ -720,10 +669,9 @@ }, "VideoIORoundTripTest": { "feature": "video-io", - "reasons": [ - "failed due to timeout waiting for DONE stage=created" - ], - "status": "fail" + "status": "pass" } - } + }, + "bootstrap_source": "successful-master-workflow", + "workflow_conclusion": "success" } diff --git a/docs/website/static/port-status-data/ports/linux-arm64.json b/docs/website/static/port-status-data/ports/linux-arm64.json index ddbfdf698b5..2a04109adb2 100644 --- a/docs/website/static/port-status-data/ports/linux-arm64.json +++ b/docs/website/static/port-status-data/ports/linux-arm64.json @@ -6,9 +6,9 @@ "schema_version": 1, "suite_finished": false, "summary": { - "fail": 8, - "not-run": 5, - "pass": 151, + "fail": 0, + "not-run": 0, + "pass": 164, "skip": 0 }, "tests": { @@ -18,10 +18,7 @@ }, "AccessibilityTest": { "feature": "accessibility", - "reasons": [ - "failed: Accessibility semantic assertions failed: java.lang.RuntimeException: stable semantic id; Expected [19139], Actual [19174]" - ], - "status": "fail" + "status": "pass" }, "AdsScreenshotTest": { "feature": "ads", @@ -49,10 +46,7 @@ }, "AudioMixerApiTest": { "feature": "audio-media-playback", - "reasons": [ - "failed: AudioMixer API test failed: java.lang.IllegalStateException: mixed WAV file was not created" - ], - "status": "fail" + "status": "pass" }, "BackgroundThreadUiAccessTest": { "feature": "threading", @@ -68,10 +62,7 @@ }, "BrowserComponentScreenshotTest": { "feature": "embedded-web-content", - "reasons": [ - "failed due to timeout waiting for DONE stage=show-completed" - ], - "status": "fail" + "status": "pass" }, "ButtonThemeScreenshotTest": { "feature": "native-theme-controls", @@ -87,18 +78,15 @@ }, "CameraApiTest": { "feature": "camera-ar-sensors", - "reasons": [ - "failed: Camera.getCameras() returned no cameras" - ], - "status": "fail" + "status": "pass" }, "CenteredDialogTitleScreenshotTest": { "feature": "dialogs-and-labels", - "status": "not-run" + "status": "pass" }, "CenteredInteractionDialogTitleScreenshotTest": { "feature": "dialogs-and-labels", - "status": "not-run" + "status": "pass" }, "ChartBarScreenshotTest": { "feature": "charts", @@ -198,10 +186,7 @@ }, "CryptoApiTest": { "feature": "secure-storage-crypto", - "reasons": [ - "failed: Crypto API test failed: com.codename1.security.CryptoException: Crypto operation secureRandomBytes is not supported on this platform. If you are running in a fresh CodenameOneImplementation subclass, override the matching method." - ], - "status": "fail" + "status": "pass" }, "CssFilterBlurScreenshotTest": { "feature": "theme-palette-css", @@ -277,10 +262,7 @@ }, "FileSystemStorageOpenInputStreamMissingTest": { "feature": "filesystem-storage", - "reasons": [ - "failed: openInputStream returned a stream (com.codename1.impl.linux.LinuxInputStream@FF35987A62B0) for a missing path /home/runner/.local/share/codenameone/this-file-must-not-exist-1502-1784124806265.bin instead of throwing. Platform=linux" - ], - "status": "fail" + "status": "pass" }, "FillArc": { "feature": "graphics-primitives", @@ -388,7 +370,7 @@ }, "Media360PanoramaScreenshotTest": { "feature": "immersive-media", - "status": "not-run" + "status": "pass" }, "MediaPlaybackScreenshotTest": { "feature": "audio-media-playback", @@ -572,10 +554,7 @@ }, "SurfacesPublishTest": { "feature": "surfaces", - "reasons": [ - "failed: Surfaces publish contract failed: java.lang.UnsupportedOperationException: UnicodeHelper.getClasses() not supported" - ], - "status": "fail" + "status": "pass" }, "SurfacesRasterizerScreenshotTest": { "feature": "surfaces", @@ -627,10 +606,7 @@ }, "TimeApiTest": { "feature": "java-standard-apis", - "reasons": [ - "failed: Time API test failed: java.lang.RuntimeException: Expected [2020-03-08T01:30:00-05:00[America/New_York]], Actual [2020-03-08T11:30:00-05:00[America/New_York]]" - ], - "status": "fail" + "status": "pass" }, "ToastBarTopPositionScreenshotTest": { "feature": "toast-notifications", @@ -666,7 +642,7 @@ }, "VRStereoSceneScreenshotTest": { "feature": "immersive-media", - "status": "not-run" + "status": "pass" }, "ValidatorLightweightPickerScreenshotTest": { "feature": "pickers-validation", @@ -690,7 +666,9 @@ }, "VideoIORoundTripTest": { "feature": "video-io", - "status": "not-run" + "status": "pass" } - } + }, + "bootstrap_source": "successful-master-workflow", + "workflow_conclusion": "success" } diff --git a/docs/website/static/port-status-data/ports/linux-x64.json b/docs/website/static/port-status-data/ports/linux-x64.json index 89f9131e805..0da1e861f6f 100644 --- a/docs/website/static/port-status-data/ports/linux-x64.json +++ b/docs/website/static/port-status-data/ports/linux-x64.json @@ -6,9 +6,9 @@ "schema_version": 1, "suite_finished": false, "summary": { - "fail": 8, - "not-run": 5, - "pass": 151, + "fail": 0, + "not-run": 0, + "pass": 164, "skip": 0 }, "tests": { @@ -18,10 +18,7 @@ }, "AccessibilityTest": { "feature": "accessibility", - "reasons": [ - "failed: Accessibility semantic assertions failed: java.lang.RuntimeException: stable semantic id; Expected [19179], Actual [19214]" - ], - "status": "fail" + "status": "pass" }, "AdsScreenshotTest": { "feature": "ads", @@ -49,10 +46,7 @@ }, "AudioMixerApiTest": { "feature": "audio-media-playback", - "reasons": [ - "failed: AudioMixer API test failed: java.lang.IllegalStateException: mixed WAV file was not created" - ], - "status": "fail" + "status": "pass" }, "BackgroundThreadUiAccessTest": { "feature": "threading", @@ -68,10 +62,7 @@ }, "BrowserComponentScreenshotTest": { "feature": "embedded-web-content", - "reasons": [ - "failed due to timeout waiting for DONE stage=show-completed" - ], - "status": "fail" + "status": "pass" }, "ButtonThemeScreenshotTest": { "feature": "native-theme-controls", @@ -87,18 +78,15 @@ }, "CameraApiTest": { "feature": "camera-ar-sensors", - "reasons": [ - "failed: Camera.getCameras() returned no cameras" - ], - "status": "fail" + "status": "pass" }, "CenteredDialogTitleScreenshotTest": { "feature": "dialogs-and-labels", - "status": "not-run" + "status": "pass" }, "CenteredInteractionDialogTitleScreenshotTest": { "feature": "dialogs-and-labels", - "status": "not-run" + "status": "pass" }, "ChartBarScreenshotTest": { "feature": "charts", @@ -198,10 +186,7 @@ }, "CryptoApiTest": { "feature": "secure-storage-crypto", - "reasons": [ - "failed: Crypto API test failed: com.codename1.security.CryptoException: Crypto operation secureRandomBytes is not supported on this platform. If you are running in a fresh CodenameOneImplementation subclass, override the matching method." - ], - "status": "fail" + "status": "pass" }, "CssFilterBlurScreenshotTest": { "feature": "theme-palette-css", @@ -277,10 +262,7 @@ }, "FileSystemStorageOpenInputStreamMissingTest": { "feature": "filesystem-storage", - "reasons": [ - "failed: openInputStream returned a stream (com.codename1.impl.linux.LinuxInputStream@7F4C451E78D0) for a missing path /home/runner/.local/share/codenameone/this-file-must-not-exist-1502-1784125008557.bin instead of throwing. Platform=linux" - ], - "status": "fail" + "status": "pass" }, "FillArc": { "feature": "graphics-primitives", @@ -388,7 +370,7 @@ }, "Media360PanoramaScreenshotTest": { "feature": "immersive-media", - "status": "not-run" + "status": "pass" }, "MediaPlaybackScreenshotTest": { "feature": "audio-media-playback", @@ -572,10 +554,7 @@ }, "SurfacesPublishTest": { "feature": "surfaces", - "reasons": [ - "failed: Surfaces publish contract failed: java.lang.UnsupportedOperationException: UnicodeHelper.getClasses() not supported" - ], - "status": "fail" + "status": "pass" }, "SurfacesRasterizerScreenshotTest": { "feature": "surfaces", @@ -627,10 +606,7 @@ }, "TimeApiTest": { "feature": "java-standard-apis", - "reasons": [ - "failed: Time API test failed: java.lang.RuntimeException: Expected [2020-03-08T01:30:00-05:00[America/New_York]], Actual [2020-03-08T11:30:00-05:00[America/New_York]]" - ], - "status": "fail" + "status": "pass" }, "ToastBarTopPositionScreenshotTest": { "feature": "toast-notifications", @@ -666,7 +642,7 @@ }, "VRStereoSceneScreenshotTest": { "feature": "immersive-media", - "status": "not-run" + "status": "pass" }, "ValidatorLightweightPickerScreenshotTest": { "feature": "pickers-validation", @@ -690,7 +666,9 @@ }, "VideoIORoundTripTest": { "feature": "video-io", - "status": "not-run" + "status": "pass" } - } + }, + "bootstrap_source": "successful-master-workflow", + "workflow_conclusion": "success" } diff --git a/docs/website/static/port-status-data/ports/mac-native.json b/docs/website/static/port-status-data/ports/mac-native.json index ec7f899ba62..3716dee79ed 100644 --- a/docs/website/static/port-status-data/ports/mac-native.json +++ b/docs/website/static/port-status-data/ports/mac-native.json @@ -674,5 +674,7 @@ ], "status": "skip" } - } + }, + "bootstrap_source": "successful-master-workflow", + "workflow_conclusion": "success" } diff --git a/docs/website/static/port-status-data/ports/tvos.json b/docs/website/static/port-status-data/ports/tvos.json index 4de926e9b98..eb277612662 100644 --- a/docs/website/static/port-status-data/ports/tvos.json +++ b/docs/website/static/port-status-data/ports/tvos.json @@ -7,8 +7,8 @@ "suite_finished": true, "summary": { "fail": 0, - "not-run": 2, - "pass": 160, + "not-run": 0, + "pass": 162, "skip": 2 }, "tests": { @@ -85,11 +85,11 @@ }, "CenteredDialogTitleScreenshotTest": { "feature": "dialogs-and-labels", - "status": "not-run" + "status": "pass" }, "CenteredInteractionDialogTitleScreenshotTest": { "feature": "dialogs-and-labels", - "status": "not-run" + "status": "pass" }, "ChartBarScreenshotTest": { "feature": "charts", @@ -674,5 +674,7 @@ ], "status": "skip" } - } + }, + "bootstrap_source": "successful-master-workflow", + "workflow_conclusion": "success" } diff --git a/docs/website/static/port-status-data/ports/watchos.json b/docs/website/static/port-status-data/ports/watchos.json index 9607bfb0715..7eacdd8082e 100644 --- a/docs/website/static/port-status-data/ports/watchos.json +++ b/docs/website/static/port-status-data/ports/watchos.json @@ -7,8 +7,8 @@ "suite_finished": true, "summary": { "fail": 0, - "not-run": 2, - "pass": 160, + "not-run": 0, + "pass": 162, "skip": 2 }, "tests": { @@ -85,11 +85,11 @@ }, "CenteredDialogTitleScreenshotTest": { "feature": "dialogs-and-labels", - "status": "not-run" + "status": "pass" }, "CenteredInteractionDialogTitleScreenshotTest": { "feature": "dialogs-and-labels", - "status": "not-run" + "status": "pass" }, "ChartBarScreenshotTest": { "feature": "charts", @@ -674,5 +674,7 @@ ], "status": "skip" } - } + }, + "bootstrap_source": "successful-master-workflow", + "workflow_conclusion": "success" } diff --git a/docs/website/static/port-status-data/ports/windows-x64.json b/docs/website/static/port-status-data/ports/windows-x64.json index 5b577c00ce4..6eb07412943 100644 --- a/docs/website/static/port-status-data/ports/windows-x64.json +++ b/docs/website/static/port-status-data/ports/windows-x64.json @@ -7,18 +7,18 @@ "suite_finished": false, "summary": { "fail": 0, - "not-run": 41, - "pass": 123, + "not-run": 0, + "pass": 164, "skip": 0 }, "tests": { "ARApiTest": { "feature": "camera-ar-sensors", - "status": "not-run" + "status": "pass" }, "AccessibilityTest": { "feature": "accessibility", - "status": "not-run" + "status": "pass" }, "AdsScreenshotTest": { "feature": "ads", @@ -46,19 +46,19 @@ }, "AudioMixerApiTest": { "feature": "audio-media-playback", - "status": "not-run" + "status": "pass" }, "BackgroundThreadUiAccessTest": { "feature": "threading", - "status": "not-run" + "status": "pass" }, "Base64NativePerformanceTest": { "feature": "native-base64", - "status": "not-run" + "status": "pass" }, "BridgeBulkTransferGuardTest": { "feature": "bytecode-runtime", - "status": "not-run" + "status": "pass" }, "BrowserComponentScreenshotTest": { "feature": "embedded-web-content", @@ -70,23 +70,23 @@ }, "BytecodeTranslatorRegressionTest": { "feature": "bytecode-runtime", - "status": "not-run" + "status": "pass" }, "CallDetectionAPITest": { "feature": "device-security-signals", - "status": "not-run" + "status": "pass" }, "CameraApiTest": { "feature": "camera-ar-sensors", - "status": "not-run" + "status": "pass" }, "CenteredDialogTitleScreenshotTest": { "feature": "dialogs-and-labels", - "status": "not-run" + "status": "pass" }, "CenteredInteractionDialogTitleScreenshotTest": { "feature": "dialogs-and-labels", - "status": "not-run" + "status": "pass" }, "ChartBarScreenshotTest": { "feature": "charts", @@ -186,11 +186,11 @@ }, "CryptoApiTest": { "feature": "secure-storage-crypto", - "status": "not-run" + "status": "pass" }, "CssFilterBlurScreenshotTest": { "feature": "theme-palette-css", - "status": "not-run" + "status": "pass" }, "CssGradientsScreenshotTest": { "feature": "theme-palette-css", @@ -206,7 +206,7 @@ }, "DeviceInputApiTest": { "feature": "text-input", - "status": "not-run" + "status": "pass" }, "DialogThemeScreenshotTest": { "feature": "dialogs-and-labels", @@ -262,7 +262,7 @@ }, "FileSystemStorageOpenInputStreamMissingTest": { "feature": "filesystem-storage", - "status": "not-run" + "status": "pass" }, "FillArc": { "feature": "graphics-primitives", @@ -298,7 +298,7 @@ }, "FloatingToStringTest": { "feature": "java-standard-apis", - "status": "not-run" + "status": "pass" }, "GaussianBlur": { "feature": "graphics-gradients-filters", @@ -306,7 +306,7 @@ }, "GoogleWebMapScreenshotTest": { "feature": "native-web-maps", - "status": "not-run" + "status": "pass" }, "Gpu3DAnimationTest": { "feature": "gpu-3d", @@ -330,7 +330,7 @@ }, "InPlaceEditViewTest": { "feature": "text-input", - "status": "not-run" + "status": "pass" }, "InscribedTriangleGrid": { "feature": "graphics-shapes-strokes", @@ -338,11 +338,11 @@ }, "Java17Tests": { "feature": "java-standard-apis", - "status": "not-run" + "status": "pass" }, "KotlinUiTest": { "feature": "application-bootstrap", - "status": "not-run" + "status": "pass" }, "LargeStrokeDirtyClipTest": { "feature": "graphics-clipping", @@ -358,7 +358,7 @@ }, "LocalNotificationOverrideTest": { "feature": "notifications", - "status": "not-run" + "status": "pass" }, "LottieAnimatedScreenshotTest": { "feature": "svg-lottie", @@ -398,7 +398,7 @@ }, "MotionSensorDeviceTest": { "feature": "camera-ar-sensors", - "status": "not-run" + "status": "pass" }, "MotionShowcaseScreenshotTest": { "feature": "layout-animation", @@ -410,15 +410,15 @@ }, "MutableImageClipReadbackTest": { "feature": "mutable-images", - "status": "not-run" + "status": "pass" }, "MutableImageReadbackTest": { "feature": "mutable-images", - "status": "not-run" + "status": "pass" }, "NanoTimeApiTest": { "feature": "java-standard-apis", - "status": "not-run" + "status": "pass" }, "NativeMapFallbackScreenshotTest": { "feature": "vector-maps", @@ -438,7 +438,7 @@ }, "PickerCancelRestoreTest": { "feature": "pickers-validation", - "status": "not-run" + "status": "pass" }, "PickerThemeScreenshotTest": { "feature": "native-theme-controls", @@ -474,7 +474,7 @@ }, "SecureStorageTest": { "feature": "secure-storage-crypto", - "status": "not-run" + "status": "pass" }, "SheetScreenshotTest": { "feature": "sheets", @@ -486,15 +486,15 @@ }, "SimdApiTest": { "feature": "simd", - "status": "not-run" + "status": "pass" }, "SimdBenchmarkTest": { "feature": "simd", - "status": "not-run" + "status": "pass" }, "SimdLargeAllocaTest": { "feature": "simd", - "status": "not-run" + "status": "pass" }, "SlideFadeTitleTransitionTest": { "feature": "slide-cover-transitions", @@ -538,11 +538,11 @@ }, "StreamApiTest": { "feature": "java-standard-apis", - "status": "not-run" + "status": "pass" }, "StringApiTest": { "feature": "java-standard-apis", - "status": "not-run" + "status": "pass" }, "StrokeTest": { "feature": "graphics-shapes-strokes", @@ -550,11 +550,11 @@ }, "SurfacesActionDispatchTest": { "feature": "surfaces", - "status": "not-run" + "status": "pass" }, "SurfacesPublishTest": { "feature": "surfaces", - "status": "not-run" + "status": "pass" }, "SurfacesRasterizerScreenshotTest": { "feature": "surfaces", @@ -562,19 +562,19 @@ }, "SurfacesRemoteViewsScreenshotTest": { "feature": "surfaces", - "status": "not-run" + "status": "pass" }, "SurfacesSerializerRoundTripTest": { "feature": "surfaces", - "status": "not-run" + "status": "pass" }, "SurfacesTimelineLogicTest": { "feature": "surfaces", - "status": "not-run" + "status": "pass" }, "SwitchThemeScreenshotTest": { "feature": "native-theme-controls", - "status": "not-run" + "status": "pass" }, "TabsAnimatedIndicatorScreenshotTest": { "feature": "tabs-animation", @@ -606,7 +606,7 @@ }, "TimeApiTest": { "feature": "java-standard-apis", - "status": "not-run" + "status": "pass" }, "ToastBarTopPositionScreenshotTest": { "feature": "toast-notifications", @@ -638,7 +638,7 @@ }, "VPNDetectionAPITest": { "feature": "device-security-signals", - "status": "not-run" + "status": "pass" }, "VRStereoSceneScreenshotTest": { "feature": "immersive-media", @@ -666,7 +666,9 @@ }, "VideoIORoundTripTest": { "feature": "video-io", - "status": "not-run" + "status": "pass" } - } + }, + "bootstrap_source": "successful-master-workflow", + "workflow_conclusion": "success" } diff --git a/scripts/hellocodenameone/README.adoc b/scripts/hellocodenameone/README.adoc index 08fdc3d207f..257bba6c35b 100644 --- a/scripts/hellocodenameone/README.adoc +++ b/scripts/hellocodenameone/README.adoc @@ -58,6 +58,9 @@ for each port. Port workflows update their reports independently on the ports that did not run. The checked-in reports under `docs/website/static/port-status-data/ports` are the initial snapshot only; the page uses one of them only until that port has its first published report. +Those bootstrap reports use the successful master workflow conclusion because +the older artifacts did not consistently retain per-test completion logs. New +reports use the normalized suite and screenshot results directly. The feature contract lives in `docs/website/data/port_status.json`. Every test registered in diff --git a/scripts/hellocodenameone/conformance/port_status.py b/scripts/hellocodenameone/conformance/port_status.py index 53ce7692ad5..0194cc831c0 100755 --- a/scripts/hellocodenameone/conformance/port_status.py +++ b/scripts/hellocodenameone/conformance/port_status.py @@ -168,6 +168,10 @@ def validate(manifest: dict) -> dict: problems.append(f"Seed report {seed_path} has the wrong schema version") if seed.get("port") != port_id: problems.append(f"Seed report {seed_path} identifies port {seed.get('port')}") + if seed.get("bootstrap_source") != "successful-master-workflow": + problems.append(f"Seed report {seed_path} has no successful-workflow provenance") + if seed.get("workflow_conclusion") != "success": + problems.append(f"Seed report {seed_path} did not come from a successful workflow") seed_tests = seed.get("tests") if not isinstance(seed_tests, dict): problems.append(f"Seed report {seed_path} has no test result map") @@ -184,6 +188,15 @@ def validate(manifest: dict) -> dict: f"Seed report {seed_path} is missing tests: " + ", ".join(missing_tests) ) + failing_tests = sorted( + test for test, result in seed_tests.items() + if result.get("status") == "fail" + ) + if failing_tests: + problems.append( + f"Successful-workflow seed report {seed_path} contains failures: " + + ", ".join(failing_tests) + ) if problems: raise ContractError("\n".join(problems)) From afc475707cd0f2edbb35fae0021a6793f3138ec9 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 16 Jul 2026 07:06:05 +0300 Subject: [PATCH 05/21] Gate port status website output --- .github/workflows/website-docs.yml | 5 + docs/website/content/port-status.md | 2 +- .../website/layouts/_default/port-status.html | 15 +- scripts/website/validate_port_status.mjs | 165 ++++++++++++++++++ 4 files changed, 177 insertions(+), 10 deletions(-) create mode 100644 scripts/website/validate_port_status.mjs diff --git a/.github/workflows/website-docs.yml b/.github/workflows/website-docs.yml index 6dc723ad448..1bc39cc2bc9 100644 --- a/.github/workflows/website-docs.yml +++ b/.github/workflows/website-docs.yml @@ -147,6 +147,11 @@ jobs: CN1_USER: ${{ secrets.CN1_USER }} CN1_TOKEN: ${{ secrets.CN1_TOKEN }} + - name: Validate Port Status page output + run: | + set -euo pipefail + node scripts/website/validate_port_status.mjs docs/website/public + - name: Validate Initializr page output run: | set -euo pipefail diff --git a/docs/website/content/port-status.md b/docs/website/content/port-status.md index 78236d9818a..d2026d488b6 100644 --- a/docs/website/content/port-status.md +++ b/docs/website/content/port-status.md @@ -3,6 +3,6 @@ title: "Port Status" slug: "port-status" url: "/port-status/" layout: "port-status" -description: "Current Codename One port conformance, generated from the HelloCodenameOne test suite." +description: "Current Codename One port compliance, generated from the automated compliance test suite." hideMeta: true --- diff --git a/docs/website/layouts/_default/port-status.html b/docs/website/layouts/_default/port-status.html index 35a5e9ca877..2d275ba8fe7 100644 --- a/docs/website/layouts/_default/port-status.html +++ b/docs/website/layouts/_default/port-status.html @@ -3,14 +3,13 @@

{{ partial "breadcrumbs.html" . }} -

Generated conformance report

+

Automated compliance report

{{ .Title }}

- Every row is backed by one or more tests in the - HelloCodenameOne suite. + Every row is backed by one or more tests in the Codename One compliance test suite. A check means every mapped test is successful in the latest available master report for that port.

-
+
{{ len $contract.features }} features {{- $testCount := 0 -}} {{- range $contract.features -}}{{- $testCount = add $testCount (len .tests) -}}{{- end -}} @@ -20,7 +19,7 @@

{{ .Title }}

- Loading the latest conformance reports from GitHub… + Loading the latest compliance reports from GitHub…
@@ -61,7 +60,7 @@

{{ .name }}

-
+
@@ -107,9 +106,7 @@

How to read this page

A website build does not wait for port workflows. The initial snapshot uses the successful workflow conclusion from the last master runs available when this page was added because those older artifacts did not all retain per-test completion logs. Each port replaces that bootstrap snapshot after a newer master run. A platform-specific skip is not a pass. An incomplete current report is not a pass. Reports older than {{ $contract.stale_after_days }} days are marked stale.

- Feature contract - - Validator and result normalizer + Compliance feature contract

diff --git a/scripts/website/validate_port_status.mjs b/scripts/website/validate_port_status.mjs new file mode 100644 index 00000000000..a1ac42baab7 --- /dev/null +++ b/scripts/website/validate_port_status.mjs @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Codename One designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Codename One through http://www.codenameone.com/ if you + * need additional information or have any questions. + */ + +import fs from "node:fs"; +import path from "node:path"; +import vm from "node:vm"; + +const publicDirectory = path.resolve(process.argv[2] || "docs/website/public"); + +function fail(message) { + throw new Error(`Port Status regression: ${message}`); +} + +function read(relativePath) { + const file = path.join(publicDirectory, relativePath); + if (!fs.existsSync(file) || !fs.statSync(file).isFile()) { + fail(`missing generated file ${relativePath}`); + } + return fs.readFileSync(file, "utf8"); +} + +function countMatches(value, pattern) { + return Array.from(value.matchAll(pattern)).length; +} + +function validate() { + const home = read("index.html"); + const page = read(path.join("port-status", "index.html")); + + if (!/]*href=(?:["']?\/port-status\/["']?)[^>]*>[\s\S]*?PORT STATUS[\s\S]*?<\/a>/i.test(home)) { + fail("the main site navigation does not link to /port-status/"); + } + + const pageText = page.replace(/<[^>]+>/g, " ").replace(/\s+/g, " "); + if (!/Codename One compliance test suite/i.test(pageText)) { + fail("the page does not identify the compliance test suite"); + } + if (/HelloCodenameOne/i.test(pageText)) { + fail("the public page exposes the internal HelloCodenameOne fixture name"); + } + if (/port_status\.py/i.test(page)) { + fail("the public page links to the result-normalizer implementation"); + } + + const contractMatch = page.match( + /]*\bdata-port-status-contract\b)[^>]*>([\s\S]*?)<\/script>/i + ); + if (!contractMatch) { + fail("the generated page does not embed its compliance contract"); + } + + let contract; + try { + contract = JSON.parse(contractMatch[1]); + } catch (error) { + fail(`the embedded compliance contract is invalid JSON: ${error.message}`); + } + if (!contract || typeof contract !== "object" || Array.isArray(contract)) { + fail("the embedded compliance contract was serialized as a string"); + } + if (!Array.isArray(contract.ports) || contract.ports.length !== 10) { + fail("the contract must contain the 10 portability targets"); + } + if (contract.ports.some((port) => port.id === "javase")) { + fail("JavaSE must not appear as a portability target"); + } + if (!Array.isArray(contract.features) || contract.features.length < 49) { + fail("the compliance feature map lost required rows"); + } + + const mappedTests = new Set(); + for (const feature of contract.features) { + if (!Array.isArray(feature.tests) || feature.tests.length === 0) { + fail(`feature ${feature.id || ""} has no mapped tests`); + } + for (const test of feature.tests) { + if (mappedTests.has(test)) { + fail(`test ${test} is mapped more than once`); + } + mappedTests.add(test); + } + } + if (mappedTests.size < 164) { + fail("the compliance contract lost mapped tests"); + } + + const portCards = countMatches(page, /\bdata-port-card(?:=|\s|>)/g); + const featureRows = countMatches(page, /\bdata-feature-row(?:=|\s|>)/g); + const featureCells = countMatches(page, /\bdata-feature-cell(?:=|\s|>)/g); + if (portCards !== contract.ports.length) { + fail(`generated ${portCards} port cards for ${contract.ports.length} ports`); + } + if (featureRows !== contract.features.length) { + fail(`generated ${featureRows} feature rows for ${contract.features.length} features`); + } + if (featureCells !== contract.ports.length * contract.features.length) { + fail("the generated compliance matrix is incomplete"); + } + + if (contract.seed_report_base !== "/port-status-data/ports/") { + fail("the initial master-result fallback is not configured"); + } + for (const port of contract.ports) { + const report = JSON.parse(read(path.join("port-status-data", "ports", `${port.id}.json`))); + if (report.port !== port.id || report.schema_version !== contract.schema_version) { + fail(`seed report ${port.id} does not match the compliance contract`); + } + if (report.workflow_conclusion !== "success" || report.summary?.fail !== 0) { + fail(`seed report ${port.id} is not based on a successful master workflow`); + } + const reportTests = Object.keys(report.tests || {}); + if (reportTests.length !== mappedTests.size || reportTests.some((test) => !mappedTests.has(test))) { + fail(`seed report ${port.id} does not cover every mapped test`); + } + } + + const assetMatch = page.match( + /]*src=(?:["']([^"']*cn1-port-status[^"']*\.js)["']|([^\s>]*cn1-port-status[^\s>]*\.js))[^>]*><\/script>/i + ); + if (!assetMatch) { + fail("the generated page does not load the Port Status JavaScript"); + } + const assetPath = (assetMatch[1] || assetMatch[2]).replace(/^\//, ""); + const script = read(assetPath); + try { + new vm.Script(script, {filename: assetPath}); + } catch (error) { + fail(`the generated Port Status JavaScript is invalid: ${error.message}`); + } + if (!script.includes("seed_report_base") || !script.includes("successful-master-workflow")) { + fail("the generated JavaScript lost master-result fallback handling"); + } + + console.log( + `Port Status page valid: ${contract.ports.length} ports, ` + + `${contract.features.length} features, ${mappedTests.size} mapped tests.` + ); +} + +try { + validate(); +} catch (error) { + console.error(error.message); + process.exit(1); +} From fe81b02e5ad20ff72f5817fd4b01a5937fcb1eb2 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 16 Jul 2026 08:57:32 +0300 Subject: [PATCH 06/21] Render port status as static snapshot --- .github/workflows/port-status-contract.yml | 4 +- .github/workflows/port-status-publish.yml | 7 +- .github/workflows/website-docs.yml | 4 + .../assets/css/extended/cn1-port-status.css | 5 + docs/website/assets/js/cn1-port-status.js | 220 +----------------- docs/website/data/port_status.json | 34 ++- .../port_status_reports}/android.json | 10 +- .../port_status_reports}/ios-gl.json | 10 +- .../port_status_reports}/ios-metal.json | 10 +- .../port_status_reports}/javascript.json | 10 +- .../port_status_reports}/linux-arm64.json | 10 +- .../port_status_reports}/linux-x64.json | 10 +- .../port_status_reports}/mac-native.json | 10 +- .../port_status_reports}/tvos.json | 10 +- .../port_status_reports}/watchos.json | 10 +- .../port_status_reports}/windows-x64.json | 10 +- .../website/layouts/_default/port-status.html | 29 +-- .../partials/port-status-feature-status.html | 63 +++++ .../partials/port-status-port-state.html | 38 +++ scripts/hellocodenameone/README.adoc | 17 +- .../conformance/port_status.py | 45 ++-- .../conformance/publish_port_status.sh | 8 +- .../conformance/test_port_status.py | 7 +- scripts/website/build.sh | 8 +- scripts/website/sync_port_status_reports.sh | 71 ++++++ scripts/website/validate_port_status.mjs | 117 +++++----- 26 files changed, 383 insertions(+), 394 deletions(-) rename docs/website/{static/port-status-data/ports => data/port_status_reports}/android.json (98%) rename docs/website/{static/port-status-data/ports => data/port_status_reports}/ios-gl.json (98%) rename docs/website/{static/port-status-data/ports => data/port_status_reports}/ios-metal.json (98%) rename docs/website/{static/port-status-data/ports => data/port_status_reports}/javascript.json (98%) rename docs/website/{static/port-status-data/ports => data/port_status_reports}/linux-arm64.json (98%) rename docs/website/{static/port-status-data/ports => data/port_status_reports}/linux-x64.json (98%) rename docs/website/{static/port-status-data/ports => data/port_status_reports}/mac-native.json (98%) rename docs/website/{static/port-status-data/ports => data/port_status_reports}/tvos.json (98%) rename docs/website/{static/port-status-data/ports => data/port_status_reports}/watchos.json (98%) rename docs/website/{static/port-status-data/ports => data/port_status_reports}/windows-x64.json (98%) create mode 100644 docs/website/layouts/partials/port-status-feature-status.html create mode 100644 docs/website/layouts/partials/port-status-port-state.html create mode 100755 scripts/website/sync_port_status_reports.sh diff --git a/.github/workflows/port-status-contract.yml b/.github/workflows/port-status-contract.yml index fff5717623d..f7aa4a4d5d8 100644 --- a/.github/workflows/port-status-contract.yml +++ b/.github/workflows/port-status-contract.yml @@ -5,7 +5,7 @@ on: paths: - '.github/workflows/port-status-contract.yml' - 'docs/website/data/port_status.json' - - 'docs/website/static/port-status-data/ports/**' + - 'docs/website/data/port_status_reports/**' - 'scripts/hellocodenameone/common/src/main/**' - 'scripts/hellocodenameone/conformance/**' - 'scripts/android/screenshots/**' @@ -23,7 +23,7 @@ on: paths: - '.github/workflows/port-status-contract.yml' - 'docs/website/data/port_status.json' - - 'docs/website/static/port-status-data/ports/**' + - 'docs/website/data/port_status_reports/**' - 'scripts/hellocodenameone/common/src/main/**' - 'scripts/hellocodenameone/conformance/**' - 'scripts/android/screenshots/**' diff --git a/.github/workflows/port-status-publish.yml b/.github/workflows/port-status-publish.yml index 3b83605d9f4..e7e47c93f8b 100644 --- a/.github/workflows/port-status-publish.yml +++ b/.github/workflows/port-status-publish.yml @@ -12,7 +12,7 @@ on: types: [completed] permissions: - actions: read + actions: write contents: write jobs: @@ -48,3 +48,8 @@ jobs: echo "No normalized port reports were found in workflow artifacts." >&2 exit 1 fi + + - name: Rebuild the static Port Status snapshot + env: + GH_TOKEN: ${{ github.token }} + run: gh workflow run website-docs.yml --ref master diff --git a/.github/workflows/website-docs.yml b/.github/workflows/website-docs.yml index 1bc39cc2bc9..2b0f8c0bec6 100644 --- a/.github/workflows/website-docs.yml +++ b/.github/workflows/website-docs.yml @@ -139,6 +139,10 @@ jobs: # than the pinned release. Bootstrap the local snapshot artifacts so # the initializr (and the other site apps) build against repo HEAD. WEBSITE_BOOTSTRAP_CN1_SNAPSHOTS: "true" + # Resolve the latest persisted master result for each port before + # Hugo writes the static status table. Checked-in reports remain the + # fallback if the data branch is temporarily unavailable. + WEBSITE_REFRESH_PORT_STATUS: "true" # PR previews build with future-dated posts visible so reviewers # can read posts staged for later in the week. Production deploys # (push to master) keep the default so future posts only appear diff --git a/docs/website/assets/css/extended/cn1-port-status.css b/docs/website/assets/css/extended/cn1-port-status.css index 5fa205fcca4..ca2fc7a8c9f 100644 --- a/docs/website/assets/css/extended/cn1-port-status.css +++ b/docs/website/assets/css/extended/cn1-port-status.css @@ -188,7 +188,11 @@ .cn1-port-status__matrix { border: 1px solid var(--cn1-status-border); border-radius: 12px; + max-height: min(78vh, 920px); + overscroll-behavior: contain; overflow: auto; + position: relative; + scrollbar-gutter: stable; } .cn1-port-status__matrix table { @@ -209,6 +213,7 @@ .cn1-port-status__matrix thead th { background: var(--entry); + box-shadow: 0 1px 0 var(--cn1-status-border); font-size: .72rem; position: sticky; text-align: center; diff --git a/docs/website/assets/js/cn1-port-status.js b/docs/website/assets/js/cn1-port-status.js index 8628bc6a161..b40a52595e6 100644 --- a/docs/website/assets/js/cn1-port-status.js +++ b/docs/website/assets/js/cn1-port-status.js @@ -29,215 +29,19 @@ return; } - var contractElement = root.querySelector("[data-port-status-contract]"); - var notice = root.querySelector("[data-port-status-notice]"); - var contract; - try { - contract = JSON.parse(contractElement.textContent); - } catch (error) { - notice.textContent = "The port-status contract could not be loaded."; - notice.classList.add("is-error"); - return; - } - - var reports = {}; - var reportSources = {}; - var reportBase = "https://raw.githubusercontent.com/codenameone/CodenameOne/" + - contract.report_branch + "/ports/"; - var seedReportBase = contract.seed_report_base || ""; - - function daysOld(value) { - var timestamp = Date.parse(value || ""); - if (Number.isNaN(timestamp)) { - return Infinity; - } - return (Date.now() - timestamp) / 86400000; - } - - function isSuccessfulBootstrap(report) { - return report.bootstrap_source === "successful-master-workflow" && - report.workflow_conclusion === "success"; - } - - function reportCompleted(report) { - return report.suite_finished || isSuccessfulBootstrap(report); - } - - function featureStatus(feature, report) { - if (!report) { - return {state: "unknown", label: "No current report", tests: []}; - } - var stale = daysOld(report.generated_at) > contract.stale_after_days; - var results = feature.tests.map(function (name) { - var result = report.tests && report.tests[name]; - return {name: name, status: result ? result.status : "not-run"}; + var category = root.querySelector("[data-category-filter]"); + var search = root.querySelector("[data-feature-search]"); + + function applyFilters() { + var categoryValue = category.value; + var query = search.value.trim().toLowerCase(); + root.querySelectorAll("[data-feature-row]").forEach(function (row) { + var categoryMatches = !categoryValue || row.dataset.category === categoryValue; + var searchMatches = !query || row.dataset.search.indexOf(query) !== -1; + row.hidden = !(categoryMatches && searchMatches); }); - var failed = results.filter(function (item) { return item.status === "fail"; }); - var passed = results.filter(function (item) { return item.status === "pass"; }); - var skipped = results.filter(function (item) { return item.status === "skip"; }); - var notRun = results.filter(function (item) { return item.status === "not-run"; }); - var state; - var label; - - if (failed.length) { - state = "fail"; - label = failed.length + " failed: " + failed.map(function (item) { return item.name; }).join(", "); - } else if (!reportCompleted(report)) { - state = "partial"; - label = "Suite did not finish"; - } else if (passed.length === results.length) { - state = "pass"; - label = "All " + results.length + " mapped test" + (results.length === 1 ? "" : "s") + " passed"; - } else if (skipped.length === results.length) { - state = "partial"; - label = "All mapped tests skipped"; - } else { - state = "partial"; - label = passed.length + " passed, " + skipped.length + " skipped, " + notRun.length + " not run"; - } - if (stale) { - state = state === "fail" ? "fail" : "stale"; - label = "Stale report. " + label; - } - return {state: state, label: label, tests: results}; - } - - function markFor(state) { - if (state === "pass") { return "✓"; } - if (state === "fail") { return "×"; } - if (state === "partial") { return "−"; } - if (state === "stale") { return "!"; } - return "?"; - } - - function updateCell(cell, status) { - cell.className = "is-" + status.state; - cell.title = status.label; - var mark = cell.querySelector(".cn1-port-status__mark"); - mark.className = "cn1-port-status__mark is-" + status.state; - mark.textContent = markFor(status.state); - cell.querySelector("[data-status-label]").textContent = status.label; - } - - function formatDate(value) { - var date = new Date(value); - if (Number.isNaN(date.getTime())) { - return "Unknown run time"; - } - return date.toLocaleString(undefined, {dateStyle: "medium", timeStyle: "short"}); - } - - function updatePort(port, report) { - var card = root.querySelector('[data-port-card="' + port.id + '"]'); - var state = card.querySelector("[data-port-state]"); - var meta = card.querySelector("[data-port-meta]"); - if (!report) { - state.textContent = port.report_pending ? "Detailed reporting pending" : "No published report"; - card.classList.add("is-unknown"); - return; - } - var summary = report.summary || {}; - var stale = daysOld(report.generated_at) > contract.stale_after_days; - var failed = summary.fail || 0; - var unfinished = !reportCompleted(report); - card.classList.add(failed ? "is-fail" : (stale || unfinished ? "is-partial" : "is-pass")); - state.textContent = failed ? failed + " failing tests" : - (unfinished ? "Run incomplete" : - (stale ? "Report is stale" : - (isSuccessfulBootstrap(report) ? "Workflow completed" : "Suite completed"))); - var detail = (summary.pass || 0) + " passed · " + (summary.skip || 0) + " skipped · " + (summary["not-run"] || 0) + " not run"; - meta.replaceChildren(document.createTextNode(formatDate(report.generated_at)), document.createElement("br"), document.createTextNode(detail)); - if (report.run_url) { - var separator = document.createTextNode(" · "); - var link = document.createElement("a"); - link.href = report.run_url; - link.target = "_blank"; - link.rel = "noopener"; - link.textContent = "Open run"; - meta.append(separator, link); - } - } - - function render() { - contract.features.forEach(function (feature) { - contract.ports.forEach(function (port) { - var cell = root.querySelector('[data-feature-cell][data-port="' + port.id + '"][data-feature="' + feature.id + '"]'); - updateCell(cell, featureStatus(feature, reports[port.id])); - }); - }); - contract.ports.forEach(function (port) { - updatePort(port, reports[port.id]); - }); - } - - function fetchReport(url) { - return fetch(url, {cache: "no-store"}) - .then(function (response) { - if (!response.ok) { - throw new Error("HTTP " + response.status); - } - return response.json(); - }) - .then(function (report) { - return report; - }); - } - - function acceptReport(port, report, source) { - if (report.port !== port.id || report.schema_version !== contract.schema_version) { - throw new Error("Report contract mismatch"); - } - reports[port.id] = report; - reportSources[port.id] = source; - } - - function loadPort(port) { - var fileName = encodeURIComponent(port.id) + ".json"; - return fetchReport(reportBase + fileName) - .then(function (report) { - acceptReport(port, report, "published"); - }) - .catch(function () { - if (!seedReportBase) { - throw new Error("No seed report base configured"); - } - return fetchReport(seedReportBase + fileName).then(function (report) { - acceptReport(port, report, "seed"); - }); - }) - .catch(function () { - reports[port.id] = null; - }); - } - - function installFilters() { - var category = root.querySelector("[data-category-filter]"); - var search = root.querySelector("[data-feature-search]"); - function apply() { - var categoryValue = category.value; - var query = search.value.trim().toLowerCase(); - root.querySelectorAll("[data-feature-row]").forEach(function (row) { - var categoryMatches = !categoryValue || row.dataset.category === categoryValue; - var searchMatches = !query || row.dataset.search.indexOf(query) !== -1; - row.hidden = !(categoryMatches && searchMatches); - }); - } - category.addEventListener("change", apply); - search.addEventListener("input", apply); } - installFilters(); - Promise.all(contract.ports.map(loadPort)).then(function () { - render(); - var loaded = Object.keys(reports).filter(function (id) { return reports[id]; }).length; - var seeded = Object.keys(reportSources).filter(function (id) { return reportSources[id] === "seed"; }).length; - if (loaded) { - notice.textContent = "Showing the latest available master results for " + loaded + - " port target" + (loaded === 1 ? "" : "s") + "." + - (seeded ? " " + seeded + " use the initial master snapshot until that port publishes a newer run." : ""); - } else { - notice.textContent = "No master port reports are available."; - } - notice.classList.toggle("is-error", loaded === 0); - }); + category.addEventListener("change", applyFilters); + search.addEventListener("input", applyFilters); }()); diff --git a/docs/website/data/port_status.json b/docs/website/data/port_status.json index ddea8946ea2..a7c76669afb 100644 --- a/docs/website/data/port_status.json +++ b/docs/website/data/port_status.json @@ -1,8 +1,6 @@ { "schema_version": 1, - "report_branch": "port-status-data", - "seed_report_base": "/port-status-data/ports/", - "seed_report_directory": "docs/website/static/port-status-data/ports", + "report_directory": "docs/website/data/port_status_reports", "stale_after_days": 14, "golden_directories": [ "scripts/android/screenshots", @@ -338,11 +336,18 @@ "tests": ["AccessibilityTest"] }, { - "id": "camera-ar-sensors", + "id": "ar-motion-sensors", "category": "Device APIs", - "name": "Camera, AR, and motion sensors", - "description": "Checks camera, augmented-reality, and motion-sensor APIs when available.", - "tests": ["ARApiTest", "CameraApiTest", "MotionSensorDeviceTest"] + "name": "AR and motion sensors", + "description": "Checks augmented-reality and motion-sensor APIs.", + "tests": ["ARApiTest", "MotionSensorDeviceTest"] + }, + { + "id": "camera-access", + "category": "Platform-dependent APIs", + "name": "Camera access", + "description": "Checks camera discovery and capture where hardware and runtime permissions are available.", + "tests": ["CameraApiTest"] }, { "id": "mutable-images", @@ -359,11 +364,18 @@ "tests": ["DesktopModeScreenshotTest"] }, { - "id": "video-io", + "id": "video-decoding", "category": "Media and graphics", - "name": "Video decoding and round trip", - "description": "Checks decoded frames and end-to-end video encode/decode behavior.", - "tests": ["VideoIODecodedFramesScreenshotTest", "VideoIORoundTripTest"] + "name": "Video frame decoding", + "description": "Checks decoded video frames.", + "tests": ["VideoIODecodedFramesScreenshotTest"] + }, + { + "id": "video-round-trip", + "category": "Platform-dependent APIs", + "name": "Video encode/decode round trip", + "description": "Checks end-to-end video encoding and decoding where the platform provides an encoder.", + "tests": ["VideoIORoundTripTest"] }, { "id": "immersive-media", diff --git a/docs/website/static/port-status-data/ports/android.json b/docs/website/data/port_status_reports/android.json similarity index 98% rename from docs/website/static/port-status-data/ports/android.json rename to docs/website/data/port_status_reports/android.json index 031441d60f6..0dc0eaeb9e4 100644 --- a/docs/website/static/port-status-data/ports/android.json +++ b/docs/website/data/port_status_reports/android.json @@ -13,7 +13,7 @@ }, "tests": { "ARApiTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "AccessibilityTest": { @@ -77,7 +77,7 @@ "status": "pass" }, "CameraApiTest": { - "feature": "camera-ar-sensors", + "feature": "camera-access", "reasons": [ "needs-runtime-permission-on-and" ], @@ -400,7 +400,7 @@ "status": "pass" }, "MotionSensorDeviceTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "MotionShowcaseScreenshotTest": { @@ -664,11 +664,11 @@ "status": "pass" }, "VideoIODecodedFramesScreenshotTest": { - "feature": "video-io", + "feature": "video-decoding", "status": "pass" }, "VideoIORoundTripTest": { - "feature": "video-io", + "feature": "video-round-trip", "status": "pass" } }, diff --git a/docs/website/static/port-status-data/ports/ios-gl.json b/docs/website/data/port_status_reports/ios-gl.json similarity index 98% rename from docs/website/static/port-status-data/ports/ios-gl.json rename to docs/website/data/port_status_reports/ios-gl.json index e0665845694..4d02f4dd7a0 100644 --- a/docs/website/static/port-status-data/ports/ios-gl.json +++ b/docs/website/data/port_status_reports/ios-gl.json @@ -13,7 +13,7 @@ }, "tests": { "ARApiTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "AccessibilityTest": { @@ -77,7 +77,7 @@ "status": "pass" }, "CameraApiTest": { - "feature": "camera-ar-sensors", + "feature": "camera-access", "reasons": [ "needs-runtime-permission-on-ios" ], @@ -400,7 +400,7 @@ "status": "pass" }, "MotionSensorDeviceTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "MotionShowcaseScreenshotTest": { @@ -664,11 +664,11 @@ "status": "pass" }, "VideoIODecodedFramesScreenshotTest": { - "feature": "video-io", + "feature": "video-decoding", "status": "pass" }, "VideoIORoundTripTest": { - "feature": "video-io", + "feature": "video-round-trip", "reasons": [ "encode-unavailable-on-ios:Failed" ], diff --git a/docs/website/static/port-status-data/ports/ios-metal.json b/docs/website/data/port_status_reports/ios-metal.json similarity index 98% rename from docs/website/static/port-status-data/ports/ios-metal.json rename to docs/website/data/port_status_reports/ios-metal.json index 6abc8e30d1d..5cfe72f4479 100644 --- a/docs/website/static/port-status-data/ports/ios-metal.json +++ b/docs/website/data/port_status_reports/ios-metal.json @@ -13,7 +13,7 @@ }, "tests": { "ARApiTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "AccessibilityTest": { @@ -77,7 +77,7 @@ "status": "pass" }, "CameraApiTest": { - "feature": "camera-ar-sensors", + "feature": "camera-access", "reasons": [ "needs-runtime-permission-on-ios" ], @@ -400,7 +400,7 @@ "status": "pass" }, "MotionSensorDeviceTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "MotionShowcaseScreenshotTest": { @@ -664,11 +664,11 @@ "status": "pass" }, "VideoIODecodedFramesScreenshotTest": { - "feature": "video-io", + "feature": "video-decoding", "status": "pass" }, "VideoIORoundTripTest": { - "feature": "video-io", + "feature": "video-round-trip", "reasons": [ "encode-unavailable-on-ios:Failed" ], diff --git a/docs/website/static/port-status-data/ports/javascript.json b/docs/website/data/port_status_reports/javascript.json similarity index 98% rename from docs/website/static/port-status-data/ports/javascript.json rename to docs/website/data/port_status_reports/javascript.json index fab15536b34..f6d5d7a422e 100644 --- a/docs/website/static/port-status-data/ports/javascript.json +++ b/docs/website/data/port_status_reports/javascript.json @@ -13,7 +13,7 @@ }, "tests": { "ARApiTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "AccessibilityTest": { @@ -77,7 +77,7 @@ "status": "pass" }, "CameraApiTest": { - "feature": "camera-ar-sensors", + "feature": "camera-access", "reasons": [ "needs-runtime-permission-on-HTML5" ], @@ -400,7 +400,7 @@ "status": "pass" }, "MotionSensorDeviceTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "MotionShowcaseScreenshotTest": { @@ -664,11 +664,11 @@ "status": "pass" }, "VideoIODecodedFramesScreenshotTest": { - "feature": "video-io", + "feature": "video-decoding", "status": "pass" }, "VideoIORoundTripTest": { - "feature": "video-io", + "feature": "video-round-trip", "status": "pass" } }, diff --git a/docs/website/static/port-status-data/ports/linux-arm64.json b/docs/website/data/port_status_reports/linux-arm64.json similarity index 98% rename from docs/website/static/port-status-data/ports/linux-arm64.json rename to docs/website/data/port_status_reports/linux-arm64.json index 2a04109adb2..6461e19b420 100644 --- a/docs/website/static/port-status-data/ports/linux-arm64.json +++ b/docs/website/data/port_status_reports/linux-arm64.json @@ -13,7 +13,7 @@ }, "tests": { "ARApiTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "AccessibilityTest": { @@ -77,7 +77,7 @@ "status": "pass" }, "CameraApiTest": { - "feature": "camera-ar-sensors", + "feature": "camera-access", "status": "pass" }, "CenteredDialogTitleScreenshotTest": { @@ -397,7 +397,7 @@ "status": "pass" }, "MotionSensorDeviceTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "MotionShowcaseScreenshotTest": { @@ -661,11 +661,11 @@ "status": "pass" }, "VideoIODecodedFramesScreenshotTest": { - "feature": "video-io", + "feature": "video-decoding", "status": "pass" }, "VideoIORoundTripTest": { - "feature": "video-io", + "feature": "video-round-trip", "status": "pass" } }, diff --git a/docs/website/static/port-status-data/ports/linux-x64.json b/docs/website/data/port_status_reports/linux-x64.json similarity index 98% rename from docs/website/static/port-status-data/ports/linux-x64.json rename to docs/website/data/port_status_reports/linux-x64.json index 0da1e861f6f..53b93d548fc 100644 --- a/docs/website/static/port-status-data/ports/linux-x64.json +++ b/docs/website/data/port_status_reports/linux-x64.json @@ -13,7 +13,7 @@ }, "tests": { "ARApiTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "AccessibilityTest": { @@ -77,7 +77,7 @@ "status": "pass" }, "CameraApiTest": { - "feature": "camera-ar-sensors", + "feature": "camera-access", "status": "pass" }, "CenteredDialogTitleScreenshotTest": { @@ -397,7 +397,7 @@ "status": "pass" }, "MotionSensorDeviceTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "MotionShowcaseScreenshotTest": { @@ -661,11 +661,11 @@ "status": "pass" }, "VideoIODecodedFramesScreenshotTest": { - "feature": "video-io", + "feature": "video-decoding", "status": "pass" }, "VideoIORoundTripTest": { - "feature": "video-io", + "feature": "video-round-trip", "status": "pass" } }, diff --git a/docs/website/static/port-status-data/ports/mac-native.json b/docs/website/data/port_status_reports/mac-native.json similarity index 98% rename from docs/website/static/port-status-data/ports/mac-native.json rename to docs/website/data/port_status_reports/mac-native.json index 3716dee79ed..49fbe6a9676 100644 --- a/docs/website/static/port-status-data/ports/mac-native.json +++ b/docs/website/data/port_status_reports/mac-native.json @@ -13,7 +13,7 @@ }, "tests": { "ARApiTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "AccessibilityTest": { @@ -77,7 +77,7 @@ "status": "pass" }, "CameraApiTest": { - "feature": "camera-ar-sensors", + "feature": "camera-access", "reasons": [ "needs-runtime-permission-on-ios" ], @@ -400,7 +400,7 @@ "status": "pass" }, "MotionSensorDeviceTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "MotionShowcaseScreenshotTest": { @@ -664,11 +664,11 @@ "status": "pass" }, "VideoIODecodedFramesScreenshotTest": { - "feature": "video-io", + "feature": "video-decoding", "status": "pass" }, "VideoIORoundTripTest": { - "feature": "video-io", + "feature": "video-round-trip", "reasons": [ "encode-unavailable-on-ios:Failed" ], diff --git a/docs/website/static/port-status-data/ports/tvos.json b/docs/website/data/port_status_reports/tvos.json similarity index 98% rename from docs/website/static/port-status-data/ports/tvos.json rename to docs/website/data/port_status_reports/tvos.json index eb277612662..777e51defea 100644 --- a/docs/website/static/port-status-data/ports/tvos.json +++ b/docs/website/data/port_status_reports/tvos.json @@ -13,7 +13,7 @@ }, "tests": { "ARApiTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "AccessibilityTest": { @@ -77,7 +77,7 @@ "status": "pass" }, "CameraApiTest": { - "feature": "camera-ar-sensors", + "feature": "camera-access", "reasons": [ "needs-runtime-permission-on-ios" ], @@ -400,7 +400,7 @@ "status": "pass" }, "MotionSensorDeviceTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "MotionShowcaseScreenshotTest": { @@ -664,11 +664,11 @@ "status": "pass" }, "VideoIODecodedFramesScreenshotTest": { - "feature": "video-io", + "feature": "video-decoding", "status": "pass" }, "VideoIORoundTripTest": { - "feature": "video-io", + "feature": "video-round-trip", "reasons": [ "VideoIO-unsupported-on-ios" ], diff --git a/docs/website/static/port-status-data/ports/watchos.json b/docs/website/data/port_status_reports/watchos.json similarity index 98% rename from docs/website/static/port-status-data/ports/watchos.json rename to docs/website/data/port_status_reports/watchos.json index 7eacdd8082e..9dbc9a21069 100644 --- a/docs/website/static/port-status-data/ports/watchos.json +++ b/docs/website/data/port_status_reports/watchos.json @@ -13,7 +13,7 @@ }, "tests": { "ARApiTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "AccessibilityTest": { @@ -77,7 +77,7 @@ "status": "pass" }, "CameraApiTest": { - "feature": "camera-ar-sensors", + "feature": "camera-access", "reasons": [ "needs-runtime-permission-on-ios" ], @@ -400,7 +400,7 @@ "status": "pass" }, "MotionSensorDeviceTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "MotionShowcaseScreenshotTest": { @@ -664,11 +664,11 @@ "status": "pass" }, "VideoIODecodedFramesScreenshotTest": { - "feature": "video-io", + "feature": "video-decoding", "status": "pass" }, "VideoIORoundTripTest": { - "feature": "video-io", + "feature": "video-round-trip", "reasons": [ "VideoIO-unsupported-on-ios" ], diff --git a/docs/website/static/port-status-data/ports/windows-x64.json b/docs/website/data/port_status_reports/windows-x64.json similarity index 98% rename from docs/website/static/port-status-data/ports/windows-x64.json rename to docs/website/data/port_status_reports/windows-x64.json index 6eb07412943..fa14027b7aa 100644 --- a/docs/website/static/port-status-data/ports/windows-x64.json +++ b/docs/website/data/port_status_reports/windows-x64.json @@ -13,7 +13,7 @@ }, "tests": { "ARApiTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "AccessibilityTest": { @@ -77,7 +77,7 @@ "status": "pass" }, "CameraApiTest": { - "feature": "camera-ar-sensors", + "feature": "camera-access", "status": "pass" }, "CenteredDialogTitleScreenshotTest": { @@ -397,7 +397,7 @@ "status": "pass" }, "MotionSensorDeviceTest": { - "feature": "camera-ar-sensors", + "feature": "ar-motion-sensors", "status": "pass" }, "MotionShowcaseScreenshotTest": { @@ -661,11 +661,11 @@ "status": "pass" }, "VideoIODecodedFramesScreenshotTest": { - "feature": "video-io", + "feature": "video-decoding", "status": "pass" }, "VideoIORoundTripTest": { - "feature": "video-io", + "feature": "video-round-trip", "status": "pass" } }, diff --git a/docs/website/layouts/_default/port-status.html b/docs/website/layouts/_default/port-status.html index 2d275ba8fe7..ce73703e0c1 100644 --- a/docs/website/layouts/_default/port-status.html +++ b/docs/website/layouts/_default/port-status.html @@ -1,5 +1,7 @@ {{- define "main" -}} {{- $contract := site.Data.port_status -}} +{{- $reports := site.Data.port_status_reports -}} +{{- $snapshotTime := now.UTC -}}
{{ partial "breadcrumbs.html" . }} @@ -18,8 +20,9 @@

{{ .Title }}

-
- Loading the latest compliance reports from GitHub… +
+ Table snapshot generated + .
@@ -31,14 +34,8 @@

{{ .Title }}

{{- range $contract.ports }} -
-
-

{{ .name }}

-

{{ .detail }}

-
-

Waiting for report

-

-
+ {{- $report := index $reports .id -}} + {{- partial "port-status-port-state.html" (dict "port" . "report" $report "contract" $contract "now" $snapshotTime) -}} {{- end }}
@@ -86,10 +83,8 @@

{{ .name }}

{{- range $contract.ports }} -
+ {{- $report := index $reports .id -}} + {{- partial "port-status-feature-status.html" (dict "feature" $feature "port" . "report" $report "contract" $contract "now" $snapshotTime) -}} {{- end }} {{- end }} @@ -100,16 +95,14 @@

{{ .name }}

How to read this page

- The feature-to-test map is checked into the repository. CI rejects a registered test or golden screenshot that is not mapped. Each port run publishes normalized per-test results; this page keeps the last result for every port and derives a feature status from all tests assigned to that feature. + The feature-to-test map is checked into the repository. CI rejects a registered test or golden screenshot that is not mapped. Each port run stores normalized per-test results, and website CI writes the latest stored result directly into this table.

- A website build does not wait for port workflows. The initial snapshot uses the successful workflow conclusion from the last master runs available when this page was added because those older artifacts did not all retain per-test completion logs. Each port replaces that bootstrap snapshot after a newer master run. A platform-specific skip is not a pass. An incomplete current report is not a pass. Reports older than {{ $contract.stale_after_days }} days are marked stale. + The browser makes no runtime report request. A website build uses the last stored result for ports that did not run, and the timestamp above identifies when this static table was assembled. A platform-specific skip is not a pass. An incomplete report is not a pass. Reports older than {{ $contract.stale_after_days }} days are marked stale.

Compliance feature contract

- - {{- end -}} diff --git a/docs/website/layouts/partials/port-status-feature-status.html b/docs/website/layouts/partials/port-status-feature-status.html new file mode 100644 index 00000000000..b7f1c0f178e --- /dev/null +++ b/docs/website/layouts/partials/port-status-feature-status.html @@ -0,0 +1,63 @@ +{{- $feature := .feature -}} +{{- $port := .port -}} +{{- $report := .report -}} +{{- $contract := .contract -}} +{{- $now := .now -}} +{{- $state := "unknown" -}} +{{- $mark := "?" -}} +{{- $label := "No current report" -}} +{{- if $report -}} + {{- $passed := 0 -}} + {{- $failed := 0 -}} + {{- $skipped := 0 -}} + {{- $notRun := 0 -}} + {{- $failedTests := slice -}} + {{- range $feature.tests -}} + {{- $result := index $report.tests . -}} + {{- $status := "not-run" -}} + {{- with $result -}}{{- $status = .status -}}{{- end -}} + {{- if eq $status "pass" -}} + {{- $passed = add $passed 1 -}} + {{- else if eq $status "fail" -}} + {{- $failed = add $failed 1 -}} + {{- $failedTests = $failedTests | append . -}} + {{- else if eq $status "skip" -}} + {{- $skipped = add $skipped 1 -}} + {{- else -}} + {{- $notRun = add $notRun 1 -}} + {{- end -}} + {{- end -}} + {{- $bootstrapComplete := and (eq $report.bootstrap_source "successful-master-workflow") (eq $report.workflow_conclusion "success") -}} + {{- $complete := or $report.suite_finished $bootstrapComplete -}} + {{- $total := len $feature.tests -}} + {{- $state = "partial" -}} + {{- $mark = "−" -}} + {{- $label = printf "%d passed, %d skipped, %d not run" $passed $skipped $notRun -}} + {{- if gt $failed 0 -}} + {{- $state = "fail" -}} + {{- $mark = "×" -}} + {{- $label = printf "%d failed: %s" $failed (delimit $failedTests ", ") -}} + {{- else if not $complete -}} + {{- $label = "Suite did not finish" -}} + {{- else if eq $passed $total -}} + {{- $state = "pass" -}} + {{- $mark = "✓" -}} + {{- $label = printf "All %d mapped test%s passed" $total (cond (eq $total 1) "" "s") -}} + {{- else if eq $skipped $total -}} + {{- $label = "All mapped tests skipped" -}} + {{- end -}} + {{- $generated := time.AsTime $report.generated_at -}} + {{- $staleSeconds := mul (int $contract.stale_after_days) 86400 -}} + {{- $stale := gt (sub $now.Unix $generated.Unix) $staleSeconds -}} + {{- if $stale -}} + {{- if ne $state "fail" -}} + {{- $state = "stale" -}} + {{- $mark = "!" -}} + {{- end -}} + {{- $label = printf "Stale report. %s" $label -}} + {{- end -}} +{{- end -}} + diff --git a/docs/website/layouts/partials/port-status-port-state.html b/docs/website/layouts/partials/port-status-port-state.html new file mode 100644 index 00000000000..efce1323cdb --- /dev/null +++ b/docs/website/layouts/partials/port-status-port-state.html @@ -0,0 +1,38 @@ +{{- $port := .port -}} +{{- $report := .report -}} +{{- $contract := .contract -}} +{{- $now := .now -}} +{{- $state := "unknown" -}} +{{- $label := "No stored report" -}} +{{- if $report -}} + {{- $failed := int (default 0 $report.summary.fail) -}} + {{- $bootstrapComplete := and (eq $report.bootstrap_source "successful-master-workflow") (eq $report.workflow_conclusion "success") -}} + {{- $complete := or $report.suite_finished $bootstrapComplete -}} + {{- $generated := time.AsTime $report.generated_at -}} + {{- $staleSeconds := mul (int $contract.stale_after_days) 86400 -}} + {{- $stale := gt (sub $now.Unix $generated.Unix) $staleSeconds -}} + {{- $state = "pass" -}} + {{- $label = cond $bootstrapComplete "Workflow completed" "Suite completed" -}} + {{- if gt $failed 0 -}} + {{- $state = "fail" -}} + {{- $label = printf "%d failing test%s" $failed (cond (eq $failed 1) "" "s") -}} + {{- else if not $complete -}} + {{- $state = "partial" -}} + {{- $label = "Run incomplete" -}} + {{- else if $stale -}} + {{- $state = "partial" -}} + {{- $label = "Report is stale" -}} + {{- end -}} +{{- end -}} +
+
+

{{ $port.name }}

+

{{ $port.detail }}

+
+

{{ $label }}

+ {{- if $report }} +

+ {{ $report.summary.pass }} passed · {{ $report.summary.skip }} skipped · {{ index $report.summary "not-run" }} not run +

+ {{- end }} +
diff --git a/scripts/hellocodenameone/README.adoc b/scripts/hellocodenameone/README.adoc index 257bba6c35b..1b4b87c409e 100644 --- a/scripts/hellocodenameone/README.adoc +++ b/scripts/hellocodenameone/README.adoc @@ -46,7 +46,7 @@ The project should work in IntelliJ out of the box. No need to copy any files. See the https://www.codenameone.com[Codename One Web Site]. -== Port conformance suite +== Port compliance suite This project is also the executable cross-port contract used by Codename One CI. `Cn1ssDeviceRunner` runs the same assertion and screenshot tests on the supported @@ -55,12 +55,15 @@ https://www.codenameone.com/port-status/[Port Status] page groups those tests by Codename One feature and publishes the latest normalized result from `master` for each port. Port workflows update their reports independently on the `port-status-data` branch, so a website-only build neither waits for nor clears -ports that did not run. The checked-in reports under -`docs/website/static/port-status-data/ports` are the initial snapshot only; -the page uses one of them only until that port has its first published report. -Those bootstrap reports use the successful master workflow conclusion because -the older artifacts did not consistently retain per-test completion logs. New -reports use the normalized suite and screenshot results directly. +ports that did not run. Before Hugo runs, website CI resolves the latest stored +report for every port into `docs/website/data/port_status_reports`; checked-in +reports are the fallback if a port has not published yet or the data branch is +temporarily unavailable. Hugo writes those results directly into the table. +The browser never fetches report data, and the page displays when the static +snapshot was generated. The bootstrap reports use the successful master +workflow conclusion because the older artifacts did not consistently retain +per-test completion logs. New reports use the normalized suite and screenshot +results directly. The feature contract lives in `docs/website/data/port_status.json`. Every test registered in diff --git a/scripts/hellocodenameone/conformance/port_status.py b/scripts/hellocodenameone/conformance/port_status.py index 0194cc831c0..0e16a26bf9b 100755 --- a/scripts/hellocodenameone/conformance/port_status.py +++ b/scripts/hellocodenameone/conformance/port_status.py @@ -154,49 +154,36 @@ def validate(manifest: dict) -> dict: if owner is None: problems.append(f"Golden screenshot {name} is not mapped to a test") - seed_directory = manifest.get("seed_report_directory") - if seed_directory: - seed_root = REPO_ROOT / seed_directory + report_directory = manifest.get("report_directory") + if report_directory: + report_root = REPO_ROOT / report_directory for port_id in port_ids: - seed_path = seed_root / f"{port_id}.json" + report_path = report_root / f"{port_id}.json" try: - seed = read_json(seed_path) + report = read_json(report_path) except ContractError as exc: problems.append(str(exc)) continue - if seed.get("schema_version") != manifest.get("schema_version"): - problems.append(f"Seed report {seed_path} has the wrong schema version") - if seed.get("port") != port_id: - problems.append(f"Seed report {seed_path} identifies port {seed.get('port')}") - if seed.get("bootstrap_source") != "successful-master-workflow": - problems.append(f"Seed report {seed_path} has no successful-workflow provenance") - if seed.get("workflow_conclusion") != "success": - problems.append(f"Seed report {seed_path} did not come from a successful workflow") - seed_tests = seed.get("tests") - if not isinstance(seed_tests, dict): - problems.append(f"Seed report {seed_path} has no test result map") + if report.get("schema_version") != manifest.get("schema_version"): + problems.append(f"Stored report {report_path} has the wrong schema version") + if report.get("port") != port_id: + problems.append(f"Stored report {report_path} identifies port {report.get('port')}") + report_tests = report.get("tests") + if not isinstance(report_tests, dict): + problems.append(f"Stored report {report_path} has no test result map") continue - unknown_tests = sorted(set(seed_tests) - set(mapped)) + unknown_tests = sorted(set(report_tests) - set(mapped)) if unknown_tests: problems.append( - f"Seed report {seed_path} contains unknown tests: " + f"Stored report {report_path} contains unknown tests: " + ", ".join(unknown_tests) ) - missing_tests = sorted(set(mapped) - set(seed_tests)) + missing_tests = sorted(set(mapped) - set(report_tests)) if missing_tests: problems.append( - f"Seed report {seed_path} is missing tests: " + f"Stored report {report_path} is missing tests: " + ", ".join(missing_tests) ) - failing_tests = sorted( - test for test, result in seed_tests.items() - if result.get("status") == "fail" - ) - if failing_tests: - problems.append( - f"Successful-workflow seed report {seed_path} contains failures: " - + ", ".join(failing_tests) - ) if problems: raise ContractError("\n".join(problems)) diff --git a/scripts/hellocodenameone/conformance/publish_port_status.sh b/scripts/hellocodenameone/conformance/publish_port_status.sh index 62ae541e1b7..092301ff655 100755 --- a/scripts/hellocodenameone/conformance/publish_port_status.sh +++ b/scripts/hellocodenameone/conformance/publish_port_status.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash set -euo pipefail -# Publish one normalized report to the data-only branch consumed by the public -# /port-status/ page. This is intentionally a per-port file update so unrelated -# conformance workflows never need to merge a shared generated document. +# Publish one normalized report to the data-only branch consumed by website CI. +# This is intentionally a per-port file update so unrelated compliance +# workflows never need to merge a shared generated document. report="${1:-}" if [ -z "$report" ] || [ ! -f "$report" ]; then @@ -41,7 +41,7 @@ for attempt in 1 2 3; do args=( --method PUT "repos/${repo}/contents/${target}" - -f message="Update ${port} conformance status" + -f message="Update ${port} compliance status" -f content="$content" -f branch="$branch" ) diff --git a/scripts/hellocodenameone/conformance/test_port_status.py b/scripts/hellocodenameone/conformance/test_port_status.py index 9f4a4db4adb..46cd98c69d1 100755 --- a/scripts/hellocodenameone/conformance/test_port_status.py +++ b/scripts/hellocodenameone/conformance/test_port_status.py @@ -16,8 +16,13 @@ def setUpClass(cls): def test_contract_covers_registered_tests_and_goldens(self): counts = port_status.validate(self.manifest) self.assertEqual(164, counts["tests"]) - self.assertGreaterEqual(counts["features"], 40) + self.assertGreaterEqual(counts["features"], 51) self.assertGreaterEqual(counts["goldens"], 100) + features = {feature["id"]: feature["tests"] for feature in self.manifest["features"]} + self.assertEqual(["ARApiTest", "MotionSensorDeviceTest"], features["ar-motion-sensors"]) + self.assertEqual(["CameraApiTest"], features["camera-access"]) + self.assertEqual(["VideoIODecodedFramesScreenshotTest"], features["video-decoding"]) + self.assertEqual(["VideoIORoundTripTest"], features["video-round-trip"]) def test_normalize_preserves_pass_skip_and_screenshot_failure(self): log_text = "\n".join( diff --git a/scripts/website/build.sh b/scripts/website/build.sh index 63a6cd676f0..d6a76ef05cb 100755 --- a/scripts/website/build.sh +++ b/scripts/website/build.sh @@ -31,12 +31,11 @@ WEBSITE_INCLUDE_INITIALIZR="${WEBSITE_INCLUDE_INITIALIZR:-false}" WEBSITE_INCLUDE_PLAYGROUND="${WEBSITE_INCLUDE_PLAYGROUND:-false}" WEBSITE_INCLUDE_SKINDESIGNER="${WEBSITE_INCLUDE_SKINDESIGNER:-true}" WEBSITE_BOOTSTRAP_CN1_SNAPSHOTS="${WEBSITE_BOOTSTRAP_CN1_SNAPSHOTS:-auto}" +WEBSITE_REFRESH_PORT_STATUS="${WEBSITE_REFRESH_PORT_STATUS:-false}" WEBSITE_CN1_VERSION="${WEBSITE_CN1_VERSION:-auto}" CN1_USER="${CN1_USER:-}" CN1_TOKEN="${CN1_TOKEN:-}" -"${PYTHON_BIN}" "${REPO_ROOT}/scripts/hellocodenameone/conformance/port_status.py" validate - if [ "${WEBSITE_INCLUDE_INITIALIZR}" = "auto" ]; then if [ -n "${CN1_USER}" ] && [ -n "${CN1_TOKEN}" ]; then WEBSITE_INCLUDE_INITIALIZR="true" @@ -862,6 +861,11 @@ if ! command -v "${HUGO_BIN}" >/dev/null 2>&1; then exit 1 fi +if [ "${WEBSITE_REFRESH_PORT_STATUS}" = "true" ]; then + "${REPO_ROOT}/scripts/website/sync_port_status_reports.sh" +fi +"${PYTHON_BIN}" "${REPO_ROOT}/scripts/hellocodenameone/conformance/port_status.py" validate + build_javadocs_for_site build_developer_guide_for_site build_initializr_for_site diff --git a/scripts/website/sync_port_status_reports.sh b/scripts/website/sync_port_status_reports.sh new file mode 100755 index 00000000000..5d4e9dbf736 --- /dev/null +++ b/scripts/website/sync_port_status_reports.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +# +# Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Codename One designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Codename One through http://www.codenameone.com/ if you +# need additional information or have any questions. + +set -euo pipefail + +# Website CI resolves the durable per-port reports before Hugo renders the +# static table. The checked-in reports remain a complete fallback, so a +# temporary fetch failure never produces an empty public page. + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" +MANIFEST="${REPO_ROOT}/docs/website/data/port_status.json" +REPORT_DIR="${REPO_ROOT}/docs/website/data/port_status_reports" +DATA_REF="refs/heads/port-status-data" + +if ! command -v jq >/dev/null 2>&1; then + echo "jq is required to refresh Port Status reports." >&2 + exit 1 +fi + +tmp_dir="$(mktemp -d)" +cleanup() { + rm -rf "${tmp_dir}" +} +trap cleanup EXIT + +if ! git -C "${REPO_ROOT}" fetch --quiet --no-tags --depth=1 origin "${DATA_REF}"; then + echo "Port Status data branch is unavailable; using the checked-in reports." >&2 + exit 0 +fi + +synced=0 +while IFS= read -r port; do + candidate="${tmp_dir}/${port}.json" + if ! git -C "${REPO_ROOT}" show "FETCH_HEAD:ports/${port}.json" > "${candidate}" 2>/dev/null; then + echo "No persisted ${port} report; keeping the checked-in report." >&2 + continue + fi + if ! jq -e --arg port "${port}" --slurpfile contract "${MANIFEST}" ' + .schema_version == $contract[0].schema_version and + .port == $port and + ((.tests | keys | sort) == ([$contract[0].features[].tests[]] | sort)) + ' "${candidate}" >/dev/null; then + echo "Persisted ${port} report does not match the current contract; keeping the checked-in report." >&2 + continue + fi + cp "${candidate}" "${REPORT_DIR}/${port}.json" + synced=$((synced + 1)) +done < <(jq -r '.ports[].id' "${MANIFEST}") + +echo "Resolved ${synced} Port Status reports from ${DATA_REF}; remaining ports use checked-in reports." diff --git a/scripts/website/validate_port_status.mjs b/scripts/website/validate_port_status.mjs index a1ac42baab7..5da6bd01b58 100644 --- a/scripts/website/validate_port_status.mjs +++ b/scripts/website/validate_port_status.mjs @@ -62,78 +62,56 @@ function validate() { fail("the public page links to the result-normalizer implementation"); } - const contractMatch = page.match( - /]*\bdata-port-status-contract\b)[^>]*>([\s\S]*?)<\/script>/i - ); - if (!contractMatch) { - fail("the generated page does not embed its compliance contract"); - } - - let contract; - try { - contract = JSON.parse(contractMatch[1]); - } catch (error) { - fail(`the embedded compliance contract is invalid JSON: ${error.message}`); - } - if (!contract || typeof contract !== "object" || Array.isArray(contract)) { - fail("the embedded compliance contract was serialized as a string"); - } - if (!Array.isArray(contract.ports) || contract.ports.length !== 10) { - fail("the contract must contain the 10 portability targets"); + if (/data-port-status-contract|raw\.githubusercontent\.com|port-status-data\/ports/i.test(page)) { + fail("the generated page still depends on runtime report data"); } - if (contract.ports.some((port) => port.id === "javase")) { + if (/\bdata-port=(?:["']?javase["']?)(?:\s|>)/i.test(page)) { fail("JavaSE must not appear as a portability target"); } - if (!Array.isArray(contract.features) || contract.features.length < 49) { - fail("the compliance feature map lost required rows"); - } - - const mappedTests = new Set(); - for (const feature of contract.features) { - if (!Array.isArray(feature.tests) || feature.tests.length === 0) { - fail(`feature ${feature.id || ""} has no mapped tests`); - } - for (const test of feature.tests) { - if (mappedTests.has(test)) { - fail(`test ${test} is mapped more than once`); - } - mappedTests.add(test); - } - } - if (mappedTests.size < 164) { - fail("the compliance contract lost mapped tests"); - } const portCards = countMatches(page, /\bdata-port-card(?:=|\s|>)/g); const featureRows = countMatches(page, /\bdata-feature-row(?:=|\s|>)/g); const featureCells = countMatches(page, /\bdata-feature-cell(?:=|\s|>)/g); - if (portCards !== contract.ports.length) { - fail(`generated ${portCards} port cards for ${contract.ports.length} ports`); + const mappedTests = countMatches(page, /
  • [^<]+<\/code><\/li>/g); + if (portCards !== 10) { + fail(`generated ${portCards} port cards instead of 10`); } - if (featureRows !== contract.features.length) { - fail(`generated ${featureRows} feature rows for ${contract.features.length} features`); + if (featureRows < 51) { + fail(`the generated table has only ${featureRows} feature rows`); } - if (featureCells !== contract.ports.length * contract.features.length) { + if (featureCells !== portCards * featureRows) { fail("the generated compliance matrix is incomplete"); } - - if (contract.seed_report_base !== "/port-status-data/ports/") { - fail("the initial master-result fallback is not configured"); + if (mappedTests < 164) { + fail(`the generated table exposes only ${mappedTests} mapped tests`); } - for (const port of contract.ports) { - const report = JSON.parse(read(path.join("port-status-data", "ports", `${port.id}.json`))); - if (report.port !== port.id || report.schema_version !== contract.schema_version) { - fail(`seed report ${port.id} does not match the compliance contract`); - } - if (report.workflow_conclusion !== "success" || report.summary?.fail !== 0) { - fail(`seed report ${port.id} is not based on a successful master workflow`); - } - const reportTests = Object.keys(report.tests || {}); - if (reportTests.length !== mappedTests.size || reportTests.some((test) => !mappedTests.has(test))) { - fail(`seed report ${port.id} does not cover every mapped test`); + for (const feature of ["ar-motion-sensors", "camera-access", "video-decoding", "video-round-trip"]) { + if (!new RegExp(`data-feature-id=["']?${feature}(?:["'\\s>])`).test(page)) { + fail(`the generated table is missing the split ${feature} feature row`); } } + const renderedCells = countMatches( + page, + /]*\bdata-feature-cell\b)(?=[^>]*\bclass=(?:["']?is-(?:pass|fail|partial|stale|unknown)))[^>]*>/g + ); + if (renderedCells !== featureCells) { + fail("not every compliance cell has a build-time status"); + } + if (/Waiting for report|Loading the latest compliance reports/i.test(page)) { + fail("the generated page still waits for client-side report rendering"); + } + const truthTime = page.match( + /]*\bdata-port-status-truth\b)(?=[^>]*\bdatetime=(?:["']([^"']+)["']|([^\s>]+)))[^>]*>/i + ); + if (!truthTime || Number.isNaN(Date.parse(truthTime[1] || truthTime[2])) || + countMatches(page, /]*src=(?:["']([^"']*cn1-port-status[^"']*\.js)["']|([^\s>]*cn1-port-status[^\s>]*\.js))[^>]*><\/script>/i ); @@ -147,13 +125,30 @@ function validate() { } catch (error) { fail(`the generated Port Status JavaScript is invalid: ${error.message}`); } - if (!script.includes("seed_report_base") || !script.includes("successful-master-workflow")) { - fail("the generated JavaScript lost master-result fallback handling"); + if (/\bfetch\s*\(/.test(script) || /raw\.githubusercontent\.com/.test(script)) { + fail("the generated JavaScript fetches report data at runtime"); + } + if (!script.includes("data-category-filter") || !script.includes("data-feature-search")) { + fail("the generated JavaScript lost table filtering"); + } + + const stylesheetMatch = page.match( + /]*href=(?:["']([^"']*stylesheet[^"']*\.css)["']|([^\s>]*stylesheet[^\s>]*\.css))[^>]*>/i + ); + if (!stylesheetMatch) { + fail("the generated page has no website stylesheet"); + } + const stylesheetPath = (stylesheetMatch[1] || stylesheetMatch[2]).replace(/^\//, ""); + const stylesheet = read(stylesheetPath); + if (!stylesheet.includes(".cn1-port-status__matrix{") || + !stylesheet.includes("max-height:min(78vh,920px)") || + !/\.cn1-port-status__matrix thead th\{[^}]*position:sticky[^}]*top:0/.test(stylesheet)) { + fail("the generated table header is not frozen inside its scroll area"); } console.log( - `Port Status page valid: ${contract.ports.length} ports, ` + - `${contract.features.length} features, ${mappedTests.size} mapped tests.` + `Port Status page valid: ${portCards} ports, ` + + `${featureRows} features, ${mappedTests} mapped tests, static snapshot.` ); } From ed75bf910e9d03f5e1f256e9b4673b047815bc20 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 16 Jul 2026 09:49:58 +0300 Subject: [PATCH 07/21] Keep port status on page scroll --- docs/website/assets/css/extended/cn1-port-status.css | 5 ----- scripts/website/validate_port_status.mjs | 6 +++--- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/docs/website/assets/css/extended/cn1-port-status.css b/docs/website/assets/css/extended/cn1-port-status.css index ca2fc7a8c9f..493220e19f9 100644 --- a/docs/website/assets/css/extended/cn1-port-status.css +++ b/docs/website/assets/css/extended/cn1-port-status.css @@ -188,11 +188,6 @@ .cn1-port-status__matrix { border: 1px solid var(--cn1-status-border); border-radius: 12px; - max-height: min(78vh, 920px); - overscroll-behavior: contain; - overflow: auto; - position: relative; - scrollbar-gutter: stable; } .cn1-port-status__matrix table { diff --git a/scripts/website/validate_port_status.mjs b/scripts/website/validate_port_status.mjs index 5da6bd01b58..4ebdb73a4cc 100644 --- a/scripts/website/validate_port_status.mjs +++ b/scripts/website/validate_port_status.mjs @@ -140,10 +140,10 @@ function validate() { } const stylesheetPath = (stylesheetMatch[1] || stylesheetMatch[2]).replace(/^\//, ""); const stylesheet = read(stylesheetPath); - if (!stylesheet.includes(".cn1-port-status__matrix{") || - !stylesheet.includes("max-height:min(78vh,920px)") || + const matrixRule = stylesheet.match(/\.cn1-port-status__matrix\{([^}]*)\}/); + if (!matrixRule || /max-height|overflow:(?:auto|scroll)/.test(matrixRule[1]) || !/\.cn1-port-status__matrix thead th\{[^}]*position:sticky[^}]*top:0/.test(stylesheet)) { - fail("the generated table header is not frozen inside its scroll area"); + fail("the table header must stick during normal page scrolling without a nested table scroller"); } console.log( From 2d3bf99180633940d633d08b12b23972d0706fe4 Mon Sep 17 00:00:00 2001 From: Shai Almog <67850168+shai-almog@users.noreply.github.com> Date: Thu, 16 Jul 2026 13:00:28 +0300 Subject: [PATCH 08/21] Expand port status coverage --- .github/workflows/parparvm-tests-windows.yml | 27 +- .github/workflows/port-status-contract.yml | 2 + .github/workflows/port-status-publish.yml | 1 + .../assets/css/extended/cn1-port-status.css | 76 ++ docs/website/data/port_status.json | 1 + .../port_status_reports/windows-arm64.json | 674 ++++++++++++++++++ docs/website/data/port_status_supplement.json | 287 ++++++++ docs/website/hugo.toml | 12 +- .../website/layouts/_default/port-status.html | 90 ++- .../partials/port-status-feature-status.html | 1 + .../partials/port-status-manual-status.html | 22 + scripts/hellocodenameone/README.adoc | 11 +- .../conformance/port_status.py | 86 +++ .../conformance/test_port_status.py | 2 + scripts/website/validate_port_status.mjs | 71 +- 15 files changed, 1343 insertions(+), 20 deletions(-) create mode 100644 docs/website/data/port_status_reports/windows-arm64.json create mode 100644 docs/website/data/port_status_supplement.json create mode 100644 docs/website/layouts/partials/port-status-manual-status.html diff --git a/.github/workflows/parparvm-tests-windows.yml b/.github/workflows/parparvm-tests-windows.yml index 27818330f0e..c467a65b8c4 100644 --- a/.github/workflows/parparvm-tests-windows.yml +++ b/.github/workflows/parparvm-tests-windows.yml @@ -26,6 +26,7 @@ on: - '.github/workflows/parparvm-tests-windows.yml' - 'vm/**' - 'Ports/WindowsPort/**' + - 'scripts/hellocodenameone/**' - '!vm/**/README.md' - '!vm/**/readme.md' - '!vm/**/docs/**' @@ -35,6 +36,7 @@ on: - '.github/workflows/parparvm-tests-windows.yml' - 'vm/**' - 'Ports/WindowsPort/**' + - 'scripts/hellocodenameone/**' - '!vm/**/README.md' - '!vm/**/readme.md' - '!vm/**/docs/**' @@ -209,12 +211,13 @@ jobs: # mode -- the app paints into an offscreen Direct2D/WIC bitmap (no window) and # writes a PNG. The PNG is uploaded as an artifact; the companion comment job # posts it to the PR. This x64 leg also publishes the compiled core + port - # bytecode for the native arm64 leg (windows-port-screenshot-arm64). PR events - # only (the comment job needs PR context). Separate from the clean-target gate - # so a rendering hiccup never blocks merges. + # bytecode for the native arm64 leg (windows-port-screenshot-arm64). Pull + # requests render review artifacts; master runs also produce the durable + # Windows ARM64 compliance report consumed by the static Port Status page. + # Separate from the clean-target gate so a rendering hiccup never blocks merges. windows-port-screenshot: name: screenshot-capture (x64) - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' || github.event_name == 'push' runs-on: windows-latest timeout-minutes: 90 steps: @@ -399,7 +402,7 @@ jobs: windows-port-screenshot-arm64: name: screenshot-capture (arm64) needs: windows-port-screenshot - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' || github.event_name == 'push' runs-on: windows-11-arm continue-on-error: true timeout-minutes: 60 @@ -599,7 +602,7 @@ jobs: windows-port-screenshot-comment-arm64: name: screenshot-comment (arm64) needs: windows-port-screenshot-arm64 - if: github.event_name == 'pull_request' + if: github.event_name == 'pull_request' || github.event_name == 'push' continue-on-error: true runs-on: ubuntu-latest permissions: @@ -651,6 +654,9 @@ jobs: # the PR -- but the mismatch is no longer silent. export CN1SS_FAIL_ON_MISMATCH=1 export CN1SS_ALLOWED_MISSING=0 + export CN1SS_PORT_ID=windows-arm64 + export CN1SS_SUITE_LOG="$ART/raw/app-output.log" + if [ "${{ github.event_name }}" != "pull_request" ]; then export CN1SS_SKIP_COMMENT=1; fi set +e cn1ss_process_and_report \ "Native Windows port (arm64)" \ @@ -669,6 +675,15 @@ jobs: fi if [ "$fail" -ne 0 ]; then echo "Windows arm64 screenshot gate failed."; exit 1; fi + - name: Upload Windows ARM64 port status + if: always() + uses: actions/upload-artifact@v4 + with: + name: port-status-windows-arm64 + path: artifacts/windows-port/port-status-windows-arm64.json + if-no-files-found: warn + retention-days: 14 + # Widgets Board provider compile check: compiles the one nativeSources TU no # other CI leg ever compiles -- cn1_windows_widgetboard.cpp, which is gated # behind CN1_WIDGETBOARD (the default CMake build never defines it and the diff --git a/.github/workflows/port-status-contract.yml b/.github/workflows/port-status-contract.yml index f7aa4a4d5d8..905374e5490 100644 --- a/.github/workflows/port-status-contract.yml +++ b/.github/workflows/port-status-contract.yml @@ -5,6 +5,7 @@ on: paths: - '.github/workflows/port-status-contract.yml' - 'docs/website/data/port_status.json' + - 'docs/website/data/port_status_supplement.json' - 'docs/website/data/port_status_reports/**' - 'scripts/hellocodenameone/common/src/main/**' - 'scripts/hellocodenameone/conformance/**' @@ -23,6 +24,7 @@ on: paths: - '.github/workflows/port-status-contract.yml' - 'docs/website/data/port_status.json' + - 'docs/website/data/port_status_supplement.json' - 'docs/website/data/port_status_reports/**' - 'scripts/hellocodenameone/common/src/main/**' - 'scripts/hellocodenameone/conformance/**' diff --git a/.github/workflows/port-status-publish.yml b/.github/workflows/port-status-publish.yml index e7e47c93f8b..6df0fac6911 100644 --- a/.github/workflows/port-status-publish.yml +++ b/.github/workflows/port-status-publish.yml @@ -9,6 +9,7 @@ on: - Test JavaScript screenshot scripts - Linux native build + run (GTK3, x64 + arm64) - Windows cross-build + run (Linux build -> Windows run) + - ParparVM Java Tests (Windows) types: [completed] permissions: diff --git a/docs/website/assets/css/extended/cn1-port-status.css b/docs/website/assets/css/extended/cn1-port-status.css index 493220e19f9..42f366f78b7 100644 --- a/docs/website/assets/css/extended/cn1-port-status.css +++ b/docs/website/assets/css/extended/cn1-port-status.css @@ -116,6 +116,10 @@ .cn1-port-status__mark.is-partial, .cn1-port-status__mark.is-stale { color: #c38a20; } .cn1-port-status__mark.is-unknown { color: #7d8791; } +.cn1-port-status__mark.is-supported { color: #27955b; } +.cn1-port-status__mark.is-conditional { color: #c38a20; } +.cn1-port-status__mark.is-fallback { color: #3976c5; } +.cn1-port-status__mark.is-unavailable { color: #7d8791; } .cn1-port-status__ports { display: grid; @@ -269,6 +273,78 @@ .cn1-port-status__matrix td.is-partial, .cn1-port-status__matrix td.is-stale { background: color-mix(in srgb, #c38a20 9%, transparent); } +.cn1-port-status__errata, +.cn1-port-status__manual { + margin-top: 2.25rem; +} + +.cn1-port-status__errata > p, +.cn1-port-status__manual > header { + color: var(--secondary); + line-height: 1.65; + max-width: 900px; +} + +.cn1-port-status__errata-list { + display: grid; + gap: 1rem; + grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); + margin-top: 1rem; +} + +.cn1-port-status__errata-list article { + background: var(--entry); + border: 1px solid var(--cn1-status-border); + border-left: 4px solid #c38a20; + border-radius: 12px; + padding: 1.1rem; +} + +.cn1-port-status__errata-list h3 { + font-size: 1rem; + margin: 0 0 .65rem; +} + +.cn1-port-status__errata-list p { + color: var(--secondary); + font-size: .84rem; + line-height: 1.55; + margin: .45rem 0; +} + +.cn1-port-status__manual > header h2 { + color: var(--primary); + margin-bottom: .6rem; +} + +.cn1-port-status__matrix--manual table { + min-width: 1320px; +} + +.cn1-port-status__matrix--manual td small { + color: var(--secondary); + display: block; + font-size: .64rem; + line-height: 1.25; + margin-top: .35rem; +} + +.cn1-port-status__matrix--manual td.is-supported { + background: color-mix(in srgb, #27955b 8%, transparent); +} + +.cn1-port-status__matrix--manual td.is-conditional { + background: color-mix(in srgb, #c38a20 9%, transparent); +} + +.cn1-port-status__matrix--manual td.is-fallback { + background: color-mix(in srgb, #3976c5 9%, transparent); +} + +.cn1-port-status__matrix--manual td.is-unavailable { + background: color-mix(in srgb, #7d8791 7%, transparent); +} + .cn1-port-status__method { background: var(--entry); border: 1px solid var(--cn1-status-border); diff --git a/docs/website/data/port_status.json b/docs/website/data/port_status.json index a7c76669afb..0286b4c24c7 100644 --- a/docs/website/data/port_status.json +++ b/docs/website/data/port_status.json @@ -23,6 +23,7 @@ {"id": "linux-x64", "name": "Linux x64", "detail": "Native GTK3/Cairo build", "workflow": "linux-build-run.yml"}, {"id": "linux-arm64", "name": "Linux ARM64", "detail": "Native GTK3/Cairo build", "workflow": "linux-build-run.yml"}, {"id": "windows-x64", "name": "Windows x64", "detail": "Native cross-compiled binary on Windows", "workflow": "windows-cross-build-run.yml"}, + {"id": "windows-arm64", "name": "Windows ARM64", "detail": "Native ARM64 binary on Windows 11", "workflow": "parparvm-tests-windows.yml"}, {"id": "watchos", "name": "watchOS", "detail": "Apple Watch Simulator", "workflow": "scripts-ios.yml"}, {"id": "tvos", "name": "tvOS", "detail": "Apple TV Simulator", "workflow": "scripts-ios.yml"} ], diff --git a/docs/website/data/port_status_reports/windows-arm64.json b/docs/website/data/port_status_reports/windows-arm64.json new file mode 100644 index 00000000000..958428986b5 --- /dev/null +++ b/docs/website/data/port_status_reports/windows-arm64.json @@ -0,0 +1,674 @@ +{ + "commit": "c2d12f867bc2081a80a1745ecd0b0ffaad86921b", + "generated_at": "2026-07-15T14:40:02Z", + "port": "windows-arm64", + "run_url": "https://github.com/codenameone/CodenameOne/actions/runs/29423004951", + "schema_version": 1, + "suite_finished": false, + "summary": { + "fail": 0, + "not-run": 0, + "pass": 164, + "skip": 0 + }, + "tests": { + "ARApiTest": { + "feature": "ar-motion-sensors", + "status": "pass" + }, + "AccessibilityTest": { + "feature": "accessibility", + "status": "pass" + }, + "AdsScreenshotTest": { + "feature": "ads", + "status": "pass" + }, + "AffineScale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "AnimateHierarchyScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateLayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AnimateUnlayoutScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "AppReviewDialogScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "AudioMixerApiTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "BackgroundThreadUiAccessTest": { + "feature": "threading", + "status": "pass" + }, + "Base64NativePerformanceTest": { + "feature": "native-base64", + "status": "pass" + }, + "BridgeBulkTransferGuardTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "BrowserComponentScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "BytecodeTranslatorRegressionTest": { + "feature": "bytecode-runtime", + "status": "pass" + }, + "CallDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "CameraApiTest": { + "feature": "camera-access", + "status": "pass" + }, + "CenteredDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "CenteredInteractionDialogTitleScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "ChartBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartBubbleScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCombinedXYScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartCubicLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartDoughnutScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartLineScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartPieScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRadarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRangeBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartRotatedScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartScatterScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartStackedBarScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTimeChartScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChartTransformScreenshotTest": { + "feature": "charts", + "status": "pass" + }, + "ChatInputScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "ChatViewScreenshotTest": { + "feature": "chat-components", + "status": "pass" + }, + "CheckBoxRadioThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "Clip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "ClipUnderRotation": { + "feature": "graphics-clipping", + "status": "pass" + }, + "CodeEditorScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "ComponentReplaceFadeScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceFlipScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "ComponentReplaceSlideScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "CoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "CryptoApiTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "CssFilterBlurScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "CssGradientsScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DarkLightShowcaseThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "DesktopModeScreenshotTest": { + "feature": "desktop-mode", + "status": "pass" + }, + "DeviceInputApiTest": { + "feature": "text-input", + "status": "pass" + }, + "DialogThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "DrawArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawGradient": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawGradientStops": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "DrawImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawLine": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "DrawShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "DrawString": { + "feature": "graphics-text-images", + "status": "pass" + }, + "DrawStringDecorated": { + "feature": "graphics-text-images", + "status": "pass" + }, + "EmptyClip": { + "feature": "graphics-clipping", + "status": "pass" + }, + "FadeTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FileSystemStorageOpenInputStreamMissingTest": { + "feature": "filesystem-storage", + "status": "pass" + }, + "FillArc": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillPolygon": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillRoundRect": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FillShape": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "FillTriangle": { + "feature": "graphics-primitives", + "status": "pass" + }, + "FlipTransitionTest": { + "feature": "fade-flip-transitions", + "status": "pass" + }, + "FloatingActionButtonThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "FloatingToStringTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "GaussianBlur": { + "feature": "graphics-gradients-filters", + "status": "pass" + }, + "GoogleWebMapScreenshotTest": { + "feature": "native-web-maps", + "status": "pass" + }, + "Gpu3DAnimationTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DModelScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "Gpu3DTexturedCubeScreenshotTest": { + "feature": "gpu-3d", + "status": "pass" + }, + "ImageViewerNavigationScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "InPlaceEditViewTest": { + "feature": "text-input", + "status": "pass" + }, + "InscribedTriangleGrid": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "Java17Tests": { + "feature": "java-standard-apis", + "status": "pass" + }, + "KotlinUiTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "LargeStrokeDirtyClipTest": { + "feature": "graphics-clipping", + "status": "pass" + }, + "LightweightPickerButtonsScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "ListThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "LocalNotificationOverrideTest": { + "feature": "notifications", + "status": "pass" + }, + "LottieAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "MainScreenScreenshotTest": { + "feature": "application-bootstrap", + "status": "pass" + }, + "Media360PanoramaScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "MediaPlaybackScreenshotTest": { + "feature": "audio-media-playback", + "status": "pass" + }, + "MorphElementMorphScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrolledSourceTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionScrubScreenshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionSnapshotTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MorphTransitionTest": { + "feature": "morph-transitions", + "status": "pass" + }, + "MotionSensorDeviceTest": { + "feature": "ar-motion-sensors", + "status": "pass" + }, + "MotionShowcaseScreenshotTest": { + "feature": "layout-animation", + "status": "pass" + }, + "MultiButtonThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "MutableImageClipReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "MutableImageReadbackTest": { + "feature": "mutable-images", + "status": "pass" + }, + "NanoTimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "NativeMapFallbackScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "OrientationLockScreenshotTest": { + "feature": "orientation", + "status": "pass" + }, + "PaletteOverrideThemeScreenshotTest": { + "feature": "theme-palette-css", + "status": "pass" + }, + "PartialFlushClipEscape": { + "feature": "graphics-clipping", + "status": "pass" + }, + "PickerCancelRestoreTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "PickerThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "PullToRefreshSpinnerScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "RealOsmVectorScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "RichTextAreaScreenshotTest": { + "feature": "embedded-web-content", + "status": "pass" + }, + "Rotate": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SVGAnimatedScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "SVGStaticScreenshotTest": { + "feature": "svg-lottie", + "status": "pass" + }, + "Scale": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "SecureStorageTest": { + "feature": "secure-storage-crypto", + "status": "pass" + }, + "SheetScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SheetSlideUpAnimationScreenshotTest": { + "feature": "sheets", + "status": "pass" + }, + "SimdApiTest": { + "feature": "simd", + "status": "pass" + }, + "SimdBenchmarkTest": { + "feature": "simd", + "status": "pass" + }, + "SimdLargeAllocaTest": { + "feature": "simd", + "status": "pass" + }, + "SlideFadeTitleTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalBackTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SlideVerticalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "SmoothScrollScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "SpanLabelThemeScreenshotTest": { + "feature": "dialogs-and-labels", + "status": "pass" + }, + "StatusBarTapDiagnosticScreenshotTest": { + "feature": "status-bar-events", + "status": "pass" + }, + "StickyHeaderFadeTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StickyHeaderSlideTransitionScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "StreamApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StringApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "StrokeTest": { + "feature": "graphics-shapes-strokes", + "status": "pass" + }, + "SurfacesActionDispatchTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesPublishTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRasterizerScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesRemoteViewsScreenshotTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesSerializerRoundTripTest": { + "feature": "surfaces", + "status": "pass" + }, + "SurfacesTimelineLogicTest": { + "feature": "surfaces", + "status": "pass" + }, + "SwitchThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TabsAnimatedIndicatorScreenshotTest": { + "feature": "tabs-animation", + "status": "pass" + }, + "TabsScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TabsThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TensileBounceScreenshotTest": { + "feature": "scrolling-and-pull", + "status": "pass" + }, + "TextAreaAlignmentScreenshotTest": { + "feature": "image-viewer-tabs-text", + "status": "pass" + }, + "TextFieldThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TileImage": { + "feature": "graphics-text-images", + "status": "pass" + }, + "TimeApiTest": { + "feature": "java-standard-apis", + "status": "pass" + }, + "ToastBarTopPositionScreenshotTest": { + "feature": "toast-notifications", + "status": "pass" + }, + "ToolbarThemeScreenshotTest": { + "feature": "native-theme-controls", + "status": "pass" + }, + "TransformCamera": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformPerspective": { + "feature": "graphics-3d-transforms", + "status": "pass" + }, + "TransformRotation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "TransformTranslation": { + "feature": "graphics-2d-transforms", + "status": "pass" + }, + "UncoverHorizontalTransitionTest": { + "feature": "slide-cover-transitions", + "status": "pass" + }, + "VPNDetectionAPITest": { + "feature": "device-security-signals", + "status": "pass" + }, + "VRStereoSceneScreenshotTest": { + "feature": "immersive-media", + "status": "pass" + }, + "ValidatorLightweightPickerScreenshotTest": { + "feature": "pickers-validation", + "status": "pass" + }, + "VectorMapDarkStyleScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapMarkersScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VectorMapShapesScreenshotTest": { + "feature": "vector-maps", + "status": "pass" + }, + "VideoIODecodedFramesScreenshotTest": { + "feature": "video-decoding", + "status": "pass" + }, + "VideoIORoundTripTest": { + "feature": "video-round-trip", + "status": "pass" + } + }, + "bootstrap_source": "successful-master-workflow", + "workflow_conclusion": "success" +} diff --git a/docs/website/data/port_status_supplement.json b/docs/website/data/port_status_supplement.json new file mode 100644 index 00000000000..2f2ad1cd4d7 --- /dev/null +++ b/docs/website/data/port_status_supplement.json @@ -0,0 +1,287 @@ +{ + "skip_reasons": [ + { + "test": "CameraApiTest", + "reason": "The unattended runner cannot respond to operating-system camera permission prompts or provide stable physical-camera input. The test therefore avoids opening a real session on targets where doing so could hang CI or produce nondeterministic frames.", + "platform_support": "A skipped camera test does not mean the Codename One port is unsupported. Every listed target remains a supported port; camera availability is a separate runtime capability and depends on the device, permissions, and camera backend.", + "verification": "The native camera implementations are compiled in their port builds and exercised with granted permissions on real hardware or an interactive browser. Deterministic API assertions use the synthetic camera backend outside this portability table." + }, + { + "test": "VideoIORoundTripTest", + "reason": "This assertion requires a working video encoder as well as a decoder. Apple simulator and constrained-device runners do not expose a stable encoder to the headless job, so the encode/decode round trip is skipped there.", + "platform_support": "The port remains supported. Video playback and frame decoding are measured separately by VideoIODecodedFramesScreenshotTest; this skip is limited to creating a new encoded video in that CI environment.", + "verification": "Encoder-backed targets run the full counting-frame and audio round trip. Apple media playback and decoding are covered separately, while device-only recording is verified in signed hardware builds." + } + ], + "features": [ + { + "id": "real-camera-capture", + "category": "Hardware and permissions", + "name": "Real camera and media capture", + "description": "Live preview, still capture, and device camera selection through the native camera backend.", + "testing": "Build each native backend, then run permission-granted capture checks on hardware or an interactive browser and verify a real frame and saved image.", + "why_not_automated": "A headless portability run cannot accept consent dialogs, guarantee a camera device, or compare nondeterministic sensor frames.", + "coverage": [ + {"ports": ["android"], "state": "supported", "label": "CameraX", "detail": "Native CameraX backend; runtime permission and hardware required."}, + {"ports": ["ios-gl", "ios-metal", "mac-native"], "state": "supported", "label": "AVFoundation", "detail": "Native AVFoundation backend; signed build, entitlement, permission, and camera hardware required."}, + {"ports": ["javascript"], "state": "conditional", "label": "MediaDevices", "detail": "Browser mediaDevices backend when the page is secure and the user grants access."}, + {"ports": ["linux-x64", "linux-arm64"], "state": "conditional", "label": "Native camera", "detail": "Native desktop camera backend when a compatible host camera is available."}, + {"ports": ["windows-x64", "windows-arm64"], "state": "conditional", "label": "Media Foundation", "detail": "Native Media Foundation camera backend when the host exposes a camera."}, + {"ports": ["watchos", "tvos"], "state": "unavailable", "label": "No camera", "detail": "The target form factor does not expose a Codename One camera-capture backend."} + ] + }, + { + "id": "microphone-recording", + "category": "Hardware and permissions", + "name": "Microphone and live audio recording", + "description": "Audio capture from a physical microphone through the platform media stack.", + "testing": "Use a signed permission-granted build, record a calibrated tone or voice sample, and verify duration, level, and playback on the target device.", + "why_not_automated": "Hosted runners do not provide consistent microphones and operating systems deliberately require interactive consent.", + "coverage": [ + {"ports": ["android", "ios-gl", "ios-metal", "mac-native"], "state": "supported", "label": "Native recorder", "detail": "Native media recorder with runtime permission and physical input."}, + {"ports": ["javascript"], "state": "conditional", "label": "Browser capture", "detail": "Available through browser media capture on a secure origin after consent."}, + {"ports": ["linux-x64", "linux-arm64", "windows-x64", "windows-arm64"], "state": "conditional", "label": "Host audio", "detail": "Available when the native desktop media stack exposes an input device."}, + {"ports": ["watchos", "tvos"], "state": "unavailable", "label": "No suite backend", "detail": "No general-purpose Codename One recording backend is declared for this target."} + ] + }, + { + "id": "ar-motion-hardware", + "category": "Hardware and permissions", + "name": "Live AR and physical motion sensors", + "description": "AR sessions plus accelerometer, gyroscope, and other readings from real hardware.", + "testing": "Run the AR or sensor sample on supported hardware, verify session startup and sensor updates, and compare motion against a controlled physical action.", + "why_not_automated": "Simulators do not provide a real camera pose, AR runtime, or reproducible physical movement; the automated row checks API contracts and unsupported fallbacks instead.", + "coverage": [ + {"ports": ["android"], "state": "conditional", "label": "ARCore / sensors", "detail": "Available on compatible devices with the required vendor services and sensors."}, + {"ports": ["ios-gl", "ios-metal"], "state": "conditional", "label": "ARKit / sensors", "detail": "Available on compatible iPhone or iPad hardware."}, + {"ports": ["watchos"], "state": "conditional", "label": "Motion sensors", "detail": "Motion sensing is form-factor dependent; general AR sessions are not applicable."}, + {"ports": ["javascript"], "state": "conditional", "label": "Browser sensors", "detail": "Browser sensor APIs depend on browser policy, secure context, consent, and hardware."}, + {"ports": ["mac-native", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64", "tvos"], "state": "unavailable", "label": "Fallback contract", "detail": "The portable API reports that no live AR or motion backend is present."} + ] + }, + { + "id": "location-geofencing", + "category": "Device services", + "name": "Location, background location, and geofencing", + "description": "Foreground fixes, monitored regions, and background location delivery.", + "testing": "Install a signed build, grant the appropriate permission level, feed known routes or physically cross a geofence, and verify foreground and background callbacks.", + "why_not_automated": "The result depends on user permission, GPS/radio state, operating-system scheduling, and physical movement outside the hosted runner.", + "coverage": [ + {"ports": ["android", "ios-gl", "ios-metal"], "state": "supported", "label": "Native location", "detail": "Native foreground and background location subject to OS permissions and policy."}, + {"ports": ["mac-native", "watchos"], "state": "conditional", "label": "Apple location", "detail": "Available where the target and entitlement expose Core Location behavior."}, + {"ports": ["javascript"], "state": "conditional", "label": "Geolocation", "detail": "Foreground browser geolocation on a secure origin after consent; background behavior is browser-limited."}, + {"ports": ["linux-x64", "linux-arm64", "windows-x64", "windows-arm64", "tvos"], "state": "unavailable", "label": "No declared backend", "detail": "No complete location and geofencing backend is declared for this portability target."} + ] + }, + { + "id": "push-notifications", + "category": "Cloud and OS services", + "name": "Remote push notifications", + "description": "Registration, token delivery, background receipt, actions, and badges through platform push services.", + "testing": "Use a signed app and real provider credentials, register a device, send from the push service, and verify foreground, background, and launch delivery.", + "why_not_automated": "Push requires certificates or provider keys, an externally reachable service, a uniquely registered installation, and asynchronous OS delivery.", + "coverage": [ + {"ports": ["android"], "state": "supported", "label": "FCM", "detail": "Firebase Cloud Messaging with app credentials and notification permission."}, + {"ports": ["ios-gl", "ios-metal"], "state": "supported", "label": "APNs", "detail": "Apple Push Notification service with signing entitlements and permission."}, + {"ports": ["javascript"], "state": "conditional", "label": "Web Push", "detail": "Supported by compatible browsers on HTTPS with service-worker and provider setup."}, + {"ports": ["mac-native"], "state": "conditional", "label": "Apple entitlement", "detail": "Depends on the signed macOS target and its notification entitlements."}, + {"ports": ["linux-x64", "linux-arm64", "windows-x64", "windows-arm64", "watchos", "tvos"], "state": "unavailable", "label": "No standalone backend", "detail": "No current standalone Codename One remote-push backend is declared for this target."} + ] + }, + { + "id": "in-app-purchases", + "category": "Store services", + "name": "In-app purchases and subscriptions", + "description": "Store product lookup, checkout, receipt restore, subscription state, and management UI.", + "testing": "Create sandbox products, sign with a store account, complete purchase and restore flows, and validate receipts against the store or Commerce backend.", + "why_not_automated": "The flow requires store-side product configuration, signed identities, sandbox accounts, payment UI, and mutable server receipt state.", + "coverage": [ + {"ports": ["android"], "state": "supported", "label": "Play Billing", "detail": "Google Play purchase and subscription flow in a store-installed build."}, + {"ports": ["ios-gl", "ios-metal"], "state": "supported", "label": "StoreKit", "detail": "Apple StoreKit purchase, restore, and subscription flow."}, + {"ports": ["mac-native"], "state": "conditional", "label": "StoreKit", "detail": "Requires a signed Mac App Store configuration and matching products."}, + {"ports": ["javascript", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64", "watchos", "tvos"], "state": "unavailable", "label": "No store adapter", "detail": "No standalone Codename One store-purchase adapter is declared for this target."} + ] + }, + { + "id": "contacts-calendar", + "category": "Personal data", + "name": "Contacts and calendar integration", + "description": "Read or select contacts and create platform calendar entries through protected personal-data APIs.", + "testing": "Populate a device test account, grant access, exercise read/select/write operations, and verify the result in the native contacts or calendar application.", + "why_not_automated": "Access is permission-gated and the expected result lives in private user databases and native UI outside the test process.", + "coverage": [ + {"ports": ["android", "ios-gl", "ios-metal"], "state": "supported", "label": "Native stores", "detail": "Native contacts and calendar services after the user grants access."}, + {"ports": ["mac-native"], "state": "conditional", "label": "Apple services", "detail": "Availability depends on the macOS target, entitlement, and user account."}, + {"ports": ["javascript", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64", "watchos", "tvos"], "state": "unavailable", "label": "No portable store", "detail": "The target does not expose a complete Codename One personal-data backend."} + ] + }, + { + "id": "biometrics", + "category": "Security hardware", + "name": "Biometric authentication and protected secrets", + "description": "Fingerprint, face, or iris authentication bound to platform keystore material.", + "testing": "Enroll biometrics on hardware, run success, cancellation, lockout, and enrollment-change cases, and verify protected-secret invalidation.", + "why_not_automated": "Hosted runners have no enrolled biometric hardware and native prompts are intentionally controlled by the user and secure hardware.", + "coverage": [ + {"ports": ["android"], "state": "supported", "label": "BiometricPrompt", "detail": "Android BiometricPrompt or legacy fingerprint support, backed by Android Keystore."}, + {"ports": ["ios-gl", "ios-metal"], "state": "supported", "label": "LocalAuthentication", "detail": "Face ID or Touch ID through LocalAuthentication and Keychain."}, + {"ports": ["mac-native", "javascript", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64", "watchos", "tvos"], "state": "unavailable", "label": "NOT_AVAILABLE", "detail": "The portable API returns its documented non-supporting fallback."} + ] + }, + { + "id": "nfc", + "category": "Security hardware", + "name": "NFC tags, smart cards, and host card emulation", + "description": "NDEF read/write, tag technology exchange, and platform-dependent card emulation.", + "testing": "Present known physical tags and cards, verify payloads and errors, and use a certified reader for host-card-emulation exchanges.", + "why_not_automated": "NFC requires short-range hardware, physical tags or readers, user presentation, and platform entitlements that hosted runners lack.", + "coverage": [ + {"ports": ["android"], "state": "supported", "label": "Android NFC", "detail": "NDEF, tag technologies, and HCE on compatible hardware."}, + {"ports": ["ios-gl", "ios-metal"], "state": "conditional", "label": "Core NFC", "detail": "NDEF and selected tag technologies; HCE is restricted by iOS version and region."}, + {"ports": ["mac-native", "javascript", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64", "watchos", "tvos"], "state": "unavailable", "label": "NOT_AVAILABLE", "detail": "The API returns its documented non-supporting fallback."} + ] + }, + { + "id": "bluetooth-le", + "category": "Security hardware", + "name": "Bluetooth Low Energy", + "description": "Peripheral discovery, connection, services, characteristics, notifications, and writes through the maintained Bluetooth library.", + "testing": "Use a known peripheral or protocol simulator, scan and connect, then verify characteristic reads, writes, notifications, reconnects, and permission denial.", + "why_not_automated": "Radio state, nearby peripherals, pairing, permissions, and timing are external to the deterministic screenshot runner.", + "coverage": [ + {"ports": ["android", "ios-gl", "ios-metal"], "state": "conditional", "label": "cn1-bluetooth", "detail": "Maintained native library backend on supported phone and tablet hardware."}, + {"ports": ["mac-native", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64"], "state": "conditional", "label": "Host-dependent", "detail": "Desktop hardware support depends on the selected maintained library backend and host adapter."}, + {"ports": ["javascript", "watchos", "tvos"], "state": "unavailable", "label": "No declared backend", "detail": "No maintained general-purpose Bluetooth backend is declared for this target."} + ] + }, + { + "id": "background-execution", + "category": "Lifecycle and scheduling", + "name": "Background fetch and long-running device work", + "description": "Operating-system scheduled callbacks and policy-compliant work while the application is not foregrounded.", + "testing": "Install a signed build, configure the required modes, background or terminate it, and observe callbacks across OS throttling and restart scenarios.", + "why_not_automated": "Scheduling is deliberately nondeterministic, power-policy controlled, entitlement dependent, and often takes longer than a CI job window.", + "coverage": [ + {"ports": ["android", "ios-gl", "ios-metal"], "state": "supported", "label": "Native scheduler", "detail": "Platform background mechanisms subject to OS quotas, permissions, and lifecycle policy."}, + {"ports": ["mac-native"], "state": "conditional", "label": "Target-dependent", "detail": "Availability depends on the macOS application mode and signed capabilities."}, + {"ports": ["javascript", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64", "watchos", "tvos"], "state": "unavailable", "label": "No equivalent contract", "detail": "No equivalent Codename One background-fetch contract is declared for this target."} + ] + }, + { + "id": "device-integrity", + "category": "Security services", + "name": "Root, jailbreak, and hardware-backed attestation", + "description": "Runtime compromise signals plus signed Play Integrity or App Attest tokens.", + "testing": "Use release-like signed builds, compromised and clean devices, fresh server nonces, and backend verification of vendor-signed verdicts.", + "why_not_automated": "Trust verdicts depend on hardware-backed keys, store-distributed builds, vendor services, device state, and an application backend.", + "coverage": [ + {"ports": ["android"], "state": "conditional", "label": "Play Integrity", "detail": "Root signals and optional Google Play Integrity when enabled and verified by a backend."}, + {"ports": ["ios-gl", "ios-metal"], "state": "conditional", "label": "App Attest", "detail": "Jailbreak signals and optional Apple App Attest when enabled and verified by a backend."}, + {"ports": ["mac-native", "javascript", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64", "watchos", "tvos"], "state": "unavailable", "label": "Unsupported fallback", "detail": "No hardware-backed Codename One attestation backend is declared for this target."} + ] + }, + { + "id": "document-gallery-pickers", + "category": "Native UI and data", + "name": "Document, gallery, and native file pickers", + "description": "User-mediated selection of media and documents from platform-owned providers.", + "testing": "Seed platform storage, launch the native picker, select and cancel items, and verify temporary URI or security-scoped access after returning to the app.", + "why_not_automated": "The decisive UI and permissions belong to another process, and hosted runners do not share an identical populated media or document library.", + "coverage": [ + {"ports": ["android", "ios-gl", "ios-metal", "mac-native", "javascript", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64"], "state": "conditional", "label": "Native picker", "detail": "Uses the target's file, document, or browser picker; available types and access rules vary by OS."}, + {"ports": ["watchos", "tvos"], "state": "unavailable", "label": "No general picker", "detail": "The form factor has no general-purpose Codename One document/gallery picker."} + ] + }, + { + "id": "sharing-communications", + "category": "Native UI and data", + "name": "Share sheets, email, SMS, dialing, and external URLs", + "description": "Hand-off to platform applications and user-selected communication targets.", + "testing": "Open each native chooser or handler on a configured device, complete and cancel actions, and verify returned result metadata where the OS supplies it.", + "why_not_automated": "Installed applications, accounts, SIM capability, chooser UI, and user selection are outside the app process and differ per runner.", + "coverage": [ + {"ports": ["android", "ios-gl", "ios-metal"], "state": "supported", "label": "Native intents", "detail": "Native share and communication handlers when the device has a matching service."}, + {"ports": ["mac-native", "javascript", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64"], "state": "conditional", "label": "OS/browser handler", "detail": "Uses an installed desktop handler, browser capability, or portable fallback where available."}, + {"ports": ["watchos", "tvos"], "state": "unavailable", "label": "Form-factor limited", "detail": "No general-purpose Codename One communication chooser is declared for this target."} + ] + }, + { + "id": "native-app-review", + "category": "Store services", + "name": "Native in-app review prompt", + "description": "Store-owned rating prompt with a portable Codename One fallback sheet.", + "testing": "Use a store-eligible build and account, request the prompt under vendor quota rules, and verify fallback behavior separately.", + "why_not_automated": "Apple and Google intentionally decide whether the native prompt appears, so a request cannot deterministically assert visible store UI.", + "coverage": [ + {"ports": ["android"], "state": "supported", "label": "Play Review", "detail": "Google Play In-App Review when the build includes the service."}, + {"ports": ["ios-gl", "ios-metal"], "state": "supported", "label": "StoreKit", "detail": "StoreKit review request subject to Apple's display quota."}, + {"ports": ["mac-native", "javascript", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64", "watchos", "tvos"], "state": "fallback", "label": "Portable fallback", "detail": "Codename One shows its built-in rating sheet when no native prompt is available."} + ] + }, + { + "id": "live-maps", + "category": "External providers", + "name": "Live native and web map providers", + "description": "Provider tiles, credentials, native peers, gestures, and network-delivered map content.", + "testing": "Use valid provider keys on a networked device, load known coordinates, exercise gestures and markers, and confirm provider attribution and fallback behavior.", + "why_not_automated": "Provider keys are secrets, map imagery changes independently, usage may be billed, and native peers or network tiles are not deterministic pixels.", + "coverage": [ + {"ports": ["android", "ios-gl", "ios-metal"], "state": "conditional", "label": "Native provider", "detail": "Native provider when configured, with the portable map renderer as fallback."}, + {"ports": ["javascript"], "state": "conditional", "label": "Web provider", "detail": "Browser map provider with API key and network access, plus portable fallback."}, + {"ports": ["mac-native", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64", "watchos", "tvos"], "state": "fallback", "label": "Portable map", "detail": "Portable vector or tile rendering is used when no native provider is active."} + ] + }, + { + "id": "live-ad-networks", + "category": "External providers", + "name": "Live advertising networks", + "description": "Real provider SDK initialization, inventory requests, consent, click-through, and revenue callbacks.", + "testing": "Use provider test-unit identifiers in a signed build, complete consent flows, and verify fill, impression, click, and lifecycle callbacks.", + "why_not_automated": "Ad inventory, consent state, provider accounts, network policy, and SDK UI are external and nondeterministic; the first table uses deterministic mock ads.", + "coverage": [ + {"ports": ["android", "ios-gl", "ios-metal"], "state": "conditional", "label": "Provider SDK", "detail": "Supported through configured native ad libraries and provider test units."}, + {"ports": ["javascript"], "state": "conditional", "label": "Web integration", "detail": "Depends on the selected web advertising integration and hosting policy."}, + {"ports": ["mac-native", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64", "watchos", "tvos"], "state": "fallback", "label": "Mock/custom", "detail": "The portable ad component can be tested with mock or application-provided content; no bundled live network is claimed."} + ] + }, + { + "id": "external-surfaces-os", + "category": "OS presentation", + "name": "Widgets, Live Activities, and OS-owned surfaces", + "description": "The final operating-system presentation of shared surface documents outside the main app window.", + "testing": "Install the correctly signed app or extension, publish timelines and actions, then inspect the launcher, lock screen, Dynamic Island, notification area, or desktop host.", + "why_not_automated": "The first table checks serialization, rasterization, timelines, and dispatch, but the final surface is rendered by a separate OS process with signing and entitlement requirements.", + "coverage": [ + {"ports": ["android"], "state": "supported", "label": "Widgets/notifications", "detail": "Lowers supported surfaces to Android widgets and ongoing notifications."}, + {"ports": ["ios-gl", "ios-metal"], "state": "conditional", "label": "WidgetKit/ActivityKit", "detail": "Requires supported OS versions, extension packaging, and entitlements."}, + {"ports": ["mac-native", "linux-x64", "linux-arm64"], "state": "conditional", "label": "Desktop surface", "detail": "Uses the desktop floating-window or preview presentation available to the port."}, + {"ports": ["windows-x64", "windows-arm64"], "state": "conditional", "label": "Windows surfaces", "detail": "Floating widgets are supported; Widgets Board integration requires MSIX and Windows App SDK packaging."}, + {"ports": ["javascript"], "state": "fallback", "label": "In-app preview", "detail": "Portable document and rasterizer behavior is available without an OS widget host."}, + {"ports": ["watchos", "tvos"], "state": "unavailable", "label": "No declared lowering", "detail": "No standalone Codename One external-surface lowering is declared for this target."} + ] + }, + { + "id": "assistive-technology", + "category": "OS presentation", + "name": "Real screen-reader and assistive-technology behavior", + "description": "How native accessibility services announce, focus, activate, and navigate the rendered application.", + "testing": "Enable the platform screen reader, traverse representative forms, verify announcements and actions, and repeat with dynamic content and input devices.", + "why_not_automated": "The first table validates semantics and API state, while the final speech, focus order, gestures, and switch-control behavior belong to external OS services.", + "coverage": [ + {"ports": ["android", "ios-gl", "ios-metal", "mac-native", "javascript", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64"], "state": "conditional", "label": "OS assistive tech", "detail": "Semantic output is consumed by the screen reader or accessibility stack available on that OS."}, + {"ports": ["watchos", "tvos"], "state": "conditional", "label": "Form-factor service", "detail": "Behavior depends on the target's accessibility service and navigation model."} + ] + }, + { + "id": "packaging-native-integration", + "category": "Build integration", + "name": "Signing, packaging, entitlements, and native SDK integration", + "description": "Production artifacts, platform metadata, native interfaces, third-party SDKs, and architecture-specific binaries.", + "testing": "Compile each architecture, inspect the generated package, sign with platform credentials, install it, and exercise the integrated native entry point or SDK in its target environment.", + "why_not_automated": "These checks happen before app startup or require private signing identities, store portals, proprietary SDK credentials, and platform-specific source rather than one shared runtime assertion.", + "coverage": [ + {"ports": ["android", "ios-gl", "ios-metal", "mac-native", "javascript", "linux-x64", "linux-arm64", "windows-x64", "windows-arm64", "watchos", "tvos"], "state": "supported", "label": "Target build", "detail": "The port has its own build, packaging, and native-integration path; exact signing and extension capabilities are target specific."} + ] + } + ] +} diff --git a/docs/website/hugo.toml b/docs/website/hugo.toml index 273dae4e820..9a92bdb9f72 100644 --- a/docs/website/hugo.toml +++ b/docs/website/hugo.toml @@ -128,6 +128,12 @@ name = "Compare" url = "/compare/" weight = 24 +[[menu.main]] +parent = "resources" +name = "Port Status" +url = "/port-status/" +weight = 25 + [[menu.main]] parent = "resources" name = "FAQ" @@ -182,12 +188,6 @@ name = "PRICING" url = "/pricing/" weight = 40 -[[menu.main]] -identifier = "port-status" -name = "PORT STATUS" -url = "/port-status/" -weight = 35 - [[menu.main]] identifier = "dashboard" name = "Dashboard" diff --git a/docs/website/layouts/_default/port-status.html b/docs/website/layouts/_default/port-status.html index ce73703e0c1..2e01e7aa5a7 100644 --- a/docs/website/layouts/_default/port-status.html +++ b/docs/website/layouts/_default/port-status.html @@ -1,6 +1,7 @@ {{- define "main" -}} {{- $contract := site.Data.port_status -}} {{- $reports := site.Data.port_status_reports -}} +{{- $supplement := site.Data.port_status_supplement -}} {{- $snapshotTime := now.UTC -}}
    @@ -8,7 +9,7 @@

    Automated compliance report

    {{ .Title }}

    - Every row is backed by one or more tests in the Codename One compliance test suite. + Every row in the automated matrix is backed by one or more tests in the Codename One compliance test suite. A check means every mapped test is successful in the latest available master report for that port.

    @@ -17,6 +18,7 @@

    {{ .Title }}

    {{- range $contract.features -}}{{- $testCount = add $testCount (len .tests) -}}{{- end -}} {{ $testCount }} tests {{ len $contract.ports }} port targets + {{ len $supplement.features }} environment-dependent feature families
    @@ -92,6 +94,89 @@

    {{ .Title }}

  • - - No current report -
    + + {{ $label }} +
    +
    +

    Skipped-test errata

    +

    + A skip describes a limitation of the unattended test environment, not an unsupported Codename One port. + Every skipped result in the table is accounted for below. +

    +
    + {{- range $supplement.skip_reasons }} + {{- $erratum := . -}} + {{- $skippedPortNames := slice -}} + {{- range $contract.ports -}} + {{- $port := . -}} + {{- $report := index $reports .id -}} + {{- with $report -}} + {{- $result := index .tests $erratum.test -}} + {{- with $result -}} + {{- if eq .status "skip" -}}{{- $skippedPortNames = $skippedPortNames | append $port.name -}}{{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- if gt (len $skippedPortNames) 0 }} +
    +

    {{ .test }}

    +

    Skipped on: {{ delimit $skippedPortNames ", " }}.

    +

    Why: {{ .reason }}

    +

    Port support: {{ .platform_support }}

    +

    How it is tested: {{ .verification }}

    +
    + {{- end }} + {{- end }} +
    +
    + +
    +
    +

    Environment-dependent coverage

    +

    Features verified outside the deterministic suite

    +

    + These are the remaining platform-integration feature families whose decisive behavior depends on hardware, + permission UI, signing, store or provider accounts, external services, or an operating-system process. + Each row states how support is delivered, how it is verified, and why it cannot honestly be counted as a + deterministic result in the automated table above. An unavailable cell applies only to that integration; + it does not mean the Codename One port itself is unsupported. +

    +
    +
    + Supported backend + Hardware, account, or configuration dependent + Portable fallback + No declared backend +
    +
    + + + + + {{- range $contract.ports }}{{- end }} + + + + {{- range $supplement.features }} + {{- $feature := . -}} + + + {{- range $contract.ports -}} + {{- partial "port-status-manual-status.html" (dict "feature" $feature "port" .) -}} + {{- end -}} + + {{- end }} + +
    Feature and testing logic{{ .name }}
    + {{ .category }} + {{ .name }} +

    {{ .description }}

    +
    + Testing logic and exclusion +

    Verification: {{ .testing }}

    +

    Why it is outside the suite: {{ .why_not_automated }}

    +
    +
    +
    +
    +
    +
    +
    +

    Deployment support contract

    +

    Supported platforms, architectures, and tested environments

    +

    + The compliance matrix uses {{ len $contract.ports }} CI targets, not {{ len $contract.ports }} distinct platforms: + renderer and CPU variants have separate columns so regressions cannot hide behind a combined result. + A deployment floor means the toolchain can target that release. Runtime CI evidence is stated separately, + because compiling for an older release is not proof that the application was launched there. +

    +
    +
    + + + + + + + + + + + + {{- range $support.deployment_support }} + + + + + + + + {{- end }} + +
    PlatformArchitecturesDeclared rangeRuntime CI evidenceFloor evidence and limits
    {{ .platform }}{{ .support }}{{ .architectures }}{{ .declared_range }}{{ .ci_evidence }}{{ .floor_evidence }}
    +
    +
    +

    JavaScript browser engines

    +

    + Chromium runs the full visual compliance suite. The smaller nightly lifecycle check boots the same + generated application in all three major browser engines and records the exact engine version here. + A browser family is not assigned an old minimum version until that version is actually exercised. +

    +
    + {{- range $environment.browsers }} +
    +

    {{ .name }}

    +

    {{ .engine_version }}

    +

    {{ .coverage }}

    + {{ cond (eq .status "pass") "Passed" (cond (eq .status "fail") "Failed" "Awaiting nightly evidence") }} +
    + {{- end }} +
    +
    +
    +
    Passed Partial or skipped @@ -177,6 +234,44 @@

    Features verified outside the deterministic suite

    +
    +
    +

    Measured performance

    +

    {{ $support.benchmark.title }}

    +

    + {{ $support.benchmark.machine }}; {{ $support.benchmark.configuration }}. + {{ $support.benchmark.result }}. {{ $support.benchmark.explanation }} +

    +
    +
    + {{- range $support.benchmark.rows }} +
    + {{ .ratio }} + {{ .name }} +
    + {{- end }} +
    +

    Flutter comparison publication contract

    +

    + Startup, size, memory, and Flutter/Dart results will appear only after the nightly job can produce a matched, + reproducible result. Until then this page makes no Flutter performance claim. That avoids comparing a complete + Flutter application with a runtime-only Codename One binary, or comparing measurements from different machines. +

    +
    + + + + {{- range $support.benchmark.comparative_metrics }} + + {{- end }} + +
    MetricRequired testing logic
    {{ .metric }}{{ .publication_rule }}
    +
    +

    + Benchmark source and reproducibility notes +

    +
    +