Skip to content

Final 1.0.0 QA: pixel + performance regression suites + live dusk validation#96

Merged
anilcancakir merged 6 commits into
masterfrom
test/final-qa-suites
Jun 8, 2026
Merged

Final 1.0.0 QA: pixel + performance regression suites + live dusk validation#96
anilcancakir merged 6 commits into
masterfrom
test/final-qa-suites

Conversation

@anilcancakir

@anilcancakir anilcancakir commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Final 1.0.0 QA gate — pixel-perfect + performance regression suites + live dusk validation

Last gate before tagging 1.0.0. Stood up a fresh consumer app driven by fluttersdk_dusk, exercised every feature, and added the two coverage dimensions the prior QA pass lacked. Zero behavioral regressions found → no lib/ changes.

New permanent suites (raise the suite 1253 → 1303)

  • test/pixel/ (24 tests) — px-exact geometry (getRect/getSize/getTopLeft, epsilon 0.5) + exact color via renderObject decoration. Asserts documented Tailwind v3 values: p-4=16, px-3=12, w-10=40, max-w-prose=512, rounded-lg=8, text-4xl=36, bg-blue-500=#3B82F6, dark-mode resolution, etc. No golden files.
  • test/interaction/ (24 tests) — tap callbacks, hover (mouse gesture), focus/disabled, responsive breakpoints (tester.view), animations (16ms pump, never pumpAndSettle), WPopover/WSelect overlay open/close.
  • test/performance/ — parser cache hit/miss speedup ratio gate (≥3×; ~26× measured) + report-only large-tree pump timing. Ratio not absolute-µs (CI-safe).

Live dusk validation

Fresh /tmp/wind_final_qa app booted on Chrome; all 11 gallery routes navigated + screenshotted; dusk:snap --includeEnrichers confirmed the live wind: enricher 7-field block (className/breakpoint/brightness/platform/states/bgColor); manual visual compare of card/alerts/badges/buttons/form/widget-roster — all faithful. (Evidence + report under the gitignored plan dir.)

Docs

  • CHANGELOG ### Quality entry for the final-QA sign-off.
  • Documented the one edge found (I01: a disabled outer WAnchor doesn't suppress hover: on a nested WDiv's own hover: — WDiv auto-wraps in a non-disabled anchor) in tailwind-divergence.md. P3 follow-up, not a 1.0.0 blocker.

Verification

  • dart analyze 0 issues · dart format no diff · flutter test 1303 pass · coverage 90.4% · flutter pub publish --dry-run 0 warnings · pana 160/160 (is:wasm-ready).
  • Planned via /ac:plan → executed via /ac:execute (complex, auto); deep-review + oracle both APPROVED.

Verdict: production-ready for 1.0.0.

Summary by CodeRabbit

  • Tests

    • Added comprehensive regression test suites covering pixel-perfect rendering, animations, overlays, interaction states, responsive design, typography, spacing, borders, and parser performance benchmarks.
  • Documentation

    • Updated changelog with final 1.0.0 QA gate details.
    • Added clarification on state-shadowing behavior in styling guide for nested disabled components.

24 tests asserting documented Tailwind v3 px/hex output via getRect/getSize +
renderObject decoration color (no golden files). Confirms wind renders every
characterized spacing/sizing/radius/ring/border/typography/color token exactly;
F05/F11 divergences asserted at documented values.
…uite

24 in-process interaction tests: tap callbacks, hover via mouse gesture, focus/
disabled, breakpoint flips via tester.view, animate-* via 16ms pump (no
pumpAndSettle), WPopover/WSelect overlay open/close.
Asserts the cache hit path is >=3x faster than cold (ratio gate, ~26x actual),
plus report-only PERF: lines for cache totals and large-tree pump time.
CHANGELOG Quality entry for the new pixel/interaction/performance regression
suites + live dusk validation (no regressions found). Document the disabled-
WAnchor-shadowed-by-nested-WDiv hover edge in tailwind-divergence.md.
Both reviewers flagged the weak isNot(72.0) assertion; assert text-7xl falls
back to the baseline default size (proving the F11 no-op) instead of only
ruling out Tailwind's 72px.
Copilot AI review requested due to automatic review settings June 8, 2026 15:36
@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

PR adds documentation updates and eight new test files covering interaction behavior (hover, focus, disabled states, animations, overlays, callbacks), responsive breakpoints, parser performance benchmarks, and pixel-exact rendering validation for colors, spacing, typography, and borders.

Changes

Wind UI Test Coverage Expansion

Layer / File(s) Summary
Documentation and test scope
CHANGELOG.md, skills/wind-ui/references/tailwind-divergence.md
Changelog entry describes new permanent regression suites in test/pixel/, test/interaction/, and test/performance/. Divergence doc adds guidance on WAnchor state-shadowing behavior when a disabled parent's hover: styles fire on nested WDiv due to internal auto-wrapping.
Interaction and responsive behavior tests
test/interaction/animation_overlay_test.dart, test/interaction/hover_focus_disabled_test.dart, test/interaction/responsive_breakpoints_test.dart, test/interaction/tap_callbacks_test.dart
Four test files exercise Widget interaction states via shared wrapWithTheme helper and cache clearing: animation/overlay component rendering and close callbacks; hover/focus/disabled/active pseudo-class color resolution; responsive breakpoint visibility and style gating; tap/change callbacks for buttons, anchors, checkboxes, selectors, and date pickers under enabled/disabled/loading conditions.
Parser performance benchmarks
test/performance/parser_perf_test.dart
Benchmark suite clears WindParser cache before tests, measures cold-vs-warm parse timing with 3× speedup gate, verifies stable cache size across warm iterations, and pumps a large ~400-node WDiv tree to validate widget rendering smoke-test and timing.
Pixel-perfect rendering validation
test/pixel/color_pixel_test.dart, test/pixel/radius_ring_border_pixel_test.dart, test/pixel/spacing_sizing_pixel_test.dart, test/pixel/typography_pixel_test.dart
Four test files pump themed Widgets and extract rendered properties to assert exact pixel values: background colors (bg-blue-500#3B82F6, dark mode variants); border-radius (rounded-lg → 8px, rounded-2xl → 16px), border-width, and ring-width via BoxShadow; padding/margin/gap/width/height/max-width via rendered geometry; font sizes and text colors via RenderParagraph.style.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • fluttersdk/wind#94: The pixel-perfect test suite (spacing_sizing_pixel_test.dart) validates that max-w-prose resolves to 512px, directly corresponding to the SizingParser code change in that PR.

Poem

🐰 A Flutter of Tests

Tests cascade like garden rows,
Pixel-perfect, interaction flows,
Performance benchmarks measure fast,
Quality gates that hold steadfast! 🎨✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding final QA validation artifacts (pixel, performance, and interaction test suites plus live dusk validation) for the 1.0.0 release.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/final-qa-suites

Comment @coderabbitai help to get the list of available commands and usage tips.

@sentry

sentry Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds final 1.0.0 QA regression coverage to the Wind package by introducing new pixel-precision, interaction, and performance test suites, plus documentation/sign-off updates, without modifying lib/ runtime code.

Changes:

  • Added new test/pixel/ coverage validating exact rendered geometry, typography, and colors via render-tree inspection (no golden files).
  • Added new test/interaction/ coverage for taps, hover/focus/disabled state behavior, responsive breakpoints, and overlay open/close flows.
  • Added new test/performance/ coverage gating parser cache warm-vs-cold speedup ratio and reporting large-tree pump timings; updated docs (tailwind divergence + changelog).

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/pixel/typography_pixel_test.dart New pixel tests for rendered font sizes and text color.
test/pixel/spacing_sizing_pixel_test.dart New pixel tests for padding/margin/gap and sizing/max-width behavior.
test/pixel/radius_ring_border_pixel_test.dart New pixel tests for border radius, border widths, and ring spread widths.
test/pixel/color_pixel_test.dart New pixel tests for background colors including dark-mode resolution.
test/performance/parser_perf_test.dart New perf gate for parser cache speedup ratio + report-only large-tree pump timing.
test/interaction/tap_callbacks_test.dart New interaction tests covering tap callbacks across common widgets.
test/interaction/responsive_breakpoints_test.dart New interaction tests for breakpoint gating and active breakpoint resolution.
test/interaction/hover_focus_disabled_test.dart New interaction tests for hover/focus/disabled and manual active: state resolution.
test/interaction/animation_overlay_test.dart New interaction tests for animation wrappers and overlay widgets (popover/select).
skills/wind-ui/references/tailwind-divergence.md Documents an additional state-shadowing edge case (disabled ancestor vs inner hover).
CHANGELOG.md Adds a 1.0.0 QA gate entry describing the new regression suites and validation.

Comment on lines +41 to +46
/// Reads the `BoxDecoration` from the first `RenderDecoratedBox` the WDiv emits.
BoxDecoration _decorationOf(WidgetTester tester) {
final render = tester.renderObject<RenderDecoratedBox>(
find.byType(DecoratedBox).first,
);
return render.decoration as BoxDecoration;
Comment on lines +26 to +31
/// Reads the `BoxDecoration` from the first `RenderDecoratedBox` the WDiv emits.
BoxDecoration _decorationOf(WidgetTester tester) {
final render = tester.renderObject<RenderDecoratedBox>(
find.byType(DecoratedBox).first,
);
return render.decoration as BoxDecoration;
Comment on lines +208 to +212
// w-1/2 wraps in FractionallySizedBox(widthFactor: 0.5).
expect(find.byType(FractionallySizedBox), findsOneWidget);
final fsb = tester.widget<FractionallySizedBox>(
find.byType(FractionallySizedBox),
);
Comment thread test/performance/parser_perf_test.dart Outdated
Comment on lines +84 to +108
// 2. Cold bench: clear the cache before each iteration.
final coldWatch = Stopwatch()..start();
for (var i = 0; i < _kBenchIterations; i++) {
WindParser.clearCache();
WindParser.parse(_kBenchClassName, capturedCtx);
}
coldWatch.stop();
final coldTotal = coldWatch.elapsedMicroseconds;

// 3. Verify the cache received exactly one entry after the last miss.
expect(WindParser.cacheSize, 1,
reason: 'cold bench must leave one cache entry after the last miss');

// 4. Warm bench: prime the cache once, then hit it [_kBenchIterations]
// times without clearing between iterations.
WindParser.clearCache();
WindParser.parse(_kBenchClassName, capturedCtx); // prime
final cacheSizeAfterPrime = WindParser.cacheSize;

final warmWatch = Stopwatch()..start();
for (var i = 0; i < _kBenchIterations; i++) {
WindParser.parse(_kBenchClassName, capturedCtx);
}
warmWatch.stop();
final warmTotal = warmWatch.elapsedMicroseconds;

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
test/interaction/animation_overlay_test.dart (1)

7-14: ⚡ Quick win

Consider extracting wrapWithTheme to a shared test helper.

The wrapWithTheme helper is duplicated identically across four test files (animation_overlay_test.dart, hover_focus_disabled_test.dart, responsive_breakpoints_test.dart, and tap_callbacks_test.dart). Extracting it to a shared location (e.g., test/helpers/test_helpers.dart) would eliminate duplication and provide a single source of truth for test widget wrapping.

♻️ Proposed refactor

Create test/helpers/test_helpers.dart:

import 'package:flutter/material.dart';
import 'package:fluttersdk_wind/fluttersdk_wind.dart';

/// Wraps [child] in a MaterialApp + WindTheme + Scaffold so className-styled
/// widgets resolve their styling context.
Widget wrapWithTheme(Widget child) {
  return MaterialApp(
    home: WindTheme(
      data: WindThemeData(),
      child: Scaffold(body: child),
    ),
  );
}

Then update all four test files to import and use it:

import '../helpers/test_helpers.dart';
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/interaction/animation_overlay_test.dart` around lines 7 - 14, The helper
function wrapWithTheme is duplicated across four tests
(animation_overlay_test.dart, hover_focus_disabled_test.dart,
responsive_breakpoints_test.dart, tap_callbacks_test.dart); extract it into a
shared test helper file (e.g., test/helpers/test_helpers.dart) that exports the
same MaterialApp+WindTheme+Scaffold wrapper, then replace the local definitions
in each of the four test files with a single import (e.g., import
'../helpers/test_helpers.dart';) so all tests call the centralized wrapWithTheme
function.
test/performance/parser_perf_test.dart (1)

63-64: 💤 Low value

Comment and assertion mismatch on "at least 3x" speedup.

The comments state the cache "must deliver at least a 3x speedup" (lines 63-64, 122), which implies ratio >= 3. However, the assertion at line 125 uses lessThan(coldTotal ~/ 3), which enforces warmTotal < coldTotal / 3, i.e., ratio > 3 (strictly greater than 3x).

For exactly 3× speedup, the test would fail. Consider either:

  • Update comments to say "more than 3x" to match the code, OR
  • Change the assertion to lessThanOrEqualTo(coldTotal ~/ 3) to accept exactly 3x

In practice, the measured ~26× speedup makes this mismatch inconsequential, but aligning the comment with the code improves clarity.

Proposed fix: align comment with code
-      // 7. Ratio gate: warm must be at least 3x faster than cold.
+      // 7. Ratio gate: warm must be more than 3x faster than cold.

Or align code with comment:

       expect(
         warmTotal,
-        lessThan(coldTotal ~/ 3),
+        lessThanOrEqualTo(coldTotal ~/ 3),
         reason: 'warm cache must be at least 3x faster than cold '

Also applies to: 122-128

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/performance/parser_perf_test.dart` around lines 63 - 64, The comment
asserts the cache "must deliver at least a 3x speedup" but the test uses a
strict check warmTotal < coldTotal / 3 (lessThan(coldTotal ~/ 3)), which rejects
exactly 3×; update the assertion that references warmTotal and coldTotal (the
lessThan(coldTotal ~/ 3) check) to use lessThanOrEqualTo(coldTotal ~/ 3) so it
accepts exactly 3×, and make the same change for the duplicate assertion block
around the other reference (lines mentioned in the review).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/interaction/animation_overlay_test.dart`:
- Around line 7-14: The helper function wrapWithTheme is duplicated across four
tests (animation_overlay_test.dart, hover_focus_disabled_test.dart,
responsive_breakpoints_test.dart, tap_callbacks_test.dart); extract it into a
shared test helper file (e.g., test/helpers/test_helpers.dart) that exports the
same MaterialApp+WindTheme+Scaffold wrapper, then replace the local definitions
in each of the four test files with a single import (e.g., import
'../helpers/test_helpers.dart';) so all tests call the centralized wrapWithTheme
function.

In `@test/performance/parser_perf_test.dart`:
- Around line 63-64: The comment asserts the cache "must deliver at least a 3x
speedup" but the test uses a strict check warmTotal < coldTotal / 3
(lessThan(coldTotal ~/ 3)), which rejects exactly 3×; update the assertion that
references warmTotal and coldTotal (the lessThan(coldTotal ~/ 3) check) to use
lessThanOrEqualTo(coldTotal ~/ 3) so it accepts exactly 3×, and make the same
change for the duplicate assertion block around the other reference (lines
mentioned in the review).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e893af2b-3e63-4d45-99af-8146e97a9c71

📥 Commits

Reviewing files that changed from the base of the PR and between c817f15 and 1362f5a.

📒 Files selected for processing (11)
  • CHANGELOG.md
  • skills/wind-ui/references/tailwind-divergence.md
  • test/interaction/animation_overlay_test.dart
  • test/interaction/hover_focus_disabled_test.dart
  • test/interaction/responsive_breakpoints_test.dart
  • test/interaction/tap_callbacks_test.dart
  • test/performance/parser_perf_test.dart
  • test/pixel/color_pixel_test.dart
  • test/pixel/radius_ring_border_pixel_test.dart
  • test/pixel/spacing_sizing_pixel_test.dart
  • test/pixel/typography_pixel_test.dart

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Comment on lines +27 to +31
BoxDecoration _decorationOf(WidgetTester tester) {
final render = tester.renderObject<RenderDecoratedBox>(
find.byType(DecoratedBox).first,
);
return render.decoration as BoxDecoration;
Comment on lines +41 to +46
/// Reads the `BoxDecoration` from the first `RenderDecoratedBox` the WDiv emits.
BoxDecoration _decorationOf(WidgetTester tester) {
final render = tester.renderObject<RenderDecoratedBox>(
find.byType(DecoratedBox).first,
);
return render.decoration as BoxDecoration;
… in cold/warm bench

Address Copilot review on PR #96:
- _decorationOf in color/radius_ring_border pixel tests now scopes
  find.byType(DecoratedBox) to descendants of the WDiv under test, so
  an app-shell DecoratedBox can never shadow the asserted decoration.
- w-1/2 FractionallySizedBox assertion scoped to the half-keyed WDiv.
- parser_perf cold bench moves clearCache() outside the measured window
  and times only parse() per iteration; warm bench mirrors the
  per-iteration start/stop so the speedup ratio compares like with like.
@anilcancakir anilcancakir merged commit 42210ca into master Jun 8, 2026
8 checks passed
@anilcancakir anilcancakir deleted the test/final-qa-suites branch June 8, 2026 18:07
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.

2 participants