flutter_flutter/packages/flutter/test/widgets/stretch_effect_test.dart
Dev TtangKong f604188a45
Retry "Implements the Android native stretch effect as a fragment shader (Impeller-only)." (#173885)
This PR retries the previously reverted PR #169293.

> [!NOTE]
> This feature was originally intended to be Impeller-only, and it was
agreed that no additional engine changes were necessary. However, during
testing on the Metal backend, a shader loading issue occurred. In my
view, this seems to be a simple problem caused by the shader not being
included in the engine’s runtime_stages.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

---------

Co-authored-by: Tong Mu <dkwingsmt@users.noreply.github.com>
Co-authored-by: Kate Lovett <katelovett@google.com>
2025-08-27 22:17:05 +00:00

57 lines
1.9 KiB
Dart

// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file is run as part of a reduced test set in CI on Mac and Windows
// machines.
@Tags(<String>['reduced-test-set'])
library;
import 'dart:ui' as ui;
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
// `StretchingOverscrollIndicator` uses a different algorithm when
// shader is available, therefore the tests must be different depending
// on shader support.
final bool shaderSupported = ui.ImageFilter.isShaderFilterSupported;
testWidgets(
'Stretch effect covers full viewport',
(WidgetTester tester) async {
// This test verifies that when the stretch effect is applied to a scrollable widget,
// it should cover the entire scrollable area (e.g., full height of the scroll view),
// even if the actual content inside has a smaller height.
//
// Without this behavior, the shader is clipped only to the content area,
// causing the stretch effect to render incorrectly or be invisible
// when the content doesn't fill the scroll view.
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: StretchEffect(
stretchStrength: 1,
axis: Axis.vertical,
child: Stack(
alignment: Alignment.topCenter,
children: <Widget>[
Container(height: 100),
Container(height: 50, color: const Color.fromRGBO(255, 0, 0, 1)),
],
),
),
),
);
await expectLater(
find.byType(StretchEffect),
matchesGoldenFile('stretch_effect_covers_full_viewport.png'),
);
},
// Skips this test when fragment shaders are not used.
skip: !shaderSupported,
);
}