Skip to content

Adding support for sticky headers#4829

Merged
shai-almog merged 7 commits intomasterfrom
sticky-headers-support-4807
Apr 30, 2026
Merged

Adding support for sticky headers#4829
shai-almog merged 7 commits intomasterfrom
sticky-headers-support-4807

Conversation

@shai-almog
Copy link
Copy Markdown
Collaborator

Fixed #4807

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented Apr 30, 2026

✅ JavaScript-port screenshot tests passed.

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented Apr 30, 2026

Compared 85 screenshots: 85 matched.

Native Android coverage

  • 📊 Line coverage: 9.70% (5259/54213 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 7.63% (25849/338985), branch 3.48% (1132/32520), complexity 4.50% (1403/31156), method 7.88% (1147/14561), class 12.89% (251/1948)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 9.70% (5259/54213 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 7.63% (25849/338985), branch 3.48% (1132/32520), complexity 4.50% (1403/31156), method 7.88% (1147/14561), class 12.89% (251/1948)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 1252.000 ms
Base64 CN1 encode 194.000 ms
Base64 encode ratio (CN1/native) 0.155x (84.5% faster)
Base64 native decode 1042.000 ms
Base64 CN1 decode 222.000 ms
Base64 decode ratio (CN1/native) 0.213x (78.7% faster)
Image encode benchmark status skipped (SIMD unsupported)

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented Apr 30, 2026

Compared 10 screenshots: 10 matched.
✅ Native iOS screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 317 seconds

Build and Run Timing

Metric Duration
Simulator Boot 79000 ms
Simulator Boot (Run) 2000 ms
App Install 24000 ms
App Launch 6000 ms
Test Execution 301000 ms

Resolves the forbidden PMD violations on StickyHeaderContainer
(ForLoopCanBeForeach, CompareObjectsWithEquals, ControlStatementBraces)
and adds StickyHeaderScreenshotTest to the JS-port chunk-decode skip
list since its 86KB PNG output triggers the same logcat-style chunk
truncation that other large screenshots hit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 30, 2026

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

shai-almog and others added 5 commits April 30, 2026 08:32
The Cn1ssDeviceRunner skip lists don't actually short-circuit my test
on the JS port (other JS-skipped animation tests fail to produce a
payload for unrelated reasons), so my 86KB PNG still gets emitted and
fails to decode through the JS port's chunked-log truncation. Override
runTest to early-return on HTML5, matching the pattern used by
OrientationLockScreenshotTest.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
StickyHeaderContainer now plays a time-driven swap animation when the
active section changes - either a directional slide (forward scroll
slides up, reverse scroll slides down) or a cross-fade. Duration is
configurable via setTransitionDurationMillis (default 250ms); set
TRANSITION_NONE to keep the prior instantaneous swap.

The animation is driven by AnimationTime, so a slow scroll surfaces
every intermediate frame at full duration while a fast scroll lets
the latest swap supersede earlier in-flight ones. Implementation paints
the outgoing header from a captured Image overlay via paintGlass while
shifting the live stickyHost through layout/opacity.

Tests
- Move StickyHeaderContainerTest from the obsolete tests/core
  AbstractTest harness into maven/core-unittests using JUnit 5 +
  UITestBase. Coverage extends to transition style/duration getters,
  setters, validation, animation progress and TRANSITION_NONE.
- Add StickyHeaderSlideTransitionScreenshotTest and
  StickyHeaderFadeTransitionScreenshotTest: each holds the scroll just
  past one section boundary and steps AnimationTime through the swap
  duration, capturing 6 frames of progress. Pair with the existing
  StickyHeaderScreenshotTest (fast scroll sweep) for a fast-vs-slow
  side-by-side. Common scaffold lives in
  AbstractStickyHeaderScreenshotTest.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 10s deadline was tuned for the JS port's tight 150s browser
lifetime; on Android the chunked-log emission is intentionally
rate-limited (500-byte chunks throttled at 30ms each to keep logcat
from dropping lines), so a 60KB PNG plus its JPEG preview legitimately
takes ~6s per appearance. Dual-appearance theme tests like
SpanLabelTheme and DarkLightShowcaseTheme need ~12s for both captures
and started intermittently tripping the cap on master.

Keep the JS port at 10s (a stuck test there would still consume the
whole browser-lifetime budget) and bump iOS / Android / JavaSE to 30s,
which only matters for genuinely stuck tests and gives the slowest
theme captures comfortable headroom.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 30ms value held against the existing ~10-15 test workload but the
sticky-headers PR adds three more screenshot tests, and the JDK 21
Android entry started flaking again with one random theme stream
truncated per run (SwitchTheme_light decoded short on the latest run,
matching the earlier MultiButtonTheme_dark / SlideHorizontalTransitionTest
pattern from #4253). Following the same approach used when the
animation tests landed, bump the inter-chunk sleep to 50ms; the new 30s
per-test deadline on native platforms (introduced in the previous
commit) gives the slower emission comfortable headroom even for dual-
appearance theme tests (~14s for two captures vs the 30s cap).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Captured from CI run #25153463284 (Android, all three matrix entries
green) and #25153463308 (iOS UI build scripts, green). These are
device-rendered references because the JavaSE simulator and the
Android/iOS native renderers do not produce pixel-identical output;
locally generated images would diff against the on-device captures.

Files:
  scripts/android/screenshots/StickyHeaderScreenshotTest.png
  scripts/android/screenshots/StickyHeaderSlideTransitionScreenshotTest.png
  scripts/android/screenshots/StickyHeaderFadeTransitionScreenshotTest.png
  scripts/ios/screenshots/StickyHeaderScreenshotTest.png
  scripts/ios/screenshots/StickyHeaderSlideTransitionScreenshotTest.png
  scripts/ios/screenshots/StickyHeaderFadeTransitionScreenshotTest.png

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shai-almog shai-almog merged commit 45b4001 into master Apr 30, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RFE: official support for StickyHeaders

1 participant