[web] Remove HTML renderer from framework tests (#162038)

- Cleanup many HTML special cases and skips in framework tests.
- Update some dartdocs that referred to the HTML renderer.

For reviewers: it may help if you set `Hide whitespace` to true in
Github. It will help you skip through all the formatting/indentation
changes.
This commit is contained in:
Mouad Debbar 2025-01-24 16:33:27 -05:00 committed by GitHub
parent b82e9022a3
commit 3755fd1f6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
48 changed files with 924 additions and 1320 deletions

View File

@ -22,9 +22,6 @@ import 'material.dart';
/// Begin a Material 3 ink sparkle ripple, centered at the tap or click position /// Begin a Material 3 ink sparkle ripple, centered at the tap or click position
/// relative to the [referenceBox]. /// relative to the [referenceBox].
/// ///
/// This effect relies on a shader and therefore is unsupported on the Flutter
/// Web HTML backend.
///
/// To use this effect, pass an instance of [splashFactory] to the /// To use this effect, pass an instance of [splashFactory] to the
/// `splashFactory` parameter of either the Material [ThemeData] or any /// `splashFactory` parameter of either the Material [ThemeData] or any
/// component that has a `splashFactory` parameter, such as buttons: /// component that has a `splashFactory` parameter, such as buttons:

View File

@ -335,9 +335,8 @@ class _ZoomEnterTransition extends StatefulWidget {
class _ZoomEnterTransitionState extends State<_ZoomEnterTransition> class _ZoomEnterTransitionState extends State<_ZoomEnterTransition>
with _ZoomTransitionBase<_ZoomEnterTransition> { with _ZoomTransitionBase<_ZoomEnterTransition> {
// See SnapshotWidget doc comment, this is disabled on web because the HTML backend doesn't // See SnapshotWidget doc comment, this is disabled on web because the canvaskit backend uses a
// support this functionality and the canvaskit backend uses a single thread for UI and raster // single thread for UI and raster work which diminishes the impact of this performance improvement.
// work which diminishes the impact of this performance improvement.
@override @override
bool get useSnapshot => !kIsWeb && widget.allowSnapshotting; bool get useSnapshot => !kIsWeb && widget.allowSnapshotting;
@ -447,9 +446,8 @@ class _ZoomExitTransitionState extends State<_ZoomExitTransition>
with _ZoomTransitionBase<_ZoomExitTransition> { with _ZoomTransitionBase<_ZoomExitTransition> {
late _ZoomExitTransitionPainter delegate; late _ZoomExitTransitionPainter delegate;
// See SnapshotWidget doc comment, this is disabled on web because the HTML backend doesn't // See SnapshotWidget doc comment, this is disabled on web because the canvaskit backend uses a
// support this functionality and the canvaskit backend uses a single thread for UI and raster // single thread for UI and raster work which diminishes the impact of this performance improvement.
// work which diminishes the impact of this performance improvement.
@override @override
bool get useSnapshot => !kIsWeb && widget.allowSnapshotting; bool get useSnapshot => !kIsWeb && widget.allowSnapshotting;

View File

@ -99,11 +99,8 @@ class SnapshotController extends ChangeNotifier {
/// defaults to [SnapshotMode.normal] which will throw an exception if a /// defaults to [SnapshotMode.normal] which will throw an exception if a
/// platform view is encountered. /// platform view is encountered.
/// ///
/// * The snapshotting functionality of this widget is not supported on the HTML /// * On the CanvasKit backend of Flutter, the performance of using this widget may regress
/// backend of Flutter for the Web. Setting [SnapshotController.allowSnapshotting] to true /// performance due to the fact that both the UI and engine share a single thread.
/// may cause an error to be thrown. On the CanvasKit backend of Flutter, the
/// performance of using this widget may regress performance due to the fact
/// that both the UI and engine share a single thread.
class SnapshotWidget extends SingleChildRenderObjectWidget { class SnapshotWidget extends SingleChildRenderObjectWidget {
/// Create a new [SnapshotWidget]. /// Create a new [SnapshotWidget].
/// ///

View File

@ -12,7 +12,7 @@ import 'dart:math' as math;
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart' show isCanvasKit; import 'package:flutter/foundation.dart' show isSkwasm;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -20,7 +20,7 @@ import 'package:flutter_test/flutter_test.dart';
import '../impeller_test_helpers.dart'; import '../impeller_test_helpers.dart';
// TODO(yjbanov): on the web text rendered with perspective produces flaky goldens: https://github.com/flutter/flutter/issues/110785 // TODO(yjbanov): on the web text rendered with perspective produces flaky goldens: https://github.com/flutter/flutter/issues/110785
final bool skipPerspectiveTextGoldens = isBrowser && !isCanvasKit; final bool skipPerspectiveTextGoldens = isBrowser && isSkwasm;
// A number of the hit tests below say "warnIfMissed: false". This is because // A number of the hit tests below say "warnIfMissed: false". This is because
// the way the CupertinoPicker works, the hits don't actually reach the labels, // the way the CupertinoPicker works, the hits don't actually reach the labels,

View File

@ -928,10 +928,7 @@ void main() {
// regular font. However, when using the test font, "Cancel" becomes 2 lines which // regular font. However, when using the test font, "Cancel" becomes 2 lines which
// is why the height we're verifying for "Cancel" is larger than "OK". // is why the height we're verifying for "Cancel" is larger than "OK".
if (!kIsWeb || isSkiaWeb) { expect(tester.getSize(find.text('The Title')), equals(const Size(270.0, 132.0)));
// https://github.com/flutter/flutter/issues/99933
expect(tester.getSize(find.text('The Title')), equals(const Size(270.0, 132.0)));
}
expect(tester.getTopLeft(find.text('The Title')), equals(const Offset(265.0, 80.0 + 24.0))); expect(tester.getTopLeft(find.text('The Title')), equals(const Offset(265.0, 80.0 + 24.0)));
expect( expect(
tester.getSize(find.widgetWithText(CupertinoDialogAction, 'Cancel')), tester.getSize(find.widgetWithText(CupertinoDialogAction, 'Cancel')),

View File

@ -109,50 +109,45 @@ void main() {
); );
} }
testWidgets( testWidgets('chevrons point to the correct side', (WidgetTester tester) async {
'chevrons point to the correct side', // Add enough TestBoxes to need 3 pages.
(WidgetTester tester) async { final List<Widget> children = List<Widget>.generate(15, (int i) => const TestBox());
// Add enough TestBoxes to need 3 pages. await tester.pumpWidget(
final List<Widget> children = List<Widget>.generate(15, (int i) => const TestBox()); CupertinoApp(
await tester.pumpWidget( home: Center(
CupertinoApp( child: CupertinoTextSelectionToolbar(
home: Center( anchorAbove: const Offset(50.0, 100.0),
child: CupertinoTextSelectionToolbar( anchorBelow: const Offset(50.0, 200.0),
anchorAbove: const Offset(50.0, 100.0), children: children,
anchorBelow: const Offset(50.0, 200.0),
children: children,
),
), ),
), ),
); ),
);
expect(findOverflowBackButton(), findsNothing); expect(findOverflowBackButton(), findsNothing);
expect(findOverflowNextButton(), findsOneWidget); expect(findOverflowNextButton(), findsOneWidget);
expect(findOverflowNextButton(), overflowNextPaintPattern()); expect(findOverflowNextButton(), overflowNextPaintPattern());
// Tap the overflow next button to show the next page of children. // Tap the overflow next button to show the next page of children.
await tester.tapAt(tester.getCenter(findOverflowNextButton())); await tester.tapAt(tester.getCenter(findOverflowNextButton()));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(findOverflowBackButton(), findsOneWidget); expect(findOverflowBackButton(), findsOneWidget);
expect(findOverflowNextButton(), findsOneWidget); expect(findOverflowNextButton(), findsOneWidget);
expect(findOverflowBackButton(), overflowBackPaintPattern()); expect(findOverflowBackButton(), overflowBackPaintPattern());
expect(findOverflowNextButton(), overflowNextPaintPattern()); expect(findOverflowNextButton(), overflowNextPaintPattern());
// Tap the overflow next button to show the last page of children. // Tap the overflow next button to show the last page of children.
await tester.tapAt(tester.getCenter(findOverflowNextButton())); await tester.tapAt(tester.getCenter(findOverflowNextButton()));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(findOverflowBackButton(), findsOneWidget); expect(findOverflowBackButton(), findsOneWidget);
expect(findOverflowNextButton(), findsNothing); expect(findOverflowNextButton(), findsNothing);
expect(findOverflowBackButton(), overflowBackPaintPattern()); expect(findOverflowBackButton(), overflowBackPaintPattern());
}, });
// Path.combine is not implemented in the HTML backend https://github.com/flutter/flutter/issues/44572
skip: kIsWeb,
);
testWidgets('paginates children if they overflow', (WidgetTester tester) async { testWidgets('paginates children if they overflow', (WidgetTester tester) async {
late StateSetter setState; late StateSetter setState;

View File

@ -479,7 +479,7 @@ void main() {
tester.getTopLeft(find.text('Licenses')), tester.getTopLeft(find.text('Licenses')),
const Offset(16.0 + safeareaPadding, 14.0 + safeareaPadding), const Offset(16.0 + safeareaPadding, 14.0 + safeareaPadding),
); );
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('LicensePage returns early if unmounted', (WidgetTester tester) async { testWidgets('LicensePage returns early if unmounted', (WidgetTester tester) async {
final Completer<LicenseEntry> licenseCompleter = Completer<LicenseEntry>(); final Completer<LicenseEntry> licenseCompleter = Completer<LicenseEntry>();
@ -1464,10 +1464,7 @@ void main() {
// If the layout width is less than 840.0 pixels, nested layout is // If the layout width is less than 840.0 pixels, nested layout is
// used which positions license page title at the top center. // used which positions license page title at the top center.
Offset titleOffset = tester.getCenter(find.text(title)); Offset titleOffset = tester.getCenter(find.text(title));
if (!kIsWeb || isSkiaWeb) { expect(titleOffset, Offset(defaultSize.width / 2, 96.0));
// https://github.com/flutter/flutter/issues/99933
expect(titleOffset, Offset(defaultSize.width / 2, 96.0));
}
expect(tester.getCenter(find.byType(ListView)), Offset(defaultSize.width / 2, 328.0)); expect(tester.getCenter(find.byType(ListView)), Offset(defaultSize.width / 2, 328.0));
// Configure a wide window to show the lateral UI. // Configure a wide window to show the lateral UI.
@ -1588,10 +1585,7 @@ void main() {
// If the layout width is less than 840.0 pixels, nested layout is // If the layout width is less than 840.0 pixels, nested layout is
// used which positions license page title at the top center. // used which positions license page title at the top center.
Offset titleOffset = tester.getCenter(find.text(title)); Offset titleOffset = tester.getCenter(find.text(title));
if (!kIsWeb || isSkiaWeb) { expect(titleOffset, Offset(defaultSize.width / 2, 96.0));
// https://github.com/flutter/flutter/issues/99933
expect(titleOffset, Offset(defaultSize.width / 2, 96.0));
}
expect(tester.getCenter(find.byType(ListView)), Offset(defaultSize.width / 2, 328.0)); expect(tester.getCenter(find.byType(ListView)), Offset(defaultSize.width / 2, 328.0));
// Configure a wide window to show the lateral UI. // Configure a wide window to show the lateral UI.

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -241,7 +240,7 @@ void main() {
await tester.pumpWidget(buildAppBar(textScaleFactor: 3.0)); await tester.pumpWidget(buildAppBar(textScaleFactor: 3.0));
expect(tester.getRect(expandedTitle).height, 43.0); expect(tester.getRect(expandedTitle).height, 43.0);
verifyTextNotClipped(expandedTitle, tester); verifyTextNotClipped(expandedTitle, tester);
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('SliverAppBar.large expanded title has upper limit on text scaling', ( testWidgets('SliverAppBar.large expanded title has upper limit on text scaling', (
WidgetTester tester, WidgetTester tester,
@ -275,46 +274,44 @@ void main() {
await tester.pumpWidget(buildAppBar(textScaleFactor: 3.0)); await tester.pumpWidget(buildAppBar(textScaleFactor: 3.0));
expect(tester.getRect(expandedTitle).height, closeTo(48.0, 0.1)); expect(tester.getRect(expandedTitle).height, closeTo(48.0, 0.1));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets( testWidgets('SliverAppBar.medium expanded title position is adjusted with textScaleFactor', (
'SliverAppBar.medium expanded title position is adjusted with textScaleFactor', WidgetTester tester,
(WidgetTester tester) async { ) async {
const String title = 'Medium AppBar'; const String title = 'Medium AppBar';
Widget buildAppBar({double textScaleFactor = 1.0}) { Widget buildAppBar({double textScaleFactor = 1.0}) {
return MaterialApp( return MaterialApp(
theme: ThemeData(useMaterial3: true), theme: ThemeData(useMaterial3: true),
home: MediaQuery.withClampedTextScaling( home: MediaQuery.withClampedTextScaling(
minScaleFactor: textScaleFactor, minScaleFactor: textScaleFactor,
maxScaleFactor: textScaleFactor, maxScaleFactor: textScaleFactor,
child: Material( child: Material(
child: CustomScrollView( child: CustomScrollView(
slivers: <Widget>[ slivers: <Widget>[
const SliverAppBar.medium(title: Text(title, maxLines: 1)), const SliverAppBar.medium(title: Text(title, maxLines: 1)),
SliverToBoxAdapter(child: Container(height: 1200, color: Colors.orange[400])), SliverToBoxAdapter(child: Container(height: 1200, color: Colors.orange[400])),
], ],
),
), ),
), ),
); ),
} );
}
await tester.pumpWidget(buildAppBar()); await tester.pumpWidget(buildAppBar());
final Finder expandedTitle = find.text(title).first; final Finder expandedTitle = find.text(title).first;
expect(tester.getBottomLeft(expandedTitle).dy, 96.0); expect(tester.getBottomLeft(expandedTitle).dy, 96.0);
verifyTextNotClipped(expandedTitle, tester); verifyTextNotClipped(expandedTitle, tester);
await tester.pumpWidget(buildAppBar(textScaleFactor: 2.0)); await tester.pumpWidget(buildAppBar(textScaleFactor: 2.0));
expect(tester.getBottomLeft(expandedTitle).dy, 107.0); expect(tester.getBottomLeft(expandedTitle).dy, 107.0);
verifyTextNotClipped(expandedTitle, tester); verifyTextNotClipped(expandedTitle, tester);
await tester.pumpWidget(buildAppBar(textScaleFactor: 3.0)); await tester.pumpWidget(buildAppBar(textScaleFactor: 3.0));
expect(tester.getBottomLeft(expandedTitle).dy, 107.0); expect(tester.getBottomLeft(expandedTitle).dy, 107.0);
verifyTextNotClipped(expandedTitle, tester); verifyTextNotClipped(expandedTitle, tester);
}, });
skip: kIsWeb && !isSkiaWeb, // https://github.com/flutter/flutter/issues/99933
);
testWidgets('SliverAppBar.large expanded title position is adjusted with textScaleFactor', ( testWidgets('SliverAppBar.large expanded title position is adjusted with textScaleFactor', (
WidgetTester tester, WidgetTester tester,
@ -1264,9 +1261,7 @@ void main() {
// Test the expanded title is positioned correctly. // Test the expanded title is positioned correctly.
final Offset titleOffset = tester.getBottomLeft(expandedTitle); final Offset titleOffset = tester.getBottomLeft(expandedTitle);
expect(titleOffset.dx, 16.0); expect(titleOffset.dx, 16.0);
if (!kIsWeb || isSkiaWeb) { expect(titleOffset.dy, 96.0);
expect(titleOffset.dy, 96.0);
}
verifyTextNotClipped(expandedTitle, tester); verifyTextNotClipped(expandedTitle, tester);

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -42,10 +41,7 @@ void main() {
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero); expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
if (!kIsWeb || isSkiaWeb) { expect(tester.getTopLeft(find.text('0')), const Offset(16, -4));
// https://github.com/flutter/flutter/issues/99933
expect(tester.getTopLeft(find.text('0')), const Offset(16, -4));
}
final RenderBox box = tester.renderObject(find.byType(Badge)); final RenderBox box = tester.renderObject(find.byType(Badge));
final RRect rrect = RRect.fromLTRBR(12, -4, 31.5, 12, const Radius.circular(8)); final RRect rrect = RRect.fromLTRBR(12, -4, 31.5, 12, const Radius.circular(8));
@ -82,10 +78,7 @@ void main() {
expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size
expect(tester.getTopLeft(find.byType(Badge)), Offset.zero); expect(tester.getTopLeft(find.byType(Badge)), Offset.zero);
if (!kIsWeb || isSkiaWeb) { expect(tester.getTopLeft(find.text('0')), const Offset(0, -4));
// https://github.com/flutter/flutter/issues/99933
expect(tester.getTopLeft(find.text('0')), const Offset(0, -4));
}
final RenderBox box = tester.renderObject(find.byType(Badge)); final RenderBox box = tester.renderObject(find.byType(Badge));
final RRect rrect = RRect.fromLTRBR(-4, -4, 15.5, 12, const Radius.circular(8)); final RRect rrect = RRect.fromLTRBR(-4, -4, 15.5, 12, const Radius.circular(8));
@ -132,10 +125,7 @@ void main() {
// x = alignment.start + padding.left // x = alignment.start + padding.left
// y = alignment.top // y = alignment.top
if (!kIsWeb || isSkiaWeb) { expect(tester.getTopLeft(find.text('0')), const Offset(16, -4));
// https://github.com/flutter/flutter/issues/99933
expect(tester.getTopLeft(find.text('0')), const Offset(16, -4));
}
final RenderBox box = tester.renderObject(find.byType(Badge)); final RenderBox box = tester.renderObject(find.byType(Badge));
// '0'.width = 12 // '0'.width = 12

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -258,29 +257,17 @@ void main() {
await tester.pumpWidget(buildApp(textScaler: TextScaler.noScaling)); await tester.pumpWidget(buildApp(textScaler: TextScaler.noScaling));
expect(find.text(label), findsOneWidget); expect(find.text(label), findsOneWidget);
if (!kIsWeb || isSkiaWeb) { expect(tester.getSize(find.text(label)), const Size(14.25, 20.0));
// https://github.com/flutter/flutter/issues/99933
expect(tester.getSize(find.text(label)), const Size(14.25, 20.0));
}
await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(1.1))); await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(1.1)));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
if (!kIsWeb || isSkiaWeb) { expect(_sizeAlmostEqual(tester.getSize(find.text(label)), const Size(15.65, 22.0)), true);
// https://github.com/flutter/flutter/issues/99933
expect(_sizeAlmostEqual(tester.getSize(find.text(label)), const Size(15.65, 22.0)), true);
}
await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(1.5))); await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(1.5)));
if (!kIsWeb || isSkiaWeb) { expect(_sizeAlmostEqual(tester.getSize(find.text(label)), const Size(21.25, 30)), true);
// https://github.com/flutter/flutter/issues/99933
expect(_sizeAlmostEqual(tester.getSize(find.text(label)), const Size(21.25, 30)), true);
}
await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(4))); await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(4)));
if (!kIsWeb || isSkiaWeb) { expect(_sizeAlmostEqual(tester.getSize(find.text(label)), const Size(21.25, 30)), true);
// https://github.com/flutter/flutter/issues/99933
expect(_sizeAlmostEqual(tester.getSize(find.text(label)), const Size(21.25, 30)), true);
}
}); });
group('MaterialBanner elevation', () { group('MaterialBanner elevation', () {

View File

@ -10,7 +10,6 @@ library;
import 'dart:math'; import 'dart:math';
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -1687,7 +1686,6 @@ void main() {
await tester.longPress(find.text(label)); await tester.longPress(find.text(label));
expect(tester.getSize(find.text(label).last).height, equals(80.0)); expect(tester.getSize(find.text(label).last).height, equals(80.0));
}, },
skip: kIsWeb && !isSkiaWeb, // https://github.com/flutter/flutter/issues/99933
); );
testWidgets('Different behaviour of tool tip in BottomNavigationBarItem', ( testWidgets('Different behaviour of tool tip in BottomNavigationBarItem', (
@ -2711,7 +2709,7 @@ void main() {
tester.getRect(find.byKey(icon1)), tester.getRect(find.byKey(icon1)),
Rect.fromLTRB(500.0, iconTop, 700.0, iconTop + iconHeight), Rect.fromLTRB(500.0, iconTop, 700.0, iconTop + iconHeight),
); );
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Material2 - BottomNavigationBar centered landscape layout', ( testWidgets('Material2 - BottomNavigationBar centered landscape layout', (
WidgetTester tester, WidgetTester tester,
@ -2855,7 +2853,7 @@ void main() {
tester.getRect(find.byKey(icon1)), tester.getRect(find.byKey(icon1)),
Rect.fromLTRB(450.0, iconTop, 650.0, iconTop + iconHeight), Rect.fromLTRB(450.0, iconTop, 650.0, iconTop + iconHeight),
); );
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Material2 - BottomNavigationBar linear landscape layout', ( testWidgets('Material2 - BottomNavigationBar linear landscape layout', (
WidgetTester tester, WidgetTester tester,
@ -2995,7 +2993,7 @@ void main() {
tester.getRect(find.byKey(icon1)), tester.getRect(find.byKey(icon1)),
Rect.fromLTRB(secondItemLeft, iconTop, secondItemLeft + iconWidth, iconTop + iconHeight), Rect.fromLTRB(secondItemLeft, iconTop, secondItemLeft + iconWidth, iconTop + iconHeight),
); );
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('BottomNavigationBar linear landscape layout label RenderFlex overflow', ( testWidgets('BottomNavigationBar linear landscape layout label RenderFlex overflow', (
WidgetTester tester, WidgetTester tester,

View File

@ -521,7 +521,7 @@ void main() {
expect(tester.getSize(find.byType(Text)).width, closeTo(40.4, 0.01)); expect(tester.getSize(find.byType(Text)).width, closeTo(40.4, 0.01));
expect(tester.getSize(find.byType(Text)).height, equals(14.0)); expect(tester.getSize(find.byType(Text)).height, equals(14.0));
expect(tester.getSize(find.byType(Chip)), const Size(800.0, 48.0)); expect(tester.getSize(find.byType(Chip)), const Size(800.0, 48.0));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Material2 - Chip responds to materialTapTargetSize', (WidgetTester tester) async { testWidgets('Material2 - Chip responds to materialTapTargetSize', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
@ -555,7 +555,7 @@ void main() {
expect(tester.getSize(find.byType(Chip).first).height, equals(48.0)); expect(tester.getSize(find.byType(Chip).first).height, equals(48.0));
expect(tester.getSize(find.byType(Chip).last).width, closeTo(48.1, 0.01)); expect(tester.getSize(find.byType(Chip).last).width, closeTo(48.1, 0.01));
expect(tester.getSize(find.byType(Chip).last).height, equals(38.0)); expect(tester.getSize(find.byType(Chip).last).height, equals(38.0));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Delete button tap target is the right proportion of the chip', ( testWidgets('Delete button tap target is the right proportion of the chip', (
WidgetTester tester, WidgetTester tester,
@ -779,7 +779,7 @@ void main() {
expect(tester.getSize(find.byType(Chip).first).height, equals(78.0)); expect(tester.getSize(find.byType(Chip).first).height, equals(78.0));
expect(tester.getSize(find.byType(Chip).last).width, closeTo(138.59, 0.01)); expect(tester.getSize(find.byType(Chip).last).width, closeTo(138.59, 0.01));
expect(tester.getSize(find.byType(Chip).last).height, equals(48.0)); expect(tester.getSize(find.byType(Chip).last).height, equals(48.0));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Material2 - Labels can be non-text widgets', (WidgetTester tester) async { testWidgets('Material2 - Labels can be non-text widgets', (WidgetTester tester) async {
final Key keyA = GlobalKey(); final Key keyA = GlobalKey();
@ -828,7 +828,7 @@ void main() {
expect(tester.getSize(find.byType(Chip).first).width, moreOrLessEquals(138.5, epsilon: 0.1)); expect(tester.getSize(find.byType(Chip).first).width, moreOrLessEquals(138.5, epsilon: 0.1));
expect(tester.getSize(find.byType(Chip).first).height, equals(48.0)); expect(tester.getSize(find.byType(Chip).first).height, equals(48.0));
expect(tester.getSize(find.byType(Chip).last), const Size(60.0, 48.0)); expect(tester.getSize(find.byType(Chip).last), const Size(60.0, 48.0));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Avatars can be non-circle avatar widgets', (WidgetTester tester) async { testWidgets('Avatars can be non-circle avatar widgets', (WidgetTester tester) async {
final Key keyA = GlobalKey(); final Key keyA = GlobalKey();
@ -1188,7 +1188,7 @@ void main() {
expect(tester.getSize(find.byType(RawChip)).height, equals(48.0)); expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(17.0, 14.0))); expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(17.0, 14.0)));
expect(find.byKey(avatarKey), findsNothing); expect(find.byKey(avatarKey), findsNothing);
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Material2 - Delete button drawer works as expected on RawChip', ( testWidgets('Material2 - Delete button drawer works as expected on RawChip', (
WidgetTester tester, WidgetTester tester,
@ -1455,7 +1455,7 @@ void main() {
expect(tester.getSize(find.byType(RawChip)).height, equals(48.0)); expect(tester.getSize(find.byType(RawChip)).height, equals(48.0));
expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(17.0, 14.0))); expect(tester.getTopLeft(find.byKey(labelKey)), equals(const Offset(17.0, 14.0)));
expect(find.byKey(deleteButtonKey), findsNothing); expect(find.byKey(deleteButtonKey), findsNothing);
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Delete button takes up at most half of the chip', (WidgetTester tester) async { testWidgets('Delete button takes up at most half of the chip', (WidgetTester tester) async {
final UniqueKey chipKey = UniqueKey(); final UniqueKey chipKey = UniqueKey();
@ -2140,7 +2140,7 @@ void main() {
// Simulate a tap on the label to select the chip. // Simulate a tap on the label to select the chip.
await tester.tap(find.byKey(labelKey)); await tester.tap(find.byKey(labelKey));
expect(selected, equals(true)); expect(selected, equals(true));
expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb && isSkiaWeb ? 3 : 1)); expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb ? 3 : 1));
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 50)); await tester.pump(const Duration(milliseconds: 50));
expect(getSelectProgress(tester), moreOrLessEquals(0.002, epsilon: 0.01)); expect(getSelectProgress(tester), moreOrLessEquals(0.002, epsilon: 0.01));
@ -2159,7 +2159,7 @@ void main() {
// Simulate another tap on the label to deselect the chip. // Simulate another tap on the label to deselect the chip.
await tester.tap(find.byKey(labelKey)); await tester.tap(find.byKey(labelKey));
expect(selected, equals(false)); expect(selected, equals(false));
expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb && isSkiaWeb ? 3 : 1)); expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb ? 3 : 1));
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 20)); await tester.pump(const Duration(milliseconds: 20));
expect(getSelectProgress(tester), moreOrLessEquals(0.875, epsilon: 0.01)); expect(getSelectProgress(tester), moreOrLessEquals(0.875, epsilon: 0.01));
@ -2173,7 +2173,7 @@ void main() {
expect(getSelectProgress(tester), equals(0.0)); expect(getSelectProgress(tester), equals(0.0));
expect(getAvatarDrawerProgress(tester), equals(1.0)); expect(getAvatarDrawerProgress(tester), equals(1.0));
expect(getDeleteDrawerProgress(tester), equals(0.0)); expect(getDeleteDrawerProgress(tester), equals(0.0));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Material2 - Selection without avatar works as expected on RawChip', ( testWidgets('Material2 - Selection without avatar works as expected on RawChip', (
WidgetTester tester, WidgetTester tester,
@ -2302,7 +2302,7 @@ void main() {
// Simulate a tap on the label to select the chip. // Simulate a tap on the label to select the chip.
await tester.tap(find.byKey(labelKey)); await tester.tap(find.byKey(labelKey));
expect(selected, equals(true)); expect(selected, equals(true));
expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb && isSkiaWeb ? 3 : 1)); expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb ? 3 : 1));
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 50)); await tester.pump(const Duration(milliseconds: 50));
expect(getSelectProgress(tester), moreOrLessEquals(0.002, epsilon: 0.01)); expect(getSelectProgress(tester), moreOrLessEquals(0.002, epsilon: 0.01));
@ -2322,7 +2322,7 @@ void main() {
// Simulate another tap on the label to deselect the chip. // Simulate another tap on the label to deselect the chip.
await tester.tap(find.byKey(labelKey)); await tester.tap(find.byKey(labelKey));
expect(selected, equals(false)); expect(selected, equals(false));
expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb && isSkiaWeb ? 3 : 1)); expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb ? 3 : 1));
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 20)); await tester.pump(const Duration(milliseconds: 20));
expect(getSelectProgress(tester), moreOrLessEquals(0.875, epsilon: 0.01)); expect(getSelectProgress(tester), moreOrLessEquals(0.875, epsilon: 0.01));
@ -2336,7 +2336,7 @@ void main() {
expect(getSelectProgress(tester), equals(0.0)); expect(getSelectProgress(tester), equals(0.0));
expect(getAvatarDrawerProgress(tester), equals(0.0)); expect(getAvatarDrawerProgress(tester), equals(0.0));
expect(getDeleteDrawerProgress(tester), equals(0.0)); expect(getDeleteDrawerProgress(tester), equals(0.0));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Material2 - Activation works as expected on RawChip', (WidgetTester tester) async { testWidgets('Material2 - Activation works as expected on RawChip', (WidgetTester tester) async {
bool selected = false; bool selected = false;
@ -2436,7 +2436,7 @@ void main() {
await tester.tap(find.byKey(labelKey)); await tester.tap(find.byKey(labelKey));
expect(selected, equals(true)); expect(selected, equals(true));
expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb && isSkiaWeb ? 3 : 1)); expect(SchedulerBinding.instance.transientCallbackCount, equals(kIsWeb ? 3 : 1));
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 50)); await tester.pump(const Duration(milliseconds: 50));
expect(getSelectProgress(tester), moreOrLessEquals(0.002, epsilon: 0.01)); expect(getSelectProgress(tester), moreOrLessEquals(0.002, epsilon: 0.01));
@ -2451,7 +2451,7 @@ void main() {
expect(getAvatarDrawerProgress(tester), equals(1.0)); expect(getAvatarDrawerProgress(tester), equals(1.0));
expect(getDeleteDrawerProgress(tester), equals(0.0)); expect(getDeleteDrawerProgress(tester), equals(0.0));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Chip uses ThemeData chip theme if present', (WidgetTester tester) async { testWidgets('Chip uses ThemeData chip theme if present', (WidgetTester tester) async {
final ThemeData theme = ThemeData( final ThemeData theme = ThemeData(
@ -2576,37 +2576,35 @@ void main() {
expect(tester.getSize(find.byKey(key2)), const Size(80.0, 32.0)); expect(tester.getSize(find.byKey(key2)), const Size(80.0, 32.0));
}); });
testWidgets( testWidgets('Material3 - Chip size is configurable by ThemeData.materialTapTargetSize', (
'Material3 - Chip size is configurable by ThemeData.materialTapTargetSize', WidgetTester tester,
(WidgetTester tester) async { ) async {
final Key key1 = UniqueKey(); final Key key1 = UniqueKey();
await tester.pumpWidget( await tester.pumpWidget(
wrapForChip( wrapForChip(
child: Theme( child: Theme(
data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.padded), data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.padded),
child: Center(child: RawChip(key: key1, label: const Text('test'))), child: Center(child: RawChip(key: key1, label: const Text('test'))),
),
), ),
); ),
);
expect(tester.getSize(find.byKey(key1)).width, moreOrLessEquals(90.4, epsilon: 0.1)); expect(tester.getSize(find.byKey(key1)).width, moreOrLessEquals(90.4, epsilon: 0.1));
expect(tester.getSize(find.byKey(key1)).height, equals(48.0)); expect(tester.getSize(find.byKey(key1)).height, equals(48.0));
final Key key2 = UniqueKey(); final Key key2 = UniqueKey();
await tester.pumpWidget( await tester.pumpWidget(
wrapForChip( wrapForChip(
child: Theme( child: Theme(
data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.shrinkWrap), data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.shrinkWrap),
child: Center(child: RawChip(key: key2, label: const Text('test'))), child: Center(child: RawChip(key: key2, label: const Text('test'))),
),
), ),
); ),
);
expect(tester.getSize(find.byKey(key2)).width, moreOrLessEquals(90.4, epsilon: 0.1)); expect(tester.getSize(find.byKey(key2)).width, moreOrLessEquals(90.4, epsilon: 0.1));
expect(tester.getSize(find.byKey(key2)).height, equals(38.0)); expect(tester.getSize(find.byKey(key2)).height, equals(38.0));
}, });
skip: kIsWeb && !isSkiaWeb, // https://github.com/flutter/flutter/issues/99933
);
testWidgets('Chip uses the right theme colors for the right components', ( testWidgets('Chip uses the right theme colors for the right components', (
WidgetTester tester, WidgetTester tester,
@ -4599,7 +4597,7 @@ void main() {
box = tester.getRect(find.byKey(key)); box = tester.getRect(find.byKey(key));
expect(box.size.width, moreOrLessEquals(130.4, epsilon: 0.1)); expect(box.size.width, moreOrLessEquals(130.4, epsilon: 0.1));
expect(box.size.height, equals(24.0 + 16.0)); expect(box.size.height, equals(24.0 + 16.0));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Chip delete button tooltip is disabled if deleteButtonTooltipMessage is empty', ( testWidgets('Chip delete button tooltip is disabled if deleteButtonTooltipMessage is empty', (
WidgetTester tester, WidgetTester tester,
@ -5897,86 +5895,84 @@ void main() {
expect(materialBox, paints..rrect(color: backgroundColor)); expect(materialBox, paints..rrect(color: backgroundColor));
}); });
testWidgets( testWidgets('ChipAnimationStyle.avatarDrawerAnimation overrides chip avatar animation duration', (
'ChipAnimationStyle.avatarDrawerAnimation overrides chip avatar animation duration', WidgetTester tester,
(WidgetTester tester) async { ) async {
const Color checkmarkColor = Color(0xffff0000); const Color checkmarkColor = Color(0xffff0000);
bool selected = false; bool selected = false;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Material( home: Material(
child: Center( child: Center(
child: StatefulBuilder( child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) { builder: (BuildContext context, StateSetter setState) {
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
RawChip( RawChip(
chipAnimationStyle: ChipAnimationStyle( chipAnimationStyle: ChipAnimationStyle(
avatarDrawerAnimation: const AnimationStyle( avatarDrawerAnimation: const AnimationStyle(
duration: Duration(milliseconds: 800), duration: Duration(milliseconds: 800),
reverseDuration: Duration(milliseconds: 400), reverseDuration: Duration(milliseconds: 400),
),
), ),
checkmarkColor: checkmarkColor,
selected: selected,
onSelected: (bool value) {},
label: const Text('RawChip'),
), ),
ElevatedButton( checkmarkColor: checkmarkColor,
onPressed: () { selected: selected,
setState(() { onSelected: (bool value) {},
selected = !selected; label: const Text('RawChip'),
}); ),
}, ElevatedButton(
child: Text('${selected ? 'Unselect' : 'Select'} Chip'), onPressed: () {
), setState(() {
], selected = !selected;
); });
}, },
), child: Text('${selected ? 'Unselect' : 'Select'} Chip'),
),
],
);
},
), ),
), ),
), ),
); ),
);
final RenderBox materialBox = tester.firstRenderObject<RenderBox>( final RenderBox materialBox = tester.firstRenderObject<RenderBox>(
find.descendant(of: find.byType(RawChip), matching: find.byType(CustomPaint)), find.descendant(of: find.byType(RawChip), matching: find.byType(CustomPaint)),
); );
// Test the checkmark is not visible yet. // Test the checkmark is not visible yet.
expect(materialBox, isNot(paints..path(color: checkmarkColor))); expect(materialBox, isNot(paints..path(color: checkmarkColor)));
expect(tester.getSize(find.byType(RawChip)).width, closeTo(132.6, 0.1)); expect(tester.getSize(find.byType(RawChip)).width, closeTo(132.6, 0.1));
await tester.tap(find.widgetWithText(ElevatedButton, 'Select Chip')); await tester.tap(find.widgetWithText(ElevatedButton, 'Select Chip'));
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 400)); await tester.pump(const Duration(milliseconds: 400));
expect(materialBox, paints..path(color: checkmarkColor)); expect(materialBox, paints..path(color: checkmarkColor));
expect(tester.getSize(find.byType(RawChip)).width, closeTo(148.2, 0.1)); expect(tester.getSize(find.byType(RawChip)).width, closeTo(148.2, 0.1));
await tester.pump(const Duration(milliseconds: 400)); await tester.pump(const Duration(milliseconds: 400));
// Test the checkmark is fully visible. // Test the checkmark is fully visible.
expect(materialBox, paints..path(color: checkmarkColor)); expect(materialBox, paints..path(color: checkmarkColor));
expect(tester.getSize(find.byType(RawChip)).width, closeTo(152.6, 0.1)); expect(tester.getSize(find.byType(RawChip)).width, closeTo(152.6, 0.1));
await tester.tap(find.widgetWithText(ElevatedButton, 'Unselect Chip')); await tester.tap(find.widgetWithText(ElevatedButton, 'Unselect Chip'));
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 200)); await tester.pump(const Duration(milliseconds: 200));
expect(materialBox, isNot(paints..path(color: checkmarkColor))); expect(materialBox, isNot(paints..path(color: checkmarkColor)));
expect(tester.getSize(find.byType(RawChip)).width, closeTo(148.2, 0.1)); expect(tester.getSize(find.byType(RawChip)).width, closeTo(148.2, 0.1));
await tester.pump(const Duration(milliseconds: 200)); await tester.pump(const Duration(milliseconds: 200));
// Test if checkmark is removed. // Test if checkmark is removed.
expect(materialBox, isNot(paints..path(color: checkmarkColor))); expect(materialBox, isNot(paints..path(color: checkmarkColor)));
expect(tester.getSize(find.byType(RawChip)).width, closeTo(132.6, 0.1)); expect(tester.getSize(find.byType(RawChip)).width, closeTo(132.6, 0.1));
}, });
skip: kIsWeb && !isSkiaWeb, // https://github.com/flutter/flutter/issues/99933
);
testWidgets( testWidgets(
'ChipAnimationStyle.deleteDrawerAnimation overrides chip delete icon animation duration', 'ChipAnimationStyle.deleteDrawerAnimation overrides chip delete icon animation duration',
@ -6048,7 +6044,6 @@ void main() {
expect(find.byIcon(Icons.cancel), findsNothing); expect(find.byIcon(Icons.cancel), findsNothing);
expect(tester.getSize(find.byType(RawChip)).width, closeTo(132.6, 0.1)); expect(tester.getSize(find.byType(RawChip)).width, closeTo(132.6, 0.1));
}, },
skip: kIsWeb && !isSkiaWeb, // https://github.com/flutter/flutter/issues/99933
); );
testWidgets('Chip.chipAnimationStyle is passed to RawChip', (WidgetTester tester) async { testWidgets('Chip.chipAnimationStyle is passed to RawChip', (WidgetTester tester) async {

View File

@ -9,7 +9,6 @@ library;
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -898,10 +897,7 @@ void main() {
final Offset subHeaderTextTopLeft = tester.getTopLeft(subHeaderText); final Offset subHeaderTextTopLeft = tester.getTopLeft(subHeaderText);
final Offset dividerTopRight = tester.getTopRight(divider); final Offset dividerTopRight = tester.getTopRight(divider);
expect(subHeaderTextTopLeft.dx, dividerTopRight.dx + 24.0); expect(subHeaderTextTopLeft.dx, dividerTopRight.dx + 24.0);
if (!kIsWeb || isSkiaWeb) { expect(subHeaderTextTopLeft.dy, dialogTopLeft.dy + 16.0);
// https://github.com/flutter/flutter/issues/99933
expect(subHeaderTextTopLeft.dy, dialogTopLeft.dy + 16.0);
}
// Test sub header icon position. // Test sub header icon position.
final Finder subHeaderIcon = find.byIcon(Icons.arrow_drop_down); final Finder subHeaderIcon = find.byIcon(Icons.arrow_drop_down);
@ -915,10 +911,7 @@ void main() {
final Offset calendarPageViewTopLeft = tester.getTopLeft(calendarPageView); final Offset calendarPageViewTopLeft = tester.getTopLeft(calendarPageView);
final Offset subHeaderTextBottomLeft = tester.getBottomLeft(subHeaderText); final Offset subHeaderTextBottomLeft = tester.getBottomLeft(subHeaderText);
expect(calendarPageViewTopLeft.dx, dividerTopRight.dx); expect(calendarPageViewTopLeft.dx, dividerTopRight.dx);
if (!kIsWeb || isSkiaWeb) { expect(calendarPageViewTopLeft.dy, subHeaderTextBottomLeft.dy + 16.0);
// https://github.com/flutter/flutter/issues/99933
expect(calendarPageViewTopLeft.dy, subHeaderTextBottomLeft.dy + 16.0);
}
// Test month navigation icons position. // Test month navigation icons position.
final Finder previousMonthButton = find.widgetWithIcon(IconButton, Icons.chevron_left); final Finder previousMonthButton = find.widgetWithIcon(IconButton, Icons.chevron_left);
@ -982,10 +975,7 @@ void main() {
final Offset headerTextTextTopLeft = tester.getTopLeft(headerText); final Offset headerTextTextTopLeft = tester.getTopLeft(headerText);
final Offset helpTextBottomLeft = tester.getBottomLeft(helpText); final Offset helpTextBottomLeft = tester.getBottomLeft(helpText);
expect(headerTextTextTopLeft.dx, dialogTopLeft.dx + 24.0); expect(headerTextTextTopLeft.dx, dialogTopLeft.dx + 24.0);
if (!kIsWeb || isSkiaWeb) { expect(headerTextTextTopLeft.dy, helpTextBottomLeft.dy + 28.0);
// https://github.com/flutter/flutter/issues/99933
expect(headerTextTextTopLeft.dy, helpTextBottomLeft.dy + 28.0);
}
// Test switch button position. // Test switch button position.
final Finder switchButtonM3 = find.widgetWithIcon(IconButton, Icons.edit_outlined); final Finder switchButtonM3 = find.widgetWithIcon(IconButton, Icons.edit_outlined);
@ -1005,10 +995,7 @@ void main() {
final Offset subHeaderTextTopLeft = tester.getTopLeft(subHeaderText); final Offset subHeaderTextTopLeft = tester.getTopLeft(subHeaderText);
final Offset dividerBottomLeft = tester.getBottomLeft(divider); final Offset dividerBottomLeft = tester.getBottomLeft(divider);
expect(subHeaderTextTopLeft.dx, dialogTopLeft.dx + 24.0); expect(subHeaderTextTopLeft.dx, dialogTopLeft.dx + 24.0);
if (!kIsWeb || isSkiaWeb) { expect(subHeaderTextTopLeft.dy, dividerBottomLeft.dy + 16.0);
// https://github.com/flutter/flutter/issues/99933
expect(subHeaderTextTopLeft.dy, dividerBottomLeft.dy + 16.0);
}
// Test sub header icon position. // Test sub header icon position.
final Finder subHeaderIcon = find.byIcon(Icons.arrow_drop_down); final Finder subHeaderIcon = find.byIcon(Icons.arrow_drop_down);
@ -1031,10 +1018,7 @@ void main() {
final Offset calendarPageViewTopLeft = tester.getTopLeft(calendarPageView); final Offset calendarPageViewTopLeft = tester.getTopLeft(calendarPageView);
final Offset subHeaderTextBottomLeft = tester.getBottomLeft(subHeaderText); final Offset subHeaderTextBottomLeft = tester.getBottomLeft(subHeaderText);
expect(calendarPageViewTopLeft.dx, dialogTopLeft.dx); expect(calendarPageViewTopLeft.dx, dialogTopLeft.dx);
if (!kIsWeb || isSkiaWeb) { expect(calendarPageViewTopLeft.dy, subHeaderTextBottomLeft.dy + 16.0);
// https://github.com/flutter/flutter/issues/99933
expect(calendarPageViewTopLeft.dy, subHeaderTextBottomLeft.dy + 16.0);
}
// Test action buttons position. // Test action buttons position.
final Offset dialogBottomRight = tester.getBottomRight(find.byType(AnimatedContainer)); final Offset dialogBottomRight = tester.getBottomRight(find.byType(AnimatedContainer));

View File

@ -4,7 +4,6 @@
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -139,23 +138,14 @@ void main() {
find.widgetWithIcon(IconButton, Icons.edit_outlined), find.widgetWithIcon(IconButton, Icons.edit_outlined),
); );
expect(saveButtonBottomLeft.dx, moreOrLessEquals(711.6, epsilon: 1e-5)); expect(saveButtonBottomLeft.dx, moreOrLessEquals(711.6, epsilon: 1e-5));
if (!kIsWeb || isSkiaWeb) { expect(saveButtonBottomLeft.dy, helpTextTopLeft.dy);
// https://github.com/flutter/flutter/issues/99933
expect(saveButtonBottomLeft.dy, helpTextTopLeft.dy);
}
expect(entryButtonBottomLeft.dx, saveButtonBottomLeft.dx - 48.0); expect(entryButtonBottomLeft.dx, saveButtonBottomLeft.dx - 48.0);
if (!kIsWeb || isSkiaWeb) { expect(entryButtonBottomLeft.dy, helpTextTopLeft.dy);
// https://github.com/flutter/flutter/issues/99933
expect(entryButtonBottomLeft.dy, helpTextTopLeft.dy);
}
// Test help text position. // Test help text position.
final Offset helpTextBottomLeft = tester.getBottomLeft(helpText); final Offset helpTextBottomLeft = tester.getBottomLeft(helpText);
expect(helpTextBottomLeft.dx, 72.0); expect(helpTextBottomLeft.dx, 72.0);
if (!kIsWeb || isSkiaWeb) { expect(helpTextBottomLeft.dy, closeButtonBottomRight.dy + 20.0);
// https://github.com/flutter/flutter/issues/99933
expect(helpTextBottomLeft.dy, closeButtonBottomRight.dy + 20.0);
}
// Test the header position. // Test the header position.
final Offset firstDateHeaderTopLeft = tester.getTopLeft(firstDateHeaderText); final Offset firstDateHeaderTopLeft = tester.getTopLeft(firstDateHeaderText);

View File

@ -428,10 +428,7 @@ void main() {
find.descendant(of: find.byType(Dialog), matching: find.byType(Material)), find.descendant(of: find.byType(Dialog), matching: find.byType(Material)),
); );
expect(bottomLeft.dx, 480.0); expect(bottomLeft.dx, 480.0);
if (!kIsWeb || isSkiaWeb) { expect(bottomLeft.dy, 124.0);
// https://github.com/flutter/flutter/issues/99933
expect(bottomLeft.dy, 124.0);
}
}); });
testWidgets('Material2 - Dialog alignment takes priority over theme', ( testWidgets('Material2 - Dialog alignment takes priority over theme', (

View File

@ -7,7 +7,6 @@
@Tags(<String>['reduced-test-set']) @Tags(<String>['reduced-test-set'])
library; library;
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
@ -847,7 +846,7 @@ void main() {
// Test the delete button icon. // Test the delete button icon.
expect(tester.getSize(find.byIcon(Icons.clear)), const Size(18.0, 18.0)); expect(tester.getSize(find.byIcon(Icons.clear)), const Size(18.0, 18.0));
expect(getIconData(tester).color, theme.colorScheme.onSurfaceVariant); expect(getIconData(tester).color, theme.colorScheme.onSurfaceVariant);
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Material2 - FilterChip supports delete button', (WidgetTester tester) async { testWidgets('Material2 - FilterChip supports delete button', (WidgetTester tester) async {
final ThemeData theme = ThemeData(useMaterial3: false); final ThemeData theme = ThemeData(useMaterial3: false);

View File

@ -7,7 +7,6 @@
@Tags(<String>['reduced-test-set']) @Tags(<String>['reduced-test-set'])
library; library;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -490,7 +489,7 @@ void main() {
expect(semantics, hasSemantics(expectedSemantics, ignoreTransform: true)); expect(semantics, hasSemantics(expectedSemantics, ignoreTransform: true));
semantics.dispose(); semantics.dispose();
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Material2 - Collapsed FlexibleSpaceBar has correct semantics', ( testWidgets('Material2 - Collapsed FlexibleSpaceBar has correct semantics', (
WidgetTester tester, WidgetTester tester,

View File

@ -119,7 +119,7 @@ void main() {
await tester.pump(const Duration(milliseconds: 200)); // wait for splash to be well under way await tester.pump(const Duration(milliseconds: 200)); // wait for splash to be well under way
final RenderBox box = Material.of(tester.element(find.byType(InkWell))) as RenderBox; final RenderBox box = Material.of(tester.element(find.byType(InkWell))) as RenderBox;
if (kIsWeb && isSkiaWeb) { if (kIsWeb) {
expect( expect(
box, box,
paints paints
@ -153,7 +153,7 @@ void main() {
); );
await gesture.up(); await gesture.up();
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('The InkWell widget renders an ink ripple', (WidgetTester tester) async { testWidgets('The InkWell widget renders an ink ripple', (WidgetTester tester) async {
const Color highlightColor = Color(0xAAFF0000); const Color highlightColor = Color(0xAAFF0000);

View File

@ -118,11 +118,11 @@ void main() {
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.text('test'))); final TestGesture gesture = await tester.startGesture(tester.getCenter(find.text('test')));
final MaterialInkController material = Material.of(tester.element(find.text('test'))); final MaterialInkController material = Material.of(tester.element(find.text('test')));
await tester.pump(const Duration(milliseconds: 200)); await tester.pump(const Duration(milliseconds: 200));
expect(material, paintsExactlyCountTimes(#drawRect, (kIsWeb && isSkiaWeb ? 1 : 2))); expect(material, paintsExactlyCountTimes(#drawRect, (kIsWeb ? 1 : 2)));
await gesture.up(); await gesture.up();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
} }
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
// Regression test for https://github.com/flutter/flutter/issues/136441. // Regression test for https://github.com/flutter/flutter/issues/136441.
testWidgets('PageView item can dispose when widget with NoSplash.splashFactory is tapped', ( testWidgets('PageView item can dispose when widget with NoSplash.splashFactory is tapped', (

View File

@ -4833,12 +4833,6 @@ void main() {
const double helperStartPadding = 12.0; const double helperStartPadding = 12.0;
const double counterEndPadding = 12.0; const double counterEndPadding = 12.0;
// Actual size varies a little on web platforms with HTML renderer.
// TODO(bleroux): remove closeTo usage when https://github.com/flutter/flutter/issues/99933 is fixed.
final Matcher closeToFullHeight = closeTo(fullHeight, 0.1);
final Matcher closeToHelperHeight = closeTo(helperHeight, 0.1);
final Matcher closeToErrorHeight = closeTo(errorHeight, 0.1);
group('for filled text field', () { group('for filled text field', () {
group('when field is enabled', () { group('when field is enabled', () {
testWidgets('Helper and counter are correctly positioned', (WidgetTester tester) async { testWidgets('Helper and counter are correctly positioned', (WidgetTester tester) async {
@ -4853,13 +4847,13 @@ void main() {
), ),
); );
expect(getDecoratorRect(tester).height, closeToFullHeight); expect(getDecoratorRect(tester).height, fullHeight);
expect(getBorderBottom(tester), containerHeight); expect(getBorderBottom(tester), containerHeight);
expect(getHelperRect(tester).top, containerHeight + helperGap); expect(getHelperRect(tester).top, containerHeight + helperGap);
expect(getHelperRect(tester).height, closeToHelperHeight); expect(getHelperRect(tester).height, helperHeight);
expect(getHelperRect(tester).left, helperStartPadding); expect(getHelperRect(tester).left, helperStartPadding);
expect(getCounterRect(tester).top, containerHeight + helperGap); expect(getCounterRect(tester).top, containerHeight + helperGap);
expect(getCounterRect(tester).height, closeToHelperHeight); expect(getCounterRect(tester).height, helperHeight);
expect(getCounterRect(tester).right, 800 - counterEndPadding); expect(getCounterRect(tester).right, 800 - counterEndPadding);
}); });
@ -4897,13 +4891,13 @@ void main() {
), ),
); );
expect(getDecoratorRect(tester).height, closeToFullHeight); expect(getDecoratorRect(tester).height, fullHeight);
expect(getBorderBottom(tester), containerHeight); expect(getBorderBottom(tester), containerHeight);
expect(getHelperRect(tester).top, containerHeight + helperGap); expect(getHelperRect(tester).top, containerHeight + helperGap);
expect(getHelperRect(tester).height, closeToHelperHeight); expect(getHelperRect(tester).height, helperHeight);
expect(getHelperRect(tester).left, helperStartPadding); expect(getHelperRect(tester).left, helperStartPadding);
expect(getCounterRect(tester).top, containerHeight + helperGap); expect(getCounterRect(tester).top, containerHeight + helperGap);
expect(getCounterRect(tester).height, closeToHelperHeight); expect(getCounterRect(tester).height, helperHeight);
expect(getCounterRect(tester).right, 800 - counterEndPadding); expect(getCounterRect(tester).right, 800 - counterEndPadding);
}); });
@ -4942,13 +4936,13 @@ void main() {
), ),
); );
expect(getDecoratorRect(tester).height, closeToFullHeight); expect(getDecoratorRect(tester).height, fullHeight);
expect(getBorderBottom(tester), containerHeight); expect(getBorderBottom(tester), containerHeight);
expect(getHelperRect(tester).top, containerHeight + helperGap); expect(getHelperRect(tester).top, containerHeight + helperGap);
expect(getHelperRect(tester).height, closeToHelperHeight); expect(getHelperRect(tester).height, helperHeight);
expect(getHelperRect(tester).left, helperStartPadding); expect(getHelperRect(tester).left, helperStartPadding);
expect(getCounterRect(tester).top, containerHeight + helperGap); expect(getCounterRect(tester).top, containerHeight + helperGap);
expect(getCounterRect(tester).height, closeToHelperHeight); expect(getCounterRect(tester).height, helperHeight);
expect(getCounterRect(tester).right, 800 - counterEndPadding); expect(getCounterRect(tester).right, 800 - counterEndPadding);
}); });
@ -4987,13 +4981,13 @@ void main() {
), ),
); );
expect(getDecoratorRect(tester).height, closeToFullHeight); expect(getDecoratorRect(tester).height, fullHeight);
expect(getBorderBottom(tester), containerHeight); expect(getBorderBottom(tester), containerHeight);
expect(getHelperRect(tester).top, containerHeight + helperGap); expect(getHelperRect(tester).top, containerHeight + helperGap);
expect(getHelperRect(tester).height, closeToHelperHeight); expect(getHelperRect(tester).height, helperHeight);
expect(getHelperRect(tester).left, helperStartPadding); expect(getHelperRect(tester).left, helperStartPadding);
expect(getCounterRect(tester).top, containerHeight + helperGap); expect(getCounterRect(tester).top, containerHeight + helperGap);
expect(getCounterRect(tester).height, closeToHelperHeight); expect(getCounterRect(tester).height, helperHeight);
expect(getCounterRect(tester).right, 800 - counterEndPadding); expect(getCounterRect(tester).right, 800 - counterEndPadding);
}); });
@ -5054,13 +5048,13 @@ void main() {
), ),
); );
expect(getDecoratorRect(tester).height, closeToFullHeight); expect(getDecoratorRect(tester).height, fullHeight);
expect(getBorderBottom(tester), containerHeight); expect(getBorderBottom(tester), containerHeight);
expect(getErrorRect(tester).top, containerHeight + helperGap); expect(getErrorRect(tester).top, containerHeight + helperGap);
expect(getErrorRect(tester).height, closeToErrorHeight); expect(getErrorRect(tester).height, errorHeight);
expect(getErrorRect(tester).left, helperStartPadding); expect(getErrorRect(tester).left, helperStartPadding);
expect(getCounterRect(tester).top, containerHeight + helperGap); expect(getCounterRect(tester).top, containerHeight + helperGap);
expect(getCounterRect(tester).height, closeToErrorHeight); expect(getCounterRect(tester).height, errorHeight);
expect(getCounterRect(tester).right, 800 - counterEndPadding); expect(getCounterRect(tester).right, 800 - counterEndPadding);
}); });
@ -5105,13 +5099,13 @@ void main() {
), ),
); );
expect(getDecoratorRect(tester).height, closeToFullHeight); expect(getDecoratorRect(tester).height, fullHeight);
expect(getBorderBottom(tester), containerHeight); expect(getBorderBottom(tester), containerHeight);
expect(getHelperRect(tester).top, containerHeight + helperGap); expect(getHelperRect(tester).top, containerHeight + helperGap);
expect(getHelperRect(tester).height, closeToHelperHeight); expect(getHelperRect(tester).height, helperHeight);
expect(getHelperRect(tester).left, helperStartPadding); expect(getHelperRect(tester).left, helperStartPadding);
expect(getCounterRect(tester).top, containerHeight + helperGap); expect(getCounterRect(tester).top, containerHeight + helperGap);
expect(getCounterRect(tester).height, closeToHelperHeight); expect(getCounterRect(tester).height, helperHeight);
expect(getCounterRect(tester).right, 800 - counterEndPadding); expect(getCounterRect(tester).right, 800 - counterEndPadding);
}); });
@ -5149,13 +5143,13 @@ void main() {
), ),
); );
expect(getDecoratorRect(tester).height, closeToFullHeight); expect(getDecoratorRect(tester).height, fullHeight);
expect(getBorderBottom(tester), containerHeight); expect(getBorderBottom(tester), containerHeight);
expect(getHelperRect(tester).top, containerHeight + helperGap); expect(getHelperRect(tester).top, containerHeight + helperGap);
expect(getHelperRect(tester).height, closeToHelperHeight); expect(getHelperRect(tester).height, helperHeight);
expect(getHelperRect(tester).left, helperStartPadding); expect(getHelperRect(tester).left, helperStartPadding);
expect(getCounterRect(tester).top, containerHeight + helperGap); expect(getCounterRect(tester).top, containerHeight + helperGap);
expect(getCounterRect(tester).height, closeToHelperHeight); expect(getCounterRect(tester).height, helperHeight);
expect(getCounterRect(tester).right, 800 - counterEndPadding); expect(getCounterRect(tester).right, 800 - counterEndPadding);
}); });
@ -5194,13 +5188,13 @@ void main() {
), ),
); );
expect(getDecoratorRect(tester).height, closeToFullHeight); expect(getDecoratorRect(tester).height, fullHeight);
expect(getBorderBottom(tester), containerHeight); expect(getBorderBottom(tester), containerHeight);
expect(getHelperRect(tester).top, containerHeight + helperGap); expect(getHelperRect(tester).top, containerHeight + helperGap);
expect(getHelperRect(tester).height, closeToHelperHeight); expect(getHelperRect(tester).height, helperHeight);
expect(getHelperRect(tester).left, helperStartPadding); expect(getHelperRect(tester).left, helperStartPadding);
expect(getCounterRect(tester).top, containerHeight + helperGap); expect(getCounterRect(tester).top, containerHeight + helperGap);
expect(getCounterRect(tester).height, closeToHelperHeight); expect(getCounterRect(tester).height, helperHeight);
expect(getCounterRect(tester).right, 800 - counterEndPadding); expect(getCounterRect(tester).right, 800 - counterEndPadding);
}); });
@ -5239,13 +5233,13 @@ void main() {
), ),
); );
expect(getDecoratorRect(tester).height, closeToFullHeight); expect(getDecoratorRect(tester).height, fullHeight);
expect(getBorderBottom(tester), containerHeight); expect(getBorderBottom(tester), containerHeight);
expect(getHelperRect(tester).top, containerHeight + helperGap); expect(getHelperRect(tester).top, containerHeight + helperGap);
expect(getHelperRect(tester).height, closeToHelperHeight); expect(getHelperRect(tester).height, helperHeight);
expect(getHelperRect(tester).left, helperStartPadding); expect(getHelperRect(tester).left, helperStartPadding);
expect(getCounterRect(tester).top, containerHeight + helperGap); expect(getCounterRect(tester).top, containerHeight + helperGap);
expect(getCounterRect(tester).height, closeToHelperHeight); expect(getCounterRect(tester).height, helperHeight);
expect(getCounterRect(tester).right, 800 - counterEndPadding); expect(getCounterRect(tester).right, 800 - counterEndPadding);
}); });
@ -5306,13 +5300,13 @@ void main() {
), ),
); );
expect(getDecoratorRect(tester).height, closeToFullHeight); expect(getDecoratorRect(tester).height, fullHeight);
expect(getBorderBottom(tester), containerHeight); expect(getBorderBottom(tester), containerHeight);
expect(getErrorRect(tester).top, containerHeight + helperGap); expect(getErrorRect(tester).top, containerHeight + helperGap);
expect(getErrorRect(tester).height, closeToErrorHeight); expect(getErrorRect(tester).height, errorHeight);
expect(getErrorRect(tester).left, helperStartPadding); expect(getErrorRect(tester).left, helperStartPadding);
expect(getCounterRect(tester).top, containerHeight + helperGap); expect(getCounterRect(tester).top, containerHeight + helperGap);
expect(getCounterRect(tester).height, closeToErrorHeight); expect(getCounterRect(tester).height, errorHeight);
expect(getCounterRect(tester).right, 800 - counterEndPadding); expect(getCounterRect(tester).right, 800 - counterEndPadding);
}); });

View File

@ -160,10 +160,7 @@ void main() {
await tester.pumpWidget(buildFrame(isTwoLine: true, textScaler: const TextScaler.linear(4.0))); await tester.pumpWidget(buildFrame(isTwoLine: true, textScaler: const TextScaler.linear(4.0)));
testChildren(); testChildren();
testHorizontalGeometry(); testHorizontalGeometry();
if (!kIsWeb || isSkiaWeb) { testVerticalGeometry(192.0);
// https://github.com/flutter/flutter/issues/99933
testVerticalGeometry(192.0);
}
// Make sure that the height of a large subtitle is taken into account. // Make sure that the height of a large subtitle is taken into account.
await tester.pumpWidget( await tester.pumpWidget(
@ -175,20 +172,14 @@ void main() {
); );
testChildren(); testChildren();
testHorizontalGeometry(); testHorizontalGeometry();
if (!kIsWeb || isSkiaWeb) { testVerticalGeometry(108.0);
// https://github.com/flutter/flutter/issues/99933
testVerticalGeometry(108.0);
}
await tester.pumpWidget( await tester.pumpWidget(
buildFrame(isThreeLine: true, textScaler: const TextScaler.linear(4.0)), buildFrame(isThreeLine: true, textScaler: const TextScaler.linear(4.0)),
); );
testChildren(); testChildren();
testHorizontalGeometry(); testHorizontalGeometry();
if (!kIsWeb || isSkiaWeb) { testVerticalGeometry(192.0);
// https://github.com/flutter/flutter/issues/99933
testVerticalGeometry(192.0);
}
}); });
testWidgets('ListTile geometry (RTL)', (WidgetTester tester) async { testWidgets('ListTile geometry (RTL)', (WidgetTester tester) async {
@ -536,10 +527,6 @@ void main() {
), ),
); );
if (kIsWeb && !isSkiaWeb) {
// https://github.com/flutter/flutter/issues/99933
return;
}
const double height = 300; const double height = 300;
const double avatarTop = 130.0; const double avatarTop = 130.0;
const double placeholderTop = 138.0; const double placeholderTop = 138.0;

View File

@ -2655,187 +2655,176 @@ void main() {
expect(closed, unorderedEquals(<TestMenu>[TestMenu.mainMenu1, TestMenu.subMenu11])); expect(closed, unorderedEquals(<TestMenu>[TestMenu.mainMenu1, TestMenu.subMenu11]));
expect(opened, isEmpty); expect(opened, isEmpty);
}); });
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/145527 });
group('MenuItemButton', () { group('MenuItemButton', () {
testWidgets( testWidgets('Shortcut mnemonics are displayed', (WidgetTester tester) async {
'Shortcut mnemonics are displayed', await tester.pumpWidget(
(WidgetTester tester) async { MaterialApp(
await tester.pumpWidget( home: Material(
MaterialApp( child: MenuBar(
home: Material( controller: controller,
child: MenuBar( children: createTestMenus(
controller: controller, shortcuts: <TestMenu, MenuSerializableShortcut>{
children: createTestMenus( TestMenu.subSubMenu110: const SingleActivator(
shortcuts: <TestMenu, MenuSerializableShortcut>{ LogicalKeyboardKey.keyA,
TestMenu.subSubMenu110: const SingleActivator( control: true,
LogicalKeyboardKey.keyA, ),
control: true, TestMenu.subSubMenu111: const SingleActivator(
), LogicalKeyboardKey.keyB,
TestMenu.subSubMenu111: const SingleActivator( shift: true,
LogicalKeyboardKey.keyB, ),
shift: true, TestMenu.subSubMenu112: const SingleActivator(LogicalKeyboardKey.keyC, alt: true),
), TestMenu.subSubMenu113: const SingleActivator(
TestMenu.subSubMenu112: const SingleActivator( LogicalKeyboardKey.keyD,
LogicalKeyboardKey.keyC, meta: true,
alt: true, ),
), },
TestMenu.subSubMenu113: const SingleActivator(
LogicalKeyboardKey.keyD,
meta: true,
),
},
),
), ),
), ),
), ),
); ),
);
// Open a menu initially. // Open a menu initially.
await tester.tap(find.text(TestMenu.mainMenu1.label)); await tester.tap(find.text(TestMenu.mainMenu1.label));
await tester.pump(); await tester.pump();
await tester.tap(find.text(TestMenu.subMenu11.label)); await tester.tap(find.text(TestMenu.subMenu11.label));
await tester.pump(); await tester.pump();
Text mnemonic0 = tester.widget(findMnemonic(TestMenu.subSubMenu110.label)); Text mnemonic0 = tester.widget(findMnemonic(TestMenu.subSubMenu110.label));
Text mnemonic1 = tester.widget(findMnemonic(TestMenu.subSubMenu111.label)); Text mnemonic1 = tester.widget(findMnemonic(TestMenu.subSubMenu111.label));
Text mnemonic2 = tester.widget(findMnemonic(TestMenu.subSubMenu112.label)); Text mnemonic2 = tester.widget(findMnemonic(TestMenu.subSubMenu112.label));
Text mnemonic3 = tester.widget(findMnemonic(TestMenu.subSubMenu113.label)); Text mnemonic3 = tester.widget(findMnemonic(TestMenu.subSubMenu113.label));
switch (defaultTargetPlatform) { switch (defaultTargetPlatform) {
case TargetPlatform.android: case TargetPlatform.android:
case TargetPlatform.fuchsia: case TargetPlatform.fuchsia:
case TargetPlatform.linux: case TargetPlatform.linux:
expect(mnemonic0.data, equals('Ctrl+A')); expect(mnemonic0.data, equals('Ctrl+A'));
expect(mnemonic1.data, equals('Shift+B')); expect(mnemonic1.data, equals('Shift+B'));
expect(mnemonic2.data, equals('Alt+C')); expect(mnemonic2.data, equals('Alt+C'));
expect(mnemonic3.data, equals('Meta+D')); expect(mnemonic3.data, equals('Meta+D'));
case TargetPlatform.windows: case TargetPlatform.windows:
expect(mnemonic0.data, equals('Ctrl+A')); expect(mnemonic0.data, equals('Ctrl+A'));
expect(mnemonic1.data, equals('Shift+B')); expect(mnemonic1.data, equals('Shift+B'));
expect(mnemonic2.data, equals('Alt+C')); expect(mnemonic2.data, equals('Alt+C'));
expect(mnemonic3.data, equals('Win+D')); expect(mnemonic3.data, equals('Win+D'));
case TargetPlatform.iOS: case TargetPlatform.iOS:
case TargetPlatform.macOS: case TargetPlatform.macOS:
expect(mnemonic0.data, equals('⌃ A')); expect(mnemonic0.data, equals('⌃ A'));
expect(mnemonic1.data, equals('⇧ B')); expect(mnemonic1.data, equals('⇧ B'));
expect(mnemonic2.data, equals('⌥ C')); expect(mnemonic2.data, equals('⌥ C'));
expect(mnemonic3.data, equals('⌘ D')); expect(mnemonic3.data, equals('⌘ D'));
} }
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Material( home: Material(
child: MenuBar( child: MenuBar(
controller: controller, controller: controller,
children: createTestMenus( children: createTestMenus(
includeExtraGroups: true, includeExtraGroups: true,
shortcuts: <TestMenu, MenuSerializableShortcut>{ shortcuts: <TestMenu, MenuSerializableShortcut>{
TestMenu.subSubMenu110: const SingleActivator(LogicalKeyboardKey.arrowRight), TestMenu.subSubMenu110: const SingleActivator(LogicalKeyboardKey.arrowRight),
TestMenu.subSubMenu111: const SingleActivator(LogicalKeyboardKey.arrowLeft), TestMenu.subSubMenu111: const SingleActivator(LogicalKeyboardKey.arrowLeft),
TestMenu.subSubMenu112: const SingleActivator(LogicalKeyboardKey.arrowUp), TestMenu.subSubMenu112: const SingleActivator(LogicalKeyboardKey.arrowUp),
TestMenu.subSubMenu113: const SingleActivator(LogicalKeyboardKey.arrowDown), TestMenu.subSubMenu113: const SingleActivator(LogicalKeyboardKey.arrowDown),
}, },
),
), ),
), ),
), ),
); ),
await tester.pumpAndSettle(); );
await tester.pumpAndSettle();
mnemonic0 = tester.widget(findMnemonic(TestMenu.subSubMenu110.label)); mnemonic0 = tester.widget(findMnemonic(TestMenu.subSubMenu110.label));
expect(mnemonic0.data, equals('')); expect(mnemonic0.data, equals(''));
mnemonic1 = tester.widget(findMnemonic(TestMenu.subSubMenu111.label)); mnemonic1 = tester.widget(findMnemonic(TestMenu.subSubMenu111.label));
expect(mnemonic1.data, equals('')); expect(mnemonic1.data, equals(''));
mnemonic2 = tester.widget(findMnemonic(TestMenu.subSubMenu112.label)); mnemonic2 = tester.widget(findMnemonic(TestMenu.subSubMenu112.label));
expect(mnemonic2.data, equals('')); expect(mnemonic2.data, equals(''));
mnemonic3 = tester.widget(findMnemonic(TestMenu.subSubMenu113.label)); mnemonic3 = tester.widget(findMnemonic(TestMenu.subSubMenu113.label));
expect(mnemonic3.data, equals('')); expect(mnemonic3.data, equals(''));
// Try some weirder ones. // Try some weirder ones.
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Material( home: Material(
child: MenuBar( child: MenuBar(
controller: controller, controller: controller,
children: createTestMenus( children: createTestMenus(
shortcuts: <TestMenu, MenuSerializableShortcut>{ shortcuts: <TestMenu, MenuSerializableShortcut>{
TestMenu.subSubMenu110: const SingleActivator(LogicalKeyboardKey.escape), TestMenu.subSubMenu110: const SingleActivator(LogicalKeyboardKey.escape),
TestMenu.subSubMenu111: const SingleActivator(LogicalKeyboardKey.fn), TestMenu.subSubMenu111: const SingleActivator(LogicalKeyboardKey.fn),
TestMenu.subSubMenu112: const SingleActivator(LogicalKeyboardKey.enter), TestMenu.subSubMenu112: const SingleActivator(LogicalKeyboardKey.enter),
}, },
),
), ),
), ),
), ),
); ),
await tester.pumpAndSettle(); );
await tester.pumpAndSettle();
mnemonic0 = tester.widget(findMnemonic(TestMenu.subSubMenu110.label)); mnemonic0 = tester.widget(findMnemonic(TestMenu.subSubMenu110.label));
expect(mnemonic0.data, equals('Esc')); expect(mnemonic0.data, equals('Esc'));
mnemonic1 = tester.widget(findMnemonic(TestMenu.subSubMenu111.label)); mnemonic1 = tester.widget(findMnemonic(TestMenu.subSubMenu111.label));
expect(mnemonic1.data, equals('Fn')); expect(mnemonic1.data, equals('Fn'));
mnemonic2 = tester.widget(findMnemonic(TestMenu.subSubMenu112.label)); mnemonic2 = tester.widget(findMnemonic(TestMenu.subSubMenu112.label));
expect(mnemonic2.data, equals('')); expect(mnemonic2.data, equals(''));
}, }, variant: TargetPlatformVariant.all());
variant: TargetPlatformVariant.all(),
skip: kIsWeb && !isCanvasKit, // https://github.com/flutter/flutter/issues/145527
);
// Regression test for https://github.com/flutter/flutter/issues/145040. // Regression test for https://github.com/flutter/flutter/issues/145040.
testWidgets( testWidgets('CharacterActivator shortcut mnemonics include modifiers', (
'CharacterActivator shortcut mnemonics include modifiers', WidgetTester tester,
(WidgetTester tester) async { ) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Material( home: Material(
child: MenuBar( child: MenuBar(
controller: controller, controller: controller,
children: createTestMenus( children: createTestMenus(
shortcuts: <TestMenu, MenuSerializableShortcut>{ shortcuts: <TestMenu, MenuSerializableShortcut>{
TestMenu.subSubMenu110: const CharacterActivator('A', control: true), TestMenu.subSubMenu110: const CharacterActivator('A', control: true),
TestMenu.subSubMenu111: const CharacterActivator('B', alt: true), TestMenu.subSubMenu111: const CharacterActivator('B', alt: true),
TestMenu.subSubMenu112: const CharacterActivator('C', meta: true), TestMenu.subSubMenu112: const CharacterActivator('C', meta: true),
}, },
),
), ),
), ),
), ),
); ),
);
// Open a menu initially. // Open a menu initially.
await tester.tap(find.text(TestMenu.mainMenu1.label)); await tester.tap(find.text(TestMenu.mainMenu1.label));
await tester.pump(); await tester.pump();
await tester.tap(find.text(TestMenu.subMenu11.label)); await tester.tap(find.text(TestMenu.subMenu11.label));
await tester.pump(); await tester.pump();
final Text mnemonic0 = tester.widget(findMnemonic(TestMenu.subSubMenu110.label)); final Text mnemonic0 = tester.widget(findMnemonic(TestMenu.subSubMenu110.label));
final Text mnemonic1 = tester.widget(findMnemonic(TestMenu.subSubMenu111.label)); final Text mnemonic1 = tester.widget(findMnemonic(TestMenu.subSubMenu111.label));
final Text mnemonic2 = tester.widget(findMnemonic(TestMenu.subSubMenu112.label)); final Text mnemonic2 = tester.widget(findMnemonic(TestMenu.subSubMenu112.label));
switch (defaultTargetPlatform) { switch (defaultTargetPlatform) {
case TargetPlatform.android: case TargetPlatform.android:
case TargetPlatform.fuchsia: case TargetPlatform.fuchsia:
case TargetPlatform.linux: case TargetPlatform.linux:
expect(mnemonic0.data, equals('Ctrl+A')); expect(mnemonic0.data, equals('Ctrl+A'));
expect(mnemonic1.data, equals('Alt+B')); expect(mnemonic1.data, equals('Alt+B'));
expect(mnemonic2.data, equals('Meta+C')); expect(mnemonic2.data, equals('Meta+C'));
case TargetPlatform.windows: case TargetPlatform.windows:
expect(mnemonic0.data, equals('Ctrl+A')); expect(mnemonic0.data, equals('Ctrl+A'));
expect(mnemonic1.data, equals('Alt+B')); expect(mnemonic1.data, equals('Alt+B'));
expect(mnemonic2.data, equals('Win+C')); expect(mnemonic2.data, equals('Win+C'));
case TargetPlatform.iOS: case TargetPlatform.iOS:
case TargetPlatform.macOS: case TargetPlatform.macOS:
expect(mnemonic0.data, equals('⌃ A')); expect(mnemonic0.data, equals('⌃ A'));
expect(mnemonic1.data, equals('⌥ B')); expect(mnemonic1.data, equals('⌥ B'));
expect(mnemonic2.data, equals('⌘ C')); expect(mnemonic2.data, equals('⌘ C'));
} }
}, }, variant: TargetPlatformVariant.all());
variant: TargetPlatformVariant.all(),
skip: kIsWeb && !isCanvasKit, // https://github.com/flutter/flutter/issues/145527
);
testWidgets('leadingIcon is used when set', (WidgetTester tester) async { testWidgets('leadingIcon is used when set', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
@ -2925,7 +2914,7 @@ void main() {
await tester.pump(); await tester.pump();
expect(find.text('trailingIcon'), findsOneWidget); expect(find.text('trailingIcon'), findsOneWidget);
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/145527 });
testWidgets('SubmenuButton uses supplied controller', (WidgetTester tester) async { testWidgets('SubmenuButton uses supplied controller', (WidgetTester tester) async {
final MenuController submenuController = MenuController(); final MenuController submenuController = MenuController();
@ -3163,7 +3152,7 @@ void main() {
// This should throw an error. // This should throw an error.
final AssertionError exception = tester.takeException() as AssertionError; final AssertionError exception = tester.takeException() as AssertionError;
expect(exception, isAssertionError); expect(exception, isAssertionError);
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('MenuItemButton.styleFrom overlayColor overrides default overlay color', ( testWidgets('MenuItemButton.styleFrom overlayColor overrides default overlay color', (
WidgetTester tester, WidgetTester tester,
@ -4005,7 +3994,7 @@ void main() {
expect(find.text(allExpected), findsOneWidget); expect(find.text(allExpected), findsOneWidget);
expect(find.text(charExpected), findsOneWidget); expect(find.text(charExpected), findsOneWidget);
}, variant: TargetPlatformVariant.all()); }, variant: TargetPlatformVariant.all());
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/145527 });
group('CheckboxMenuButton', () { group('CheckboxMenuButton', () {
testWidgets('tapping toggles checkbox', (WidgetTester tester) async { testWidgets('tapping toggles checkbox', (WidgetTester tester) async {
@ -4425,7 +4414,7 @@ void main() {
expect(material.textStyle?.fontStyle, menuTextStyle.fontStyle); expect(material.textStyle?.fontStyle, menuTextStyle.fontStyle);
expect(material.textStyle?.wordSpacing, menuTextStyle.wordSpacing); expect(material.textStyle?.wordSpacing, menuTextStyle.wordSpacing);
expect(material.textStyle?.decoration, menuTextStyle.decoration); expect(material.textStyle?.decoration, menuTextStyle.decoration);
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/145527 });
testWidgets('SubmenuButton.onFocusChange is respected', (WidgetTester tester) async { testWidgets('SubmenuButton.onFocusChange is respected', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -78,14 +77,11 @@ void main() {
expect(tester.getRect(findMenuPanels().first).size, equals(const Size(600.0, 60.0))); expect(tester.getRect(findMenuPanels().first).size, equals(const Size(600.0, 60.0)));
// MenuTheme affects menus. // MenuTheme affects menus.
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 tester.getRect(findMenuPanels().at(1)),
expect( equals(const Rect.fromLTRB(104.0, 54.0, 204.0, 154.0)),
tester.getRect(findMenuPanels().at(1)), );
equals(const Rect.fromLTRB(104.0, 54.0, 204.0, 154.0)), expect(tester.getRect(findMenuPanels().at(1)).size, equals(const Size(100.0, 100.0)));
);
expect(tester.getRect(findMenuPanels().at(1)).size, equals(const Size(100.0, 100.0)));
}
}); });
testWidgets('maximumSize affects geometry', (WidgetTester tester) async { testWidgets('maximumSize affects geometry', (WidgetTester tester) async {

View File

@ -360,9 +360,7 @@ void main() {
await tester.longPress(find.text(label)); await tester.longPress(find.text(label));
expect(find.text(label), findsNWidgets(2)); expect(find.text(label), findsNWidgets(2));
if (!kIsWeb || isSkiaWeb) { expect(tester.getSize(find.text(label).last), const Size(14.25, 20.0));
expect(tester.getSize(find.text(label).last), const Size(14.25, 20.0));
}
// The duration is needed to ensure the tooltip disappears. // The duration is needed to ensure the tooltip disappears.
await tester.pumpAndSettle(const Duration(seconds: 2)); await tester.pumpAndSettle(const Duration(seconds: 2));
@ -370,9 +368,7 @@ void main() {
expect(find.text(label), findsOneWidget); expect(find.text(label), findsOneWidget);
await tester.longPress(find.text(label)); await tester.longPress(find.text(label));
if (!kIsWeb || isSkiaWeb) { expect(tester.getSize(find.text(label).last), const Size(56.25, 80.0));
expect(tester.getSize(find.text(label).last), const Size(56.25, 80.0));
}
}); });
testWidgets('Material3 - NavigationBar label can scale and has maxScaleFactor', ( testWidgets('Material3 - NavigationBar label can scale and has maxScaleFactor', (
@ -413,31 +409,19 @@ void main() {
await tester.pumpWidget(buildApp(textScaler: TextScaler.noScaling)); await tester.pumpWidget(buildApp(textScaler: TextScaler.noScaling));
expect(find.text(label), findsOneWidget); expect(find.text(label), findsOneWidget);
if (!kIsWeb || isSkiaWeb) { expect(_sizeAlmostEqual(tester.getSize(find.text(label)), const Size(12.5, 16.0)), true);
// https://github.com/flutter/flutter/issues/99933
expect(_sizeAlmostEqual(tester.getSize(find.text(label)), const Size(12.5, 16.0)), true);
}
await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(1.1))); await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(1.1)));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
if (!kIsWeb || isSkiaWeb) { expect(_sizeAlmostEqual(tester.getSize(find.text(label)), const Size(13.7, 18.0)), true);
// https://github.com/flutter/flutter/issues/99933
expect(_sizeAlmostEqual(tester.getSize(find.text(label)), const Size(13.7, 18.0)), true);
}
await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(1.3))); await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(1.3)));
if (!kIsWeb || isSkiaWeb) { expect(_sizeAlmostEqual(tester.getSize(find.text(label)), const Size(16.1, 21.0)), true);
// https://github.com/flutter/flutter/issues/99933
expect(_sizeAlmostEqual(tester.getSize(find.text(label)), const Size(16.1, 21.0)), true);
}
await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(4))); await tester.pumpWidget(buildApp(textScaler: const TextScaler.linear(4)));
if (!kIsWeb || isSkiaWeb) { expect(_sizeAlmostEqual(tester.getSize(find.text(label)), const Size(16.1, 21.0)), true);
// https://github.com/flutter/flutter/issues/99933
expect(_sizeAlmostEqual(tester.getSize(find.text(label)), const Size(16.1, 21.0)), true);
}
}); });
testWidgets('Custom tooltips in NavigationBarDestination', (WidgetTester tester) async { testWidgets('Custom tooltips in NavigationBarDestination', (WidgetTester tester) async {
@ -821,7 +805,7 @@ void main() {
color: const Color(0x0a000000), color: const Color(0x0a000000),
), ),
); );
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Material3 - Navigation indicator ripple golden test', (WidgetTester tester) async { testWidgets('Material3 - Navigation indicator ripple golden test', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/117420. // This is a regression test for https://github.com/flutter/flutter/issues/117420.

View File

@ -807,50 +807,41 @@ void main() {
// The second destination is below the first with some spacing. // The second destination is below the first with some spacing.
nextDestinationY += destinationHeightWithLabel + destinationSpacing; nextDestinationY += destinationHeightWithLabel + destinationSpacing;
final RenderBox secondIconRenderBox = _iconRenderBox(tester, Icons.bookmark_border); final RenderBox secondIconRenderBox = _iconRenderBox(tester, Icons.bookmark_border);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 secondIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
secondIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - secondIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - secondIconRenderBox.size.height) / 2.0,
(destinationWidth - secondIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - secondIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
// The third destination is below the second with some spacing. // The third destination is below the second with some spacing.
nextDestinationY += destinationHeight + destinationSpacing; nextDestinationY += destinationHeight + destinationSpacing;
final RenderBox thirdIconRenderBox = _iconRenderBox(tester, Icons.star_border); final RenderBox thirdIconRenderBox = _iconRenderBox(tester, Icons.star_border);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 thirdIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
thirdIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - thirdIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - thirdIconRenderBox.size.height) / 2.0,
(destinationWidth - thirdIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - thirdIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
// The fourth destination is below the third with some spacing. // The fourth destination is below the third with some spacing.
nextDestinationY += destinationHeight + destinationSpacing; nextDestinationY += destinationHeight + destinationSpacing;
final RenderBox fourthIconRenderBox = _iconRenderBox(tester, Icons.hotel); final RenderBox fourthIconRenderBox = _iconRenderBox(tester, Icons.hotel);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 fourthIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
fourthIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - fourthIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - fourthIconRenderBox.size.height) / 2.0,
(destinationWidth - fourthIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - fourthIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
}, },
); );
@ -912,50 +903,41 @@ void main() {
// The second destination is below the first with some spacing. // The second destination is below the first with some spacing.
nextDestinationY += destinationHeightWithLabel + destinationSpacing; nextDestinationY += destinationHeightWithLabel + destinationSpacing;
final RenderBox secondIconRenderBox = _iconRenderBox(tester, Icons.bookmark_border); final RenderBox secondIconRenderBox = _iconRenderBox(tester, Icons.bookmark_border);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 secondIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
secondIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - secondIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - secondIconRenderBox.size.height) / 2.0,
(destinationWidth - secondIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - secondIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
// The third destination is below the second with some spacing. // The third destination is below the second with some spacing.
nextDestinationY += destinationHeight + destinationSpacing; nextDestinationY += destinationHeight + destinationSpacing;
final RenderBox thirdIconRenderBox = _iconRenderBox(tester, Icons.star_border); final RenderBox thirdIconRenderBox = _iconRenderBox(tester, Icons.star_border);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 thirdIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
thirdIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - thirdIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - thirdIconRenderBox.size.height) / 2.0,
(destinationWidth - thirdIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - thirdIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
// The fourth destination is below the third with some spacing. // The fourth destination is below the third with some spacing.
nextDestinationY += destinationHeight + destinationSpacing; nextDestinationY += destinationHeight + destinationSpacing;
final RenderBox fourthIconRenderBox = _iconRenderBox(tester, Icons.hotel); final RenderBox fourthIconRenderBox = _iconRenderBox(tester, Icons.hotel);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 fourthIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
fourthIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - fourthIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - fourthIconRenderBox.size.height) / 2.0,
(destinationWidth - fourthIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - fourthIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
}); });
testWidgets('Destination spacing is correct - [labelType]=selected, [textScaleFactor]=0.75', ( testWidgets('Destination spacing is correct - [labelType]=selected, [textScaleFactor]=0.75', (
@ -1016,50 +998,41 @@ void main() {
// The second destination is below the first with some spacing. // The second destination is below the first with some spacing.
nextDestinationY += destinationHeightWithLabel + destinationSpacing; nextDestinationY += destinationHeightWithLabel + destinationSpacing;
final RenderBox secondIconRenderBox = _iconRenderBox(tester, Icons.bookmark_border); final RenderBox secondIconRenderBox = _iconRenderBox(tester, Icons.bookmark_border);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 secondIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
secondIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - secondIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - secondIconRenderBox.size.height) / 2.0,
(destinationWidth - secondIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - secondIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
// The third destination is below the second with some spacing. // The third destination is below the second with some spacing.
nextDestinationY += destinationHeight + destinationSpacing; nextDestinationY += destinationHeight + destinationSpacing;
final RenderBox thirdIconRenderBox = _iconRenderBox(tester, Icons.star_border); final RenderBox thirdIconRenderBox = _iconRenderBox(tester, Icons.star_border);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 thirdIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
thirdIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - thirdIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - thirdIconRenderBox.size.height) / 2.0,
(destinationWidth - thirdIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - thirdIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
// The fourth destination is below the third with some spacing. // The fourth destination is below the third with some spacing.
nextDestinationY += destinationHeight + destinationSpacing; nextDestinationY += destinationHeight + destinationSpacing;
final RenderBox fourthIconRenderBox = _iconRenderBox(tester, Icons.hotel); final RenderBox fourthIconRenderBox = _iconRenderBox(tester, Icons.hotel);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 fourthIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
fourthIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - fourthIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - fourthIconRenderBox.size.height) / 2.0,
(destinationWidth - fourthIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - fourthIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
}); });
testWidgets('Destination spacing is correct - [labelType]=all, [textScaleFactor]=1.0 (default)', ( testWidgets('Destination spacing is correct - [labelType]=all, [textScaleFactor]=1.0 (default)', (
@ -1119,50 +1092,41 @@ void main() {
// The second destination is below the first with some spacing. // The second destination is below the first with some spacing.
nextDestinationY += destinationHeightWithLabel + destinationSpacing; nextDestinationY += destinationHeightWithLabel + destinationSpacing;
final RenderBox secondIconRenderBox = _iconRenderBox(tester, Icons.bookmark_border); final RenderBox secondIconRenderBox = _iconRenderBox(tester, Icons.bookmark_border);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 secondIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
secondIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - secondIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - secondIconRenderBox.size.height) / 2.0,
(destinationWidth - secondIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - secondIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
// The third destination is below the second with some spacing. // The third destination is below the second with some spacing.
nextDestinationY += destinationHeightWithLabel + destinationSpacing; nextDestinationY += destinationHeightWithLabel + destinationSpacing;
final RenderBox thirdIconRenderBox = _iconRenderBox(tester, Icons.star_border); final RenderBox thirdIconRenderBox = _iconRenderBox(tester, Icons.star_border);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 thirdIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
thirdIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - thirdIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - thirdIconRenderBox.size.height) / 2.0,
(destinationWidth - thirdIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - thirdIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
// The fourth destination is below the third with some spacing. // The fourth destination is below the third with some spacing.
nextDestinationY += destinationHeightWithLabel + destinationSpacing; nextDestinationY += destinationHeightWithLabel + destinationSpacing;
final RenderBox fourthIconRenderBox = _iconRenderBox(tester, Icons.hotel); final RenderBox fourthIconRenderBox = _iconRenderBox(tester, Icons.hotel);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 fourthIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
fourthIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - fourthIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - fourthIconRenderBox.size.height) / 2.0,
(destinationWidth - fourthIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - fourthIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
}); });
testWidgets('Destination spacing is correct - [labelType]=all, [textScaleFactor]=3.0', ( testWidgets('Destination spacing is correct - [labelType]=all, [textScaleFactor]=3.0', (
@ -1223,50 +1187,41 @@ void main() {
// The second destination is below the first with some spacing. // The second destination is below the first with some spacing.
nextDestinationY += destinationHeightWithLabel + destinationSpacing; nextDestinationY += destinationHeightWithLabel + destinationSpacing;
final RenderBox secondIconRenderBox = _iconRenderBox(tester, Icons.bookmark_border); final RenderBox secondIconRenderBox = _iconRenderBox(tester, Icons.bookmark_border);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 secondIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
secondIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - secondIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - secondIconRenderBox.size.height) / 2.0,
(destinationWidth - secondIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - secondIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
// The third destination is below the second with some spacing. // The third destination is below the second with some spacing.
nextDestinationY += destinationHeightWithLabel + destinationSpacing; nextDestinationY += destinationHeightWithLabel + destinationSpacing;
final RenderBox thirdIconRenderBox = _iconRenderBox(tester, Icons.star_border); final RenderBox thirdIconRenderBox = _iconRenderBox(tester, Icons.star_border);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 thirdIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
thirdIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - thirdIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - thirdIconRenderBox.size.height) / 2.0,
(destinationWidth - thirdIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - thirdIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
// The fourth destination is below the third with some spacing. // The fourth destination is below the third with some spacing.
nextDestinationY += destinationHeightWithLabel + destinationSpacing; nextDestinationY += destinationHeightWithLabel + destinationSpacing;
final RenderBox fourthIconRenderBox = _iconRenderBox(tester, Icons.hotel); final RenderBox fourthIconRenderBox = _iconRenderBox(tester, Icons.hotel);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 fourthIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
fourthIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - fourthIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - fourthIconRenderBox.size.height) / 2.0,
(destinationWidth - fourthIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - fourthIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
}); });
testWidgets('Destination spacing is correct - [labelType]=all, [textScaleFactor]=0.75', ( testWidgets('Destination spacing is correct - [labelType]=all, [textScaleFactor]=0.75', (
@ -1327,50 +1282,41 @@ void main() {
// The second destination is below the first with some spacing. // The second destination is below the first with some spacing.
nextDestinationY += destinationHeightWithLabel + destinationSpacing; nextDestinationY += destinationHeightWithLabel + destinationSpacing;
final RenderBox secondIconRenderBox = _iconRenderBox(tester, Icons.bookmark_border); final RenderBox secondIconRenderBox = _iconRenderBox(tester, Icons.bookmark_border);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 secondIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
secondIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - secondIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - secondIconRenderBox.size.height) / 2.0,
(destinationWidth - secondIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - secondIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
// The third destination is below the second with some spacing. // The third destination is below the second with some spacing.
nextDestinationY += destinationHeightWithLabel + destinationSpacing; nextDestinationY += destinationHeightWithLabel + destinationSpacing;
final RenderBox thirdIconRenderBox = _iconRenderBox(tester, Icons.star_border); final RenderBox thirdIconRenderBox = _iconRenderBox(tester, Icons.star_border);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 thirdIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
thirdIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - thirdIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - thirdIconRenderBox.size.height) / 2.0,
(destinationWidth - thirdIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - thirdIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
// The fourth destination is below the third with some spacing. // The fourth destination is below the third with some spacing.
nextDestinationY += destinationHeightWithLabel + destinationSpacing; nextDestinationY += destinationHeightWithLabel + destinationSpacing;
final RenderBox fourthIconRenderBox = _iconRenderBox(tester, Icons.hotel); final RenderBox fourthIconRenderBox = _iconRenderBox(tester, Icons.hotel);
if (!kIsWeb || isSkiaWeb) { expect(
// https://github.com/flutter/flutter/issues/99933 fourthIconRenderBox.localToGlobal(Offset.zero),
expect( equals(
fourthIconRenderBox.localToGlobal(Offset.zero), Offset(
equals( (destinationWidth - fourthIconRenderBox.size.width) / 2.0,
Offset( nextDestinationY + (destinationHeight - fourthIconRenderBox.size.height) / 2.0,
(destinationWidth - fourthIconRenderBox.size.width) / 2.0,
nextDestinationY + (destinationHeight - fourthIconRenderBox.size.height) / 2.0,
),
), ),
); ),
} );
}); });
testWidgets( testWidgets(
@ -3164,7 +3110,7 @@ void main() {
color: const Color(0xffe8def8), color: const Color(0xffe8def8),
), ),
); );
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('NavigationRail indicator renders ripple - extended', (WidgetTester tester) async { testWidgets('NavigationRail indicator renders ripple - extended', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/117126 // This is a regression test for https://github.com/flutter/flutter/issues/117126
@ -3516,7 +3462,7 @@ void main() {
color: const Color(0xffe8def8), color: const Color(0xffe8def8),
), ),
); );
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('NavigationRail indicator renders properly with large icon', ( testWidgets('NavigationRail indicator renders properly with large icon', (
WidgetTester tester, WidgetTester tester,
@ -3626,7 +3572,7 @@ void main() {
color: const Color(0xffe8def8), color: const Color(0xffe8def8),
), ),
); );
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('NavigationRail indicator renders properly when text direction is rtl', ( testWidgets('NavigationRail indicator renders properly when text direction is rtl', (
WidgetTester tester, WidgetTester tester,
@ -3729,7 +3675,7 @@ void main() {
color: const Color(0xffe8def8), color: const Color(0xffe8def8),
), ),
); );
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('NavigationRail indicator scale transform', (WidgetTester tester) async { testWidgets('NavigationRail indicator scale transform', (WidgetTester tester) async {
int selectedIndex = 0; int selectedIndex = 0;
@ -3967,7 +3913,7 @@ void main() {
(RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures', (RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures',
); );
expect(inkFeatures, paints..circle(color: Colors.transparent)); expect(inkFeatures, paints..circle(color: Colors.transparent));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Navigation rail can have expanded widgets inside', (WidgetTester tester) async { testWidgets('Navigation rail can have expanded widgets inside', (WidgetTester tester) async {
await _pumpNavigationRail( await _pumpNavigationRail(
@ -4397,7 +4343,6 @@ void main() {
), ),
); );
}, },
skip: kIsWeb && !isSkiaWeb, // https://github.com/flutter/flutter/issues/99933
); );
testWidgets( testWidgets(
@ -4468,7 +4413,6 @@ void main() {
), ),
); );
}, },
skip: kIsWeb && !isSkiaWeb, // https://github.com/flutter/flutter/issues/99933
); );
testWidgets( testWidgets(
@ -4539,7 +4483,6 @@ void main() {
), ),
); );
}, },
skip: kIsWeb && !isSkiaWeb, // https://github.com/flutter/flutter/issues/99933
); );
testWidgets( testWidgets(

View File

@ -1323,7 +1323,7 @@ void main() {
expect(tester.getSize(find.byType(OutlinedButton)), const Size(134.0, 48.0)); expect(tester.getSize(find.byType(OutlinedButton)), const Size(134.0, 48.0));
expect(tester.getSize(find.byType(Text)), const Size(126.0, 42.0)); expect(tester.getSize(find.byType(Text)), const Size(126.0, 42.0));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/122066 });
testWidgets('OutlinedButton onPressed and onLongPress callbacks are distinctly recognized', ( testWidgets('OutlinedButton onPressed and onLongPress callbacks are distinctly recognized', (
WidgetTester tester, WidgetTester tester,

View File

@ -9,7 +9,6 @@ library;
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -929,7 +928,7 @@ void main() {
// The width of the SegmentedButton must be less than the width of the parent widget. // The width of the SegmentedButton must be less than the width of the parent widget.
expect(segmentedButtonWidth, lessThan(screenWidth)); expect(segmentedButtonWidth, lessThan(screenWidth));
}, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/145527 });
testWidgets('SegmentedButton.styleFrom overlayColor overrides default overlay color', ( testWidgets('SegmentedButton.styleFrom overlayColor overrides default overlay color', (
WidgetTester tester, WidgetTester tester,
@ -1120,7 +1119,7 @@ void main() {
p2: const Offset(166.8000030517578, tapTargetSize - 4.0), p2: const Offset(166.8000030517578, tapTargetSize - 4.0),
), ),
); );
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('SegmentedButton vertical aligned children', (WidgetTester tester) async { testWidgets('SegmentedButton vertical aligned children', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(

View File

@ -3046,11 +3046,7 @@ void main() {
matchesGoldenFile('m3_snack_bar.scaffold.nested.png'), matchesGoldenFile('m3_snack_bar.scaffold.nested.png'),
); );
final Offset snackBarTopRight = tester.getTopRight(find.byType(SnackBar)); final Offset snackBarTopRight = tester.getTopRight(find.byType(SnackBar));
expect(snackBarTopRight.dy, 465.0);
if (!kIsWeb || isSkiaWeb) {
// https://github.com/flutter/flutter/issues/99933
expect(snackBarTopRight.dy, 465.0);
}
}, },
); );

View File

@ -1618,7 +1618,6 @@ void main() {
labelSize = tester.getSize(find.text('Tab 1')); labelSize = tester.getSize(find.text('Tab 1'));
expect(labelSize, equals(const Size(140.5, 40.0))); expect(labelSize, equals(const Size(140.5, 40.0)));
}, },
skip: isBrowser && !isSkiaWeb, // https://github.com/flutter/flutter/issues/87543
); );
testWidgets('TabBarTheme indicatorAnimation can customize tab indicator animation', ( testWidgets('TabBarTheme indicatorAnimation can customize tab indicator animation', (

View File

@ -7539,7 +7539,6 @@ void main() {
labelSize = tester.getSize(find.text('Tab 1')); labelSize = tester.getSize(find.text('Tab 1'));
expect(labelSize, equals(const Size(140.5, 40.0))); expect(labelSize, equals(const Size(140.5, 40.0)));
}, },
skip: isBrowser && !isSkiaWeb, // https://github.com/flutter/flutter/issues/87543
); );
// This is a regression test for https://github.com/flutter/flutter/issues/150000. // This is a regression test for https://github.com/flutter/flutter/issues/150000.

View File

@ -827,7 +827,7 @@ void main() {
expect(tester.getSize(find.byType(TextButton)), const Size(134.0, 48.0)); expect(tester.getSize(find.byType(TextButton)), const Size(134.0, 48.0));
expect(tester.getSize(find.byType(Text)), const Size(126.0, 42.0)); expect(tester.getSize(find.byType(Text)), const Size(126.0, 42.0));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/61016 });
testWidgets('TextButton size is configurable by ThemeData.materialTapTargetSize', ( testWidgets('TextButton size is configurable by ThemeData.materialTapTargetSize', (
WidgetTester tester, WidgetTester tester,

View File

@ -1175,7 +1175,7 @@ void main() {
expect(firstToggleButtonDy, secondToggleButtonDy); expect(firstToggleButtonDy, secondToggleButtonDy);
expect(firstToggleButtonDy, closeTo(elevatedButtonDy - 1.7, 0.1)); expect(firstToggleButtonDy, closeTo(elevatedButtonDy - 1.7, 0.1));
expect(firstToggleButtonDy, closeTo(textDy - 9.7, 0.1)); expect(firstToggleButtonDy, closeTo(textDy - 9.7, 0.1));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Directionality test', (WidgetTester tester) async { testWidgets('Directionality test', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(

View File

@ -202,7 +202,7 @@ void main() {
final RenderBox tip = tester.renderObject(_findTooltipContainer(tooltipText)); final RenderBox tip = tester.renderObject(_findTooltipContainer(tooltipText));
expect(tip.size.height, equals(24.0)); // 14.0 height + 5.0 padding * 2 (top, bottom) expect(tip.size.height, equals(24.0)); // 14.0 height + 5.0 padding * 2 (top, bottom)
expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)), equals(const Offset(10.0, 20.0))); expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)), equals(const Offset(10.0, 20.0)));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Material3 - Does tooltip end up in the right place - top left', ( testWidgets('Material3 - Does tooltip end up in the right place - top left', (
WidgetTester tester, WidgetTester tester,
@ -260,7 +260,7 @@ void main() {
final RenderBox tip = tester.renderObject(_findTooltipContainer(tooltipText)); final RenderBox tip = tester.renderObject(_findTooltipContainer(tooltipText));
expect(tip.size.height, equals(30.0)); // 20.0 height + 5.0 padding * 2 (top, bottom) expect(tip.size.height, equals(30.0)); // 20.0 height + 5.0 padding * 2 (top, bottom)
expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)), equals(const Offset(10.0, 20.0))); expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)), equals(const Offset(10.0, 20.0)));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Does tooltip end up in the right place - center prefer above fits', ( testWidgets('Does tooltip end up in the right place - center prefer above fits', (
WidgetTester tester, WidgetTester tester,
@ -514,51 +514,51 @@ void main() {
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(324.0)); expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(324.0));
}); });
testWidgets( testWidgets('Material3 - Does tooltip end up in the right place - way off to the right', (
'Material3 - Does tooltip end up in the right place - way off to the right', WidgetTester tester,
(WidgetTester tester) async { ) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();
late final OverlayEntry entry; late final OverlayEntry entry;
addTearDown( addTearDown(
() => () =>
entry entry
..remove() ..remove()
..dispose(), ..dispose(),
); );
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Overlay( home: Overlay(
initialEntries: <OverlayEntry>[ initialEntries: <OverlayEntry>[
entry = OverlayEntry( entry = OverlayEntry(
builder: (BuildContext context) { builder: (BuildContext context) {
return Stack( return Stack(
children: <Widget>[ children: <Widget>[
Positioned( Positioned(
left: 1600.0, left: 1600.0,
top: 300.0, top: 300.0,
child: Tooltip( child: Tooltip(
key: tooltipKey, key: tooltipKey,
message: tooltipText, message: tooltipText,
height: 10.0, height: 10.0,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
verticalOffset: 10.0, verticalOffset: 10.0,
preferBelow: true, preferBelow: true,
child: const SizedBox.shrink(), child: const SizedBox.shrink(),
),
), ),
], ),
); ],
}, );
), },
], ),
), ],
), ),
); ),
tooltipKey.currentState?.ensureTooltipVisible(); );
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0) tooltipKey.currentState?.ensureTooltipVisible();
await tester.pump(const Duration(seconds: 2)); // faded in, show timer started (and at 0.0)
/********************* 800x600 screen /********************* 800x600 screen
* * * *
* * * *
* * y=300.0; target --> o * * y=300.0; target --> o
@ -568,14 +568,12 @@ void main() {
* * }-10.0 margin * * }-10.0 margin
*********************/ *********************/
final RenderBox tip = tester.renderObject(_findTooltipContainer(tooltipText)); final RenderBox tip = tester.renderObject(_findTooltipContainer(tooltipText));
expect(tip.size.height, equals(20.0)); expect(tip.size.height, equals(20.0));
expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)).dy, equals(310.0)); expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)).dy, equals(310.0));
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dx, equals(790.0)); expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dx, equals(790.0));
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(330.0)); expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(330.0));
}, });
skip: kIsWeb && !isSkiaWeb, // https://github.com/flutter/flutter/issues/99933
);
testWidgets('Material2 - Does tooltip end up in the right place - near the edge', ( testWidgets('Material2 - Does tooltip end up in the right place - near the edge', (
WidgetTester tester, WidgetTester tester,
@ -698,7 +696,7 @@ void main() {
expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)).dy, equals(310.0)); expect(tip.localToGlobal(tip.size.topLeft(Offset.zero)).dy, equals(310.0));
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dx, equals(790.0)); expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dx, equals(790.0));
expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(330.0)); expect(tip.localToGlobal(tip.size.bottomRight(Offset.zero)).dy, equals(330.0));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Tooltip should be fully visible when MediaQuery.viewInsets > 0', ( testWidgets('Tooltip should be fully visible when MediaQuery.viewInsets > 0', (
WidgetTester tester, WidgetTester tester,
@ -1207,7 +1205,6 @@ void main() {
TargetPlatform.linux, TargetPlatform.linux,
TargetPlatform.windows, TargetPlatform.windows,
}), }),
skip: kIsWeb && !isSkiaWeb, // https://github.com/flutter/flutter/issues/99933
); );
testWidgets('Material2 - Can tooltip decoration be customized', (WidgetTester tester) async { testWidgets('Material2 - Can tooltip decoration be customized', (WidgetTester tester) async {
@ -2167,7 +2164,7 @@ void main() {
expect(tester.getSize(find.text(tooltipText)).height, equals(80.0)); expect(tester.getSize(find.text(tooltipText)).height, equals(80.0));
tip = tester.renderObject(_findTooltipContainer(tooltipText)); tip = tester.renderObject(_findTooltipContainer(tooltipText));
expect(tip.size.height, equals(88.0)); expect(tip.size.height, equals(88.0));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/99933 });
testWidgets('Tooltip text displays with richMessage', (WidgetTester tester) async { testWidgets('Tooltip text displays with richMessage', (WidgetTester tester) async {
final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>(); final GlobalKey<TooltipState> tooltipKey = GlobalKey<TooltipState>();

View File

@ -139,7 +139,7 @@ void runTests() {
}); });
expect(recordedError, isNotNull); expect(recordedError, isNotNull);
expect(imageInfo, isNull); expect(imageInfo, isNull);
}, skip: !isSkiaWeb); });
testWidgets('When strategy is .fallback, emits a WebImageInfo if the image is cross-origin', ( testWidgets('When strategy is .fallback, emits a WebImageInfo if the image is cross-origin', (
WidgetTester tester, WidgetTester tester,
@ -191,7 +191,7 @@ void runTests() {
final WebImageInfo webImageInfo = imageInfo! as WebImageInfo; final WebImageInfo webImageInfo = imageInfo! as WebImageInfo;
expect(webImageInfo.htmlImage.src, equals('https://www.example.com/images/frame5.png')); expect(webImageInfo.htmlImage.src, equals('https://www.example.com/images/frame5.png'));
}, skip: !isSkiaWeb); });
testWidgets( testWidgets(
'When strategy is .fallback, emits an error if the image is cross-origin but fails to decode', 'When strategy is .fallback, emits an error if the image is cross-origin but fails to decode',
@ -241,7 +241,6 @@ void runTests() {
expect(recordedError, isNotNull); expect(recordedError, isNotNull);
expect(imageInfo, isNull); expect(imageInfo, isNull);
}, },
skip: !isSkiaWeb,
); );
testWidgets('When strategy is .prefer, emits an WebImageInfo if the image is same-origin', ( testWidgets('When strategy is .prefer, emits an WebImageInfo if the image is same-origin', (
@ -294,7 +293,7 @@ void runTests() {
final WebImageInfo webImageInfo = imageInfo! as WebImageInfo; final WebImageInfo webImageInfo = imageInfo! as WebImageInfo;
expect(webImageInfo.htmlImage.src, equals('https://www.example.com/images/frame7.png')); expect(webImageInfo.htmlImage.src, equals('https://www.example.com/images/frame7.png'));
}, skip: !isSkiaWeb); });
testWidgets('When strategy is .prefer, emits a normal image if headers is not null', ( testWidgets('When strategy is .prefer, emits a normal image if headers is not null', (
WidgetTester tester, WidgetTester tester,
@ -345,7 +344,7 @@ void runTests() {
expect(recordedError, isNull); expect(recordedError, isNull);
expect(imageInfo, isNotNull); expect(imageInfo, isNotNull);
expect(imageInfo, isNot(isA<WebImageInfo>())); expect(imageInfo, isNot(isA<WebImageInfo>()));
}, skip: !isSkiaWeb); });
testWidgets('Image renders an image using a Platform View if the image info is WebImageInfo', ( testWidgets('Image renders an image using a Platform View if the image info is WebImageInfo', (
WidgetTester tester, WidgetTester tester,
@ -369,7 +368,7 @@ void runTests() {
// After getting a WebImageInfo, the Image uses a Platform View to render. // After getting a WebImageInfo, the Image uses a Platform View to render.
expect(find.byType(RawWebImage), findsOneWidget); expect(find.byType(RawWebImage), findsOneWidget);
expect(find.byType(PlatformViewLink), findsOneWidget); expect(find.byType(PlatformViewLink), findsOneWidget);
}, skip: !isSkiaWeb); });
} }
class _TestImageProvider extends ImageProvider<Object> { class _TestImageProvider extends ImageProvider<Object> {

View File

@ -4,7 +4,6 @@
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -15,7 +14,7 @@ Future<void> main() async {
debugCaptureShaderWarmUpImage = expectAsync1((ui.Image image) => true); debugCaptureShaderWarmUpImage = expectAsync1((ui.Image image) => true);
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
expect(shaderWarmUp.ranWarmUp, true); expect(shaderWarmUp.ranWarmUp, true);
}, skip: kIsWeb && !isSkiaWeb); // [intended] Testing only for canvasKit });
} }
class FakeShaderWarmUp extends ShaderWarmUp { class FakeShaderWarmUp extends ShaderWarmUp {

View File

@ -217,7 +217,7 @@ void main() {
verifyCharacterIsConsideredTrailingSpace('\u{205F}'); verifyCharacterIsConsideredTrailingSpace('\u{205F}');
painter.dispose(); painter.dispose();
}, skip: isBrowser && !isSkiaWeb); // https://github.com/flutter/flutter/issues/56308 });
test('TextPainter caret test with WidgetSpan', () { test('TextPainter caret test with WidgetSpan', () {
// Regression test for https://github.com/flutter/flutter/issues/98458. // Regression test for https://github.com/flutter/flutter/issues/98458.
@ -244,7 +244,7 @@ void main() {
); );
expect(caretOffset.dx, painter.width); expect(caretOffset.dx, painter.width);
painter.dispose(); painter.dispose();
}, skip: isBrowser && !isSkiaWeb); // https://github.com/flutter/flutter/issues/56308 });
test('TextPainter null text test', () { test('TextPainter null text test', () {
final TextPainter painter = TextPainter()..textDirection = TextDirection.ltr; final TextPainter painter = TextPainter()..textDirection = TextDirection.ltr;
@ -346,7 +346,7 @@ void main() {
caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: 23), ui.Rect.zero); caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: 23), ui.Rect.zero);
expect(caretOffset.dx, 126); // end of string expect(caretOffset.dx, 126); // end of string
painter.dispose(); painter.dispose();
}, skip: isBrowser && !isSkiaWeb); // https://github.com/flutter/flutter/issues/56308 });
test('TextPainter caret emoji tests: single, long emoji', () { test('TextPainter caret emoji tests: single, long emoji', () {
// Regression test for https://github.com/flutter/flutter/issues/50563 // Regression test for https://github.com/flutter/flutter/issues/50563
@ -364,24 +364,20 @@ void main() {
// their lengths in code units are powers of 2, namely 4 and 8). // their lengths in code units are powers of 2, namely 4 and 8).
checkCaretOffsetsLtr('🇺🇳'); checkCaretOffsetsLtr('🇺🇳');
checkCaretOffsetsLtr('👩‍❤️‍👨'); checkCaretOffsetsLtr('👩‍❤️‍👨');
}, skip: isBrowser && !isSkiaWeb); // https://github.com/flutter/flutter/issues/56308 });
test( test('TextPainter caret emoji test: letters, then 1 emoji of 5 code units', () {
'TextPainter caret emoji test: letters, then 1 emoji of 5 code units', // Regression test for https://github.com/flutter/flutter/issues/50563
() { checkCaretOffsetsLtr('a👩🚀');
// Regression test for https://github.com/flutter/flutter/issues/50563 checkCaretOffsetsLtr('ab👩🚀');
checkCaretOffsetsLtr('a👩🚀'); checkCaretOffsetsLtr('abc👩🚀');
checkCaretOffsetsLtr('ab👩🚀'); checkCaretOffsetsLtr('abcd👩🚀');
checkCaretOffsetsLtr('abc👩🚀'); });
checkCaretOffsetsLtr('abcd👩🚀');
},
skip: isBrowser && !isSkiaWeb, // https://github.com/flutter/flutter/issues/56308
);
test('TextPainter caret zalgo test', () { test('TextPainter caret zalgo test', () {
// Regression test for https://github.com/flutter/flutter/issues/98516 // Regression test for https://github.com/flutter/flutter/issues/98516
checkCaretOffsetsLtr('Z͉̳̺ͥͬ̾a̴͕̲̒̒͌̋ͪl̨͎̰̘͉̟ͤ̀̈̚͜g͕͔̤͖̟̒͝ͅo̵̡̡̼͚̐ͯ̅ͪ̆ͣ̚'); checkCaretOffsetsLtr('Z͉̳̺ͥͬ̾a̴͕̲̒̒͌̋ͪl̨͎̰̘͉̟ͤ̀̈̚͜g͕͔̤͖̟̒͝ͅo̵̡̡̼͚̐ͯ̅ͪ̆ͣ̚');
}, skip: isBrowser && !isSkiaWeb); // https://github.com/flutter/flutter/issues/56308 });
test('TextPainter caret Devanagari test', () { test('TextPainter caret Devanagari test', () {
// Regression test for https://github.com/flutter/flutter/issues/118403 // Regression test for https://github.com/flutter/flutter/issues/118403
@ -397,82 +393,74 @@ void main() {
'व्रु', 'व्रु',
'ति', 'ति',
]); ]);
}, skip: isBrowser && !isSkiaWeb); // https://github.com/flutter/flutter/issues/56308 });
test('TextPainter caret Devanagari test, full strength', () { test('TextPainter caret Devanagari test, full strength', () {
// Regression test for https://github.com/flutter/flutter/issues/118403 // Regression test for https://github.com/flutter/flutter/issues/118403
checkCaretOffsetsLtr('प्राप्त वर्णन प्रव्रुति'); checkCaretOffsetsLtr('प्राप्त वर्णन प्रव्रुति');
}, skip: true); // https://github.com/flutter/flutter/issues/122478 }, skip: true); // https://github.com/flutter/flutter/issues/122478
test( test('TextPainter caret emoji test LTR: letters next to emoji, as separate TextBoxes', () {
'TextPainter caret emoji test LTR: letters next to emoji, as separate TextBoxes', // Regression test for https://github.com/flutter/flutter/issues/122477
() { // The trigger for this bug was to have SkParagraph report separate
// Regression test for https://github.com/flutter/flutter/issues/122477 // TextBoxes for the emoji and for the characters next to it.
// The trigger for this bug was to have SkParagraph report separate // In normal usage on a real device, this can happen by simply typing
// TextBoxes for the emoji and for the characters next to it. // letters and then an emoji, presumably because they get different fonts.
// In normal usage on a real device, this can happen by simply typing // In these tests, our single test font covers both letters and emoji,
// letters and then an emoji, presumably because they get different fonts. // so we provoke the same effect by adding styles.
// In these tests, our single test font covers both letters and emoji, expect(
// so we provoke the same effect by adding styles. caretOffsetsForTextSpan(
expect( TextDirection.ltr,
caretOffsetsForTextSpan( const TextSpan(
TextDirection.ltr, children: <TextSpan>[
const TextSpan( TextSpan(text: '👩‍🚀', style: TextStyle()),
children: <TextSpan>[ TextSpan(text: ' words', style: TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: '👩‍🚀', style: TextStyle()), ],
TextSpan(text: ' words', style: TextStyle(fontWeight: FontWeight.bold)),
],
),
), ),
<double>[0, 28, 28, 28, 28, 28, 42, 56, 70, 84, 98, 112], ),
); <double>[0, 28, 28, 28, 28, 28, 42, 56, 70, 84, 98, 112],
expect( );
caretOffsetsForTextSpan( expect(
TextDirection.ltr, caretOffsetsForTextSpan(
const TextSpan( TextDirection.ltr,
children: <TextSpan>[ const TextSpan(
TextSpan(text: 'words ', style: TextStyle(fontWeight: FontWeight.bold)), children: <TextSpan>[
TextSpan(text: '👩‍🚀', style: TextStyle()), TextSpan(text: 'words ', style: TextStyle(fontWeight: FontWeight.bold)),
], TextSpan(text: '👩‍🚀', style: TextStyle()),
), ],
), ),
<double>[0, 14, 28, 42, 56, 70, 84, 112, 112, 112, 112, 112], ),
); <double>[0, 14, 28, 42, 56, 70, 84, 112, 112, 112, 112, 112],
}, );
skip: isBrowser && !isSkiaWeb, // https://github.com/flutter/flutter/issues/56308 });
);
test( test('TextPainter caret emoji test RTL: letters next to emoji, as separate TextBoxes', () {
'TextPainter caret emoji test RTL: letters next to emoji, as separate TextBoxes', // Regression test for https://github.com/flutter/flutter/issues/122477
() { expect(
// Regression test for https://github.com/flutter/flutter/issues/122477 caretOffsetsForTextSpan(
expect( TextDirection.rtl,
caretOffsetsForTextSpan( const TextSpan(
TextDirection.rtl, children: <TextSpan>[
const TextSpan( TextSpan(text: '👩‍🚀', style: TextStyle()),
children: <TextSpan>[ TextSpan(text: ' מילים', style: TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: '👩‍🚀', style: TextStyle()), ],
TextSpan(text: ' מילים', style: TextStyle(fontWeight: FontWeight.bold)),
],
),
), ),
<double>[112, 84, 84, 84, 84, 84, 70, 56, 42, 28, 14, 0], ),
); <double>[112, 84, 84, 84, 84, 84, 70, 56, 42, 28, 14, 0],
expect( );
caretOffsetsForTextSpan( expect(
TextDirection.rtl, caretOffsetsForTextSpan(
const TextSpan( TextDirection.rtl,
children: <TextSpan>[ const TextSpan(
TextSpan(text: 'מילים ', style: TextStyle(fontWeight: FontWeight.bold)), children: <TextSpan>[
TextSpan(text: '👩‍🚀', style: TextStyle()), TextSpan(text: 'מילים ', style: TextStyle(fontWeight: FontWeight.bold)),
], TextSpan(text: '👩‍🚀', style: TextStyle()),
), ],
), ),
<double>[112, 98, 84, 70, 56, 42, 28, 0, 0, 0, 0, 0], ),
); <double>[112, 98, 84, 70, 56, 42, 28, 0, 0, 0, 0, 0],
}, );
skip: isBrowser && !isSkiaWeb, // https://github.com/flutter/flutter/issues/56308 });
);
test('TextPainter caret center space test', () { test('TextPainter caret center space test', () {
final TextPainter painter = TextPainter()..textDirection = TextDirection.ltr; final TextPainter painter = TextPainter()..textDirection = TextDirection.ltr;
@ -500,7 +488,7 @@ void main() {
caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: 2), ui.Rect.zero); caretOffset = painter.getOffsetForCaret(const ui.TextPosition(offset: 2), ui.Rect.zero);
expect(caretOffset.dx, 49); expect(caretOffset.dx, 49);
painter.dispose(); painter.dispose();
}, skip: isBrowser && !isSkiaWeb); // https://github.com/flutter/flutter/issues/56308 });
test('TextPainter caret height and line height', () { test('TextPainter caret height and line height', () {
final TextPainter painter = final TextPainter painter =
@ -518,7 +506,7 @@ void main() {
); );
expect(caretHeight, 50.0); expect(caretHeight, 50.0);
painter.dispose(); painter.dispose();
}, skip: isBrowser && !isSkiaWeb); // https://github.com/flutter/flutter/issues/56308 });
test('upstream downstream makes no difference in the same line within the same bidi run', () { test('upstream downstream makes no difference in the same line within the same bidi run', () {
final TextPainter painter = final TextPainter painter =
@ -559,7 +547,7 @@ void main() {
painter.getOffsetForCaret(TextPosition(offset: text.length), largeRect).dx, painter.getOffsetForCaret(TextPosition(offset: text.length), largeRect).dx,
1000 - text.length * fontSize - largeRect.width, 1000 - text.length * fontSize - largeRect.width,
); );
}, skip: isBrowser && !isSkiaWeb); // https://github.com/flutter/flutter/issues/56308 });
test('End of text caret when the text ends with +1 bidi level', () { test('End of text caret when the text ends with +1 bidi level', () {
const double fontSize = 14.0; const double fontSize = 14.0;
@ -577,7 +565,7 @@ void main() {
fontSize * 2 - largeRect.width, fontSize * 2 - largeRect.width,
); );
expect(painter.getOffsetForCaret(const TextPosition(offset: 2), largeRect).dx, fontSize * 2); expect(painter.getOffsetForCaret(const TextPosition(offset: 2), largeRect).dx, fontSize * 2);
}, skip: isBrowser && !isSkiaWeb); // https://github.com/flutter/flutter/issues/56308 });
test('handles newlines properly', () { test('handles newlines properly', () {
final TextPainter painter = TextPainter()..textDirection = TextDirection.ltr; final TextPainter painter = TextPainter()..textDirection = TextDirection.ltr;
@ -1243,7 +1231,7 @@ void main() {
const TextBox.fromLTRBD(351, 30, 401, 60, TextDirection.ltr), const TextBox.fromLTRBD(351, 30, 401, 60, TextDirection.ltr),
); );
painter.dispose(); painter.dispose();
}, skip: isBrowser && !isSkiaWeb); // https://github.com/flutter/flutter/issues/87540 });
// Null values are valid. See https://github.com/flutter/flutter/pull/48346#issuecomment-584839221 // Null values are valid. See https://github.com/flutter/flutter/pull/48346#issuecomment-584839221
test('TextPainter set TextHeightBehavior null test', () { test('TextPainter set TextHeightBehavior null test', () {
@ -1314,7 +1302,7 @@ void main() {
expect(lines[2].lineNumber, 2); expect(lines[2].lineNumber, 2);
expect(lines[3].lineNumber, 3); expect(lines[3].lineNumber, 3);
painter.dispose(); painter.dispose();
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/122066 });
group('TextPainter line-height', () { group('TextPainter line-height', () {
test('half-leading', () { test('half-leading', () {
@ -1453,7 +1441,7 @@ void main() {
expect(glyphBox, newGlyphBox); expect(glyphBox, newGlyphBox);
painter.dispose(); painter.dispose();
}); });
}, skip: isBrowser && !isSkiaWeb); // https://github.com/flutter/flutter/issues/87543 });
test('TextPainter handles invalid UTF-16', () { test('TextPainter handles invalid UTF-16', () {
FlutterErrorDetails? error; FlutterErrorDetails? error;
@ -1488,7 +1476,7 @@ void main() {
); );
expect(caretOffset.dx, painter.width); expect(caretOffset.dx, painter.width);
painter.dispose(); painter.dispose();
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/87545 });
test('TextPainter line metrics update after layout', () { test('TextPainter line metrics update after layout', () {
final TextPainter painter = TextPainter()..textDirection = TextDirection.ltr; final TextPainter painter = TextPainter()..textDirection = TextDirection.ltr;
@ -1506,7 +1494,7 @@ void main() {
lines = painter.computeLineMetrics(); lines = painter.computeLineMetrics();
expect(lines.length, 1); expect(lines.length, 1);
painter.dispose(); painter.dispose();
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/62819 });
test('TextPainter throws with stack trace when accessing text layout', () { test('TextPainter throws with stack trace when accessing text layout', () {
final TextPainter painter = final TextPainter painter =
@ -1546,36 +1534,75 @@ void main() {
painter.dispose(); painter.dispose();
}); });
test( test('TextPainter requires layout after providing different placeholder dimensions', () {
'TextPainter requires layout after providing different placeholder dimensions', final TextPainter painter = TextPainter()..textDirection = TextDirection.ltr;
() {
final TextPainter painter = TextPainter()..textDirection = TextDirection.ltr;
painter.text = const TextSpan( painter.text = const TextSpan(
children: <InlineSpan>[ children: <InlineSpan>[
TextSpan(text: 'before'), TextSpan(text: 'before'),
WidgetSpan(child: Text('widget1')), WidgetSpan(child: Text('widget1')),
WidgetSpan(child: Text('widget2')), WidgetSpan(child: Text('widget2')),
WidgetSpan(child: Text('widget3')), WidgetSpan(child: Text('widget3')),
TextSpan(text: 'after'), TextSpan(text: 'after'),
], ],
); );
painter.setPlaceholderDimensions(const <PlaceholderDimensions>[ painter.setPlaceholderDimensions(const <PlaceholderDimensions>[
PlaceholderDimensions(size: Size(30, 30), alignment: ui.PlaceholderAlignment.bottom), PlaceholderDimensions(size: Size(30, 30), alignment: ui.PlaceholderAlignment.bottom),
PlaceholderDimensions(size: Size(40, 30), alignment: ui.PlaceholderAlignment.bottom), PlaceholderDimensions(size: Size(40, 30), alignment: ui.PlaceholderAlignment.bottom),
PlaceholderDimensions(size: Size(50, 30), alignment: ui.PlaceholderAlignment.bottom), PlaceholderDimensions(size: Size(50, 30), alignment: ui.PlaceholderAlignment.bottom),
]); ]);
painter.layout(); painter.layout();
painter.setPlaceholderDimensions(const <PlaceholderDimensions>[ painter.setPlaceholderDimensions(const <PlaceholderDimensions>[
PlaceholderDimensions(size: Size(30, 30), alignment: ui.PlaceholderAlignment.bottom), PlaceholderDimensions(size: Size(30, 30), alignment: ui.PlaceholderAlignment.bottom),
PlaceholderDimensions(size: Size(40, 20), alignment: ui.PlaceholderAlignment.bottom), PlaceholderDimensions(size: Size(40, 20), alignment: ui.PlaceholderAlignment.bottom),
PlaceholderDimensions(size: Size(50, 30), alignment: ui.PlaceholderAlignment.bottom), PlaceholderDimensions(size: Size(50, 30), alignment: ui.PlaceholderAlignment.bottom),
]); ]);
expect( expect(
() => painter.paint(MockCanvas(), Offset.zero), () => painter.paint(MockCanvas(), Offset.zero),
throwsA(
isA<StateError>().having(
(StateError error) => error.message,
'message',
contains('TextPainter.paint called when text geometry was not yet calculated'),
),
),
);
painter.dispose();
});
test('TextPainter does not require layout after providing identical placeholder dimensions', () {
final TextPainter painter = TextPainter()..textDirection = TextDirection.ltr;
painter.text = const TextSpan(
children: <InlineSpan>[
TextSpan(text: 'before'),
WidgetSpan(child: Text('widget1')),
WidgetSpan(child: Text('widget2')),
WidgetSpan(child: Text('widget3')),
TextSpan(text: 'after'),
],
);
painter.setPlaceholderDimensions(const <PlaceholderDimensions>[
PlaceholderDimensions(size: Size(30, 30), alignment: ui.PlaceholderAlignment.bottom),
PlaceholderDimensions(size: Size(40, 30), alignment: ui.PlaceholderAlignment.bottom),
PlaceholderDimensions(size: Size(50, 30), alignment: ui.PlaceholderAlignment.bottom),
]);
painter.layout();
painter.setPlaceholderDimensions(const <PlaceholderDimensions>[
PlaceholderDimensions(size: Size(30, 30), alignment: ui.PlaceholderAlignment.bottom),
PlaceholderDimensions(size: Size(40, 30), alignment: ui.PlaceholderAlignment.bottom),
PlaceholderDimensions(size: Size(50, 30), alignment: ui.PlaceholderAlignment.bottom),
]);
// In tests, paint() will throw an UnimplementedError due to missing drawParagraph method.
expect(
() => painter.paint(MockCanvas(), Offset.zero),
isNot(
throwsA( throwsA(
isA<StateError>().having( isA<StateError>().having(
(StateError error) => error.message, (StateError error) => error.message,
@ -1583,57 +1610,10 @@ void main() {
contains('TextPainter.paint called when text geometry was not yet calculated'), contains('TextPainter.paint called when text geometry was not yet calculated'),
), ),
), ),
); ),
painter.dispose(); );
}, painter.dispose();
skip: isBrowser && !isSkiaWeb, // https://github.com/flutter/flutter/issues/56308 });
);
test(
'TextPainter does not require layout after providing identical placeholder dimensions',
() {
final TextPainter painter = TextPainter()..textDirection = TextDirection.ltr;
painter.text = const TextSpan(
children: <InlineSpan>[
TextSpan(text: 'before'),
WidgetSpan(child: Text('widget1')),
WidgetSpan(child: Text('widget2')),
WidgetSpan(child: Text('widget3')),
TextSpan(text: 'after'),
],
);
painter.setPlaceholderDimensions(const <PlaceholderDimensions>[
PlaceholderDimensions(size: Size(30, 30), alignment: ui.PlaceholderAlignment.bottom),
PlaceholderDimensions(size: Size(40, 30), alignment: ui.PlaceholderAlignment.bottom),
PlaceholderDimensions(size: Size(50, 30), alignment: ui.PlaceholderAlignment.bottom),
]);
painter.layout();
painter.setPlaceholderDimensions(const <PlaceholderDimensions>[
PlaceholderDimensions(size: Size(30, 30), alignment: ui.PlaceholderAlignment.bottom),
PlaceholderDimensions(size: Size(40, 30), alignment: ui.PlaceholderAlignment.bottom),
PlaceholderDimensions(size: Size(50, 30), alignment: ui.PlaceholderAlignment.bottom),
]);
// In tests, paint() will throw an UnimplementedError due to missing drawParagraph method.
expect(
() => painter.paint(MockCanvas(), Offset.zero),
isNot(
throwsA(
isA<StateError>().having(
(StateError error) => error.message,
'message',
contains('TextPainter.paint called when text geometry was not yet calculated'),
),
),
),
);
painter.dispose();
},
skip: isBrowser && !isSkiaWeb, // https://github.com/flutter/flutter/issues/56308
);
test('TextPainter - debugDisposed', () { test('TextPainter - debugDisposed', () {
final TextPainter painter = TextPainter(); final TextPainter painter = TextPainter();
@ -1870,94 +1850,86 @@ void main() {
case final List<ui.LineMetrics> metrics: case final List<ui.LineMetrics> metrics:
expect(metrics, hasLength(1)); expect(metrics, hasLength(1));
} }
}, skip: kIsWeb && !isSkiaWeb); // [intended] Browsers seem to always round font/glyph metrics. });
group( group('strut style', () {
'strut style', test('strut style applies when the span has no style', () {
() { const StrutStyle strut = StrutStyle(height: 10, fontSize: 10);
test('strut style applies when the span has no style', () { final TextPainter painter = TextPainter(
const StrutStyle strut = StrutStyle(height: 10, fontSize: 10); textDirection: TextDirection.ltr,
final TextPainter painter = TextPainter( text: const TextSpan(),
textDirection: TextDirection.ltr, strutStyle: strut,
text: const TextSpan(), )..layout();
strutStyle: strut, expect(painter.height, 100);
)..layout(); });
expect(painter.height, 100);
});
test('strut style leading is a fontSize multiplier', () { test('strut style leading is a fontSize multiplier', () {
const StrutStyle strut = StrutStyle(height: 10, fontSize: 10, leading: 2); const StrutStyle strut = StrutStyle(height: 10, fontSize: 10, leading: 2);
final TextPainter painter = TextPainter( final TextPainter painter = TextPainter(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
text: const TextSpan(), text: const TextSpan(),
strutStyle: strut, strutStyle: strut,
)..layout(); )..layout();
expect(painter.height, 100 + 20); expect(painter.height, 100 + 20);
// Top leading + scaled ascent. // Top leading + scaled ascent.
expect(painter.computeDistanceToActualBaseline(TextBaseline.alphabetic), 10 + 10 * 7.5); expect(painter.computeDistanceToActualBaseline(TextBaseline.alphabetic), 10 + 10 * 7.5);
}); });
test('strut no half leading + force strut height', () { test('strut no half leading + force strut height', () {
const StrutStyle strut = StrutStyle(height: 10, fontSize: 10, forceStrutHeight: true); const StrutStyle strut = StrutStyle(height: 10, fontSize: 10, forceStrutHeight: true);
final TextPainter painter = TextPainter( final TextPainter painter = TextPainter(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
text: const TextSpan(text: 'A', style: TextStyle(fontSize: 20)), text: const TextSpan(text: 'A', style: TextStyle(fontSize: 20)),
strutStyle: strut, strutStyle: strut,
)..layout(); )..layout();
expect(painter.height, 100); expect(painter.height, 100);
const double baseline = 75; const double baseline = 75;
expect( expect(
painter.getBoxesForSelection(const TextSelection(baseOffset: 0, extentOffset: 1)), painter.getBoxesForSelection(const TextSelection(baseOffset: 0, extentOffset: 1)),
const <ui.TextBox>[ const <ui.TextBox>[
TextBox.fromLTRBD(0, baseline - 15, 20, baseline + 5, TextDirection.ltr), TextBox.fromLTRBD(0, baseline - 15, 20, baseline + 5, TextDirection.ltr),
], ],
); );
}); });
test('strut half leading + force strut height', () { test('strut half leading + force strut height', () {
const StrutStyle strut = StrutStyle( const StrutStyle strut = StrutStyle(
height: 10, height: 10,
fontSize: 10, fontSize: 10,
forceStrutHeight: true, forceStrutHeight: true,
leadingDistribution: TextLeadingDistribution.even, leadingDistribution: TextLeadingDistribution.even,
); );
final TextPainter painter = TextPainter( final TextPainter painter = TextPainter(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
text: const TextSpan(text: 'A', style: TextStyle(fontSize: 20)), text: const TextSpan(text: 'A', style: TextStyle(fontSize: 20)),
strutStyle: strut, strutStyle: strut,
)..layout(); )..layout();
expect(painter.height, 100); expect(painter.height, 100);
const double baseline = 45 + 7.5; const double baseline = 45 + 7.5;
expect( expect(
painter.getBoxesForSelection(const TextSelection(baseOffset: 0, extentOffset: 1)), painter.getBoxesForSelection(const TextSelection(baseOffset: 0, extentOffset: 1)),
const <ui.TextBox>[ const <ui.TextBox>[
TextBox.fromLTRBD(0, baseline - 15, 20, baseline + 5, TextDirection.ltr), TextBox.fromLTRBD(0, baseline - 15, 20, baseline + 5, TextDirection.ltr),
], ],
); );
}); });
test('force strut height applies to widget spans', () { test('force strut height applies to widget spans', () {
const Size placeholderSize = Size(1000, 1000); const Size placeholderSize = Size(1000, 1000);
const StrutStyle strut = StrutStyle(height: 10, fontSize: 10, forceStrutHeight: true); const StrutStyle strut = StrutStyle(height: 10, fontSize: 10, forceStrutHeight: true);
final TextPainter painter = final TextPainter painter =
TextPainter( TextPainter(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
text: const WidgetSpan(child: SizedBox()), text: const WidgetSpan(child: SizedBox()),
strutStyle: strut, strutStyle: strut,
) )
..setPlaceholderDimensions(const <PlaceholderDimensions>[ ..setPlaceholderDimensions(const <PlaceholderDimensions>[
PlaceholderDimensions( PlaceholderDimensions(size: placeholderSize, alignment: PlaceholderAlignment.bottom),
size: placeholderSize, ])
alignment: PlaceholderAlignment.bottom, ..layout();
), expect(painter.height, 100);
]) });
..layout(); });
expect(painter.height, 100);
});
},
// [intended] strut support for HTML renderer https://github.com/flutter/flutter/issues/32243.
skip: kIsWeb && !isSkiaWeb,
);
test('getOffsetForCaret does not crash on decomposed characters', () { test('getOffsetForCaret does not crash on decomposed characters', () {
final TextPainter painter = TextPainter( final TextPainter painter = TextPainter(

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -88,26 +87,21 @@ void main() {
expect(editable.getMaxIntrinsicHeight(double.infinity), 10); expect(editable.getMaxIntrinsicHeight(double.infinity), 10);
}); });
test( test('strutStyle affects intrinsics', () {
'strutStyle affects intrinsics', final RenderEditable editable = RenderEditable(
() { text: const TextSpan(style: TextStyle(fontSize: 10), text: 'Hello World'),
final RenderEditable editable = RenderEditable( textDirection: TextDirection.ltr,
text: const TextSpan(style: TextStyle(fontSize: 10), text: 'Hello World'), startHandleLayerLink: LayerLink(),
textDirection: TextDirection.ltr, endHandleLayerLink: LayerLink(),
startHandleLayerLink: LayerLink(), offset: ViewportOffset.zero(),
endHandleLayerLink: LayerLink(), textSelectionDelegate: delegate,
offset: ViewportOffset.zero(), );
textSelectionDelegate: delegate,
);
expect(editable.getMaxIntrinsicHeight(double.infinity), 10); expect(editable.getMaxIntrinsicHeight(double.infinity), 10);
editable.strutStyle = const StrutStyle(fontSize: 100, forceStrutHeight: true); editable.strutStyle = const StrutStyle(fontSize: 100, forceStrutHeight: true);
expect(editable.getMaxIntrinsicHeight(double.infinity), 100); expect(editable.getMaxIntrinsicHeight(double.infinity), 100);
}, });
// [intended] strut support for HTML renderer https://github.com/flutter/flutter/issues/32243.
skip: kIsWeb && !isSkiaWeb,
);
} }
class _FakeEditableTextState with TextSelectionDelegate { class _FakeEditableTextState with TextSelectionDelegate {

View File

@ -521,51 +521,41 @@ void main() {
}); });
}); });
test( test('ContainerLayer.toImage can render interior layer', () {
'ContainerLayer.toImage can render interior layer', final OffsetLayer parent = OffsetLayer();
() { final OffsetLayer child = OffsetLayer();
final OffsetLayer parent = OffsetLayer(); final OffsetLayer grandChild = OffsetLayer();
final OffsetLayer child = OffsetLayer(); child.append(grandChild);
final OffsetLayer grandChild = OffsetLayer(); parent.append(child);
child.append(grandChild);
parent.append(child);
// This renders the layers and generates engine layers. // This renders the layers and generates engine layers.
parent.buildScene(SceneBuilder()); parent.buildScene(SceneBuilder());
// Causes grandChild to pass its engine layer as `oldLayer` // Causes grandChild to pass its engine layer as `oldLayer`
grandChild.toImage(const Rect.fromLTRB(0, 0, 10, 10)); grandChild.toImage(const Rect.fromLTRB(0, 0, 10, 10));
// Ensure we can render the same scene again after rendering an interior // Ensure we can render the same scene again after rendering an interior
// layer. // layer.
parent.buildScene(SceneBuilder()); parent.buildScene(SceneBuilder());
}, });
// TODO(yjbanov): `toImage` doesn't work in HTML: https://github.com/flutter/flutter/issues/49857
skip: isBrowser && !isSkiaWeb,
);
test( test('ContainerLayer.toImageSync can render interior layer', () {
'ContainerLayer.toImageSync can render interior layer', final OffsetLayer parent = OffsetLayer();
() { final OffsetLayer child = OffsetLayer();
final OffsetLayer parent = OffsetLayer(); final OffsetLayer grandChild = OffsetLayer();
final OffsetLayer child = OffsetLayer(); child.append(grandChild);
final OffsetLayer grandChild = OffsetLayer(); parent.append(child);
child.append(grandChild);
parent.append(child);
// This renders the layers and generates engine layers. // This renders the layers and generates engine layers.
parent.buildScene(SceneBuilder()); parent.buildScene(SceneBuilder());
// Causes grandChild to pass its engine layer as `oldLayer` // Causes grandChild to pass its engine layer as `oldLayer`
grandChild.toImageSync(const Rect.fromLTRB(0, 0, 10, 10)); grandChild.toImageSync(const Rect.fromLTRB(0, 0, 10, 10));
// Ensure we can render the same scene again after rendering an interior // Ensure we can render the same scene again after rendering an interior
// layer. // layer.
parent.buildScene(SceneBuilder()); parent.buildScene(SceneBuilder());
}, });
// TODO(yjbanov): `toImage` doesn't work in HTML: https://github.com/flutter/flutter/issues/49857
skip: isBrowser && !isSkiaWeb,
);
test('PictureLayer does not let you call dispose unless refcount is 0', () { test('PictureLayer does not let you call dispose unless refcount is 0', () {
PictureLayer layer = PictureLayer(Rect.zero); PictureLayer layer = PictureLayer(Rect.zero);

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
@ -85,20 +84,15 @@ void main() {
expect(paragraph.getMaxIntrinsicHeight(double.infinity), 10); expect(paragraph.getMaxIntrinsicHeight(double.infinity), 10);
}); });
test( test('strutStyle affects intrinsics', () {
'strutStyle affects intrinsics', final RenderParagraph paragraph = RenderParagraph(
() { const TextSpan(style: TextStyle(fontSize: 10), text: 'Hello World'),
final RenderParagraph paragraph = RenderParagraph( textDirection: TextDirection.ltr,
const TextSpan(style: TextStyle(fontSize: 10), text: 'Hello World'), );
textDirection: TextDirection.ltr,
);
expect(paragraph.getMaxIntrinsicHeight(double.infinity), 10); expect(paragraph.getMaxIntrinsicHeight(double.infinity), 10);
paragraph.strutStyle = const StrutStyle(fontSize: 100, forceStrutHeight: true); paragraph.strutStyle = const StrutStyle(fontSize: 100, forceStrutHeight: true);
expect(paragraph.getMaxIntrinsicHeight(double.infinity), 100); expect(paragraph.getMaxIntrinsicHeight(double.infinity), 100);
}, });
// [intended] strut support for HTML renderer https://github.com/flutter/flutter/issues/32243.
skip: kIsWeb && !isSkiaWeb,
);
} }

View File

@ -4,7 +4,6 @@
import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle, Paragraph, TextBox; import 'dart:ui' as ui show BoxHeightStyle, BoxWidthStyle, Paragraph, TextBox;
import 'package:flutter/foundation.dart' show isSkiaWeb, kIsWeb;
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
@ -206,7 +205,7 @@ void main() {
expect(boxes[2], const TextBox.fromLTRBD(0.0, 10.0, 130.0, 20.0, TextDirection.ltr)); expect(boxes[2], const TextBox.fromLTRBD(0.0, 10.0, 130.0, 20.0, TextDirection.ltr));
// 'fifth': // 'fifth':
expect(boxes[3], const TextBox.fromLTRBD(0.0, 20.0, 50.0, 30.0, TextDirection.ltr)); expect(boxes[3], const TextBox.fromLTRBD(0.0, 20.0, 50.0, 30.0, TextDirection.ltr));
}, skip: kIsWeb && !isSkiaWeb); // https://github.com/flutter/flutter/issues/61016 });
test('getBoxesForSelection test with boxHeightStyle and boxWidthStyle set to max', () { test('getBoxesForSelection test with boxHeightStyle and boxWidthStyle set to max', () {
final RenderParagraph paragraph = RenderParagraph( final RenderParagraph paragraph = RenderParagraph(

View File

@ -1274,54 +1274,50 @@ void main() {
expect(controller.text, isEmpty); expect(controller.text, isEmpty);
}); });
testWidgets( testWidgets('Caret center space test', (WidgetTester tester) async {
'Caret center space test', EditableText.debugDeterministicCursor = true;
(WidgetTester tester) async { addTearDown(() {
EditableText.debugDeterministicCursor = true; EditableText.debugDeterministicCursor = false;
addTearDown(() { });
EditableText.debugDeterministicCursor = false; final String text = 'test${' ' * 1000}';
}); final TextEditingController controller = TextEditingController.fromValue(
final String text = 'test${' ' * 1000}'; TextEditingValue(
final TextEditingController controller = TextEditingController.fromValue( text: text,
TextEditingValue( selection: TextSelection.collapsed(offset: text.length, affinity: TextAffinity.upstream),
text: text, ),
selection: TextSelection.collapsed(offset: text.length, affinity: TextAffinity.upstream), );
), addTearDown(controller.dispose);
);
addTearDown(controller.dispose);
final Widget widget = EditableText( final Widget widget = EditableText(
autofocus: true, autofocus: true,
backgroundCursorColor: Colors.grey, backgroundCursorColor: Colors.grey,
controller: controller, controller: controller,
focusNode: focusNode, focusNode: focusNode,
style: const TextStyle(fontSize: 17), style: const TextStyle(fontSize: 17),
textAlign: TextAlign.center, textAlign: TextAlign.center,
keyboardType: TextInputType.text, keyboardType: TextInputType.text,
cursorColor: cursorColor, cursorColor: cursorColor,
cursorWidth: 13.0, cursorWidth: 13.0,
cursorHeight: 17.0, cursorHeight: 17.0,
maxLines: null, maxLines: null,
); );
await tester.pumpWidget(MaterialApp(home: widget)); await tester.pumpWidget(MaterialApp(home: widget));
final EditableTextState editableTextState = tester.firstState(find.byWidget(widget)); final EditableTextState editableTextState = tester.firstState(find.byWidget(widget));
final Rect editableTextRect = tester.getRect(find.byWidget(widget)); final Rect editableTextRect = tester.getRect(find.byWidget(widget));
final RenderEditable renderEditable = editableTextState.renderEditable; final RenderEditable renderEditable = editableTextState.renderEditable;
// The trailing whitespaces are not line break opportunities. // The trailing whitespaces are not line break opportunities.
expect(renderEditable.getLineAtOffset(TextPosition(offset: text.length)).start, 0); expect(renderEditable.getLineAtOffset(TextPosition(offset: text.length)).start, 0);
// The caretRect shouldn't be outside of the RenderEditable. // The caretRect shouldn't be outside of the RenderEditable.
final Rect caretRect = Rect.fromLTWH( final Rect caretRect = Rect.fromLTWH(
editableTextRect.right - 13.0 - 1.0, editableTextRect.right - 13.0 - 1.0,
editableTextRect.top, editableTextRect.top,
13.0, 13.0,
17.0, 17.0,
); );
expect(renderEditable, paints..rect(color: cursorColor, rect: caretRect)); expect(renderEditable, paints..rect(color: cursorColor, rect: caretRect));
}, });
skip: isBrowser && !isSkiaWeb, // https://github.com/flutter/flutter/issues/56308
);
testWidgets( testWidgets(
'Caret with a cursorHeight smaller than font size is vertically centered on non-Apple platforms', 'Caret with a cursorHeight smaller than font size is vertically centered on non-Apple platforms',
@ -1364,7 +1360,6 @@ void main() {
variant: TargetPlatformVariant.all( variant: TargetPlatformVariant.all(
excluding: <TargetPlatform>{TargetPlatform.macOS, TargetPlatform.iOS}, excluding: <TargetPlatform>{TargetPlatform.macOS, TargetPlatform.iOS},
), ),
skip: isBrowser && !isCanvasKit, // https://github.com/flutter/flutter/issues/56308
); );
testWidgets( testWidgets(
@ -1408,7 +1403,6 @@ void main() {
variant: TargetPlatformVariant.all( variant: TargetPlatformVariant.all(
excluding: <TargetPlatform>{TargetPlatform.macOS, TargetPlatform.iOS}, excluding: <TargetPlatform>{TargetPlatform.macOS, TargetPlatform.iOS},
), ),
skip: isBrowser && !isCanvasKit, // https://github.com/flutter/flutter/issues/56308
); );
testWidgets('getLocalRectForCaret reports the real caret Rect', (WidgetTester tester) async { testWidgets('getLocalRectForCaret reports the real caret Rect', (WidgetTester tester) async {

View File

@ -227,7 +227,6 @@ class SkiaGoldClient {
'--png-file', '--png-file',
goldenFile.path, goldenFile.path,
'--passfail', '--passfail',
..._getPixelMatchingArguments(),
]; ];
final io.ProcessResult result = await process.run(imgtestCommand); final io.ProcessResult result = await process.run(imgtestCommand);
@ -365,7 +364,6 @@ class SkiaGoldClient {
cleanTestName(testName), cleanTestName(testName),
'--png-file', '--png-file',
goldenFile.path, goldenFile.path,
..._getPixelMatchingArguments(),
]; ];
final io.ProcessResult result = await process.run(imgtestCommand); final io.ProcessResult result = await process.run(imgtestCommand);
@ -395,54 +393,6 @@ class SkiaGoldClient {
return result.exitCode == 0 ? null : resultStdout; return result.exitCode == 0 ? null : resultStdout;
} }
// Constructs arguments for `goldctl` for controlling how pixels are compared.
//
// For AOT and CanvasKit exact pixel matching is used. For the HTML renderer
// on the web a fuzzy matching algorithm is used that allows very small deltas
// because Chromium cannot exactly reproduce the same golden on all computers.
// It seems to depend on the hardware/OS/driver combination. However, those
// differences are very small (typically not noticeable to human eye).
List<String> _getPixelMatchingArguments() {
// Only use fuzzy pixel matching in the HTML renderer.
if (!_isBrowserTest || _isBrowserSkiaTest) {
return const <String>[];
}
// The algorithm to be used when matching images. The available options are:
// - "fuzzy": Allows for customizing the thresholds of pixel differences.
// - "sobel": Same as "fuzzy" but performs edge detection before performing
// a fuzzy match.
const String algorithm = 'fuzzy';
// The number of pixels in this image that are allowed to differ from the
// baseline.
//
// The chosen number - 20 - is arbitrary. Even for a small golden file, say
// 50 x 50, it would be less than 1% of the total number of pixels. This
// number should not grow too much. If it's growing, it is probably due to a
// larger issue that needs to be addressed at the infra level.
const int maxDifferentPixels = 20;
// The maximum acceptable difference per pixel.
//
// Uses the Manhattan distance using the RGBA color components as
// coordinates. The chosen number - 4 - is arbitrary. It's small enough to
// both not be noticeable and not trigger test flakes due to sub-pixel
// golden deltas. This number should not grow too much. If it's growing, it
// is probably due to a larger issue that needs to be addressed at the infra
// level.
const int pixelDeltaThreshold = 4;
return <String>[
'--add-test-optional-key',
'image_matching_algorithm:$algorithm',
'--add-test-optional-key',
'fuzzy_max_different_pixels:$maxDifferentPixels',
'--add-test-optional-key',
'fuzzy_pixel_delta_threshold:$pixelDeltaThreshold',
];
}
/// Returns the latest positive digest for the given test known to Flutter /// Returns the latest positive digest for the given test known to Flutter
/// Gold at head. /// Gold at head.
Future<String?> getExpectationForTest(String testName) async { Future<String?> getExpectationForTest(String testName) async {

View File

@ -96,56 +96,6 @@ const List<int> _kTestPngBytes = <int>[
void main() { void main() {
group('SkiaGoldClient', () { group('SkiaGoldClient', () {
test('web HTML test', () async {
final MemoryFileSystem fs = MemoryFileSystem();
final FakePlatform platform = FakePlatform(
environment: <String, String>{
'GOLDCTL': 'goldctl',
'FLUTTER_ROOT': _kFlutterRoot,
'FLUTTER_TEST_BROWSER': 'Chrome',
'FLUTTER_WEB_RENDERER': 'html',
},
operatingSystem: 'macos',
);
final FakeProcessManager process = FakeProcessManager();
final FakeHttpClient fakeHttpClient = FakeHttpClient();
fs.directory(_kFlutterRoot).createSync(recursive: true);
final Directory workDirectory = fs.directory('/workDirectory')..createSync(recursive: true);
final SkiaGoldClient skiaClient = SkiaGoldClient(
workDirectory,
fs: fs,
process: process,
platform: platform,
httpClient: fakeHttpClient,
log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
);
final File goldenFile = fs.file('/workDirectory/temp/golden_file_test.png')
..createSync(recursive: true);
const RunInvocation goldctlInvocation = RunInvocation(<String>[
'goldctl',
'imgtest',
'add',
'--work-dir',
'/workDirectory/temp',
'--test-name',
'golden_file_test',
'--png-file',
'/workDirectory/temp/golden_file_test.png',
'--passfail',
'--add-test-optional-key',
'image_matching_algorithm:fuzzy',
'--add-test-optional-key',
'fuzzy_max_different_pixels:20',
'--add-test-optional-key',
'fuzzy_pixel_delta_threshold:4',
], null);
process.processResults[goldctlInvocation] = ProcessResult(123, 0, '', '');
expect(await skiaClient.imgtestAdd('golden_file_test.png', goldenFile), isTrue);
});
test('web CanvasKit test', () async { test('web CanvasKit test', () async {
final MemoryFileSystem fs = MemoryFileSystem(); final MemoryFileSystem fs = MemoryFileSystem();
final FakePlatform platform = FakePlatform( final FakePlatform platform = FakePlatform(

View File

@ -7,7 +7,6 @@ import 'dart:js_interop';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'dart:ui_web' as ui_web; import 'dart:ui_web' as ui_web;
import 'package:flutter/foundation.dart' show isSkiaWeb;
import 'package:stream_channel/stream_channel.dart'; import 'package:stream_channel/stream_channel.dart';
import 'package:test_api/backend.dart'; import 'package:test_api/backend.dart';
@ -43,13 +42,7 @@ Future<void> runWebTest(WebTest test) async {
await ui_web.bootstrapEngine(runApp: () => completer.complete()); await ui_web.bootstrapEngine(runApp: () => completer.complete());
await completer.future; await completer.future;
// TODO(matanlurey): Remove webGoldenComparator when dart:html is deprecated. goldenFileComparator = HttpProxyGoldenComparator(test.goldensUri);
// See https://github.com/flutter/flutter/issues/145954.
if (isSkiaWeb) {
goldenFileComparator = HttpProxyGoldenComparator(test.goldensUri);
} else {
webGoldenComparator = DefaultWebGoldenComparator(test.goldensUri);
}
/// This hard-codes the device pixel ratio to 3.0 and a 2400 x 1800 window /// This hard-codes the device pixel ratio to 3.0 and a 2400 x 1800 window
/// size for the purposes of testing. /// size for the purposes of testing.

View File

@ -478,9 +478,9 @@ void main() {
// Tests whether using a deprecated webRenderer toggles a warningText. // Tests whether using a deprecated webRenderer toggles a warningText.
Future<void> testWebRendererDeprecationMessage(WebRendererMode webRenderer) async { Future<void> testWebRendererDeprecationMessage(WebRendererMode webRenderer) async {
testUsingContext( testUsingContext(
'Using --web-renderer=${webRenderer.name} triggers a warningText.', 'Using the "${webRenderer.name}" renderer triggers a warningText.',
() async { () async {
// Run the command so it parses --web-renderer, but ignore all errors. // Run the command so it parses the renderer, but ignore all errors.
// We only care about the logger. // We only care about the logger.
try { try {
final TestWebBuildCommand buildCommand = TestWebBuildCommand(fileSystem: fileSystem); final TestWebBuildCommand buildCommand = TestWebBuildCommand(fileSystem: fileSystem);

View File

@ -1130,9 +1130,9 @@ void main() {
// Tests whether using a deprecated webRenderer toggles a warningText. // Tests whether using a deprecated webRenderer toggles a warningText.
Future<void> testWebRendererDeprecationMessage(WebRendererMode webRenderer) async { Future<void> testWebRendererDeprecationMessage(WebRendererMode webRenderer) async {
testUsingContext( testUsingContext(
'Using --web-renderer=${webRenderer.name} triggers a warningText.', 'Using the "${webRenderer.name}" renderer triggers a warningText.',
() async { () async {
// Run the command so it parses --web-renderer, but ignore all errors. // Run the command so it parses the renderer, but ignore all errors.
// We only care about the logger. // We only care about the logger.
try { try {
await createTestCommandRunner( await createTestCommandRunner(

View File

@ -1528,9 +1528,9 @@ dev_dependencies:
// Tests whether using a deprecated webRenderer toggles a warningText. // Tests whether using a deprecated webRenderer toggles a warningText.
Future<void> testWebRendererDeprecationMessage(WebRendererMode webRenderer) async { Future<void> testWebRendererDeprecationMessage(WebRendererMode webRenderer) async {
testUsingContext( testUsingContext(
'Using --web-renderer=${webRenderer.name} triggers a warningText.', 'Using the "${webRenderer.name}" renderer triggers a warningText.',
() async { () async {
// Run the command so it parses --web-renderer, but ignore all errors. // Run the command so it parses the renderer, but ignore all errors.
// We only care about the logger. // We only care about the logger.
try { try {
final FakeFlutterTestRunner testRunner = FakeFlutterTestRunner(0); final FakeFlutterTestRunner testRunner = FakeFlutterTestRunner(0);

View File

@ -8,7 +8,6 @@ library;
import 'dart:async'; import 'dart:async';
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:flutter_tools/src/web/compile.dart';
import '../integration.shard/test_data/hot_reload_project.dart'; import '../integration.shard/test_data/hot_reload_project.dart';
import '../integration.shard/test_driver.dart'; import '../integration.shard/test_driver.dart';
@ -74,30 +73,6 @@ Future<void> _testProject(HotReloadProject project, {String name = 'Default'}) a
await flutter.hotRestart(); await flutter.hotRestart();
}); });
testWithoutContext(
'$testName: newly added code executes during hot restart - html (legacy)',
() async {
final Completer<void> completer = Completer<void>();
final StreamSubscription<String> subscription = flutter.stdout.listen((String line) {
printOnFailure(line);
if (line.contains('(((((RELOAD WORKED)))))')) {
completer.complete();
}
});
await flutter.run(
chrome: true,
additionalCommandArgs: <String>['--verbose', ...WebRendererMode.html.toCliDartDefines],
);
project.uncommentHotReloadPrint();
try {
await flutter.hotRestart();
await completer.future.timeout(const Duration(seconds: 15));
} finally {
await subscription.cancel();
}
},
);
testWithoutContext( testWithoutContext(
'$testName: newly added code executes during hot restart - canvaskit', '$testName: newly added code executes during hot restart - canvaskit',
() async { () async {