Unverified Commit 3dbe90e1 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Add TargetPlatform.macOS tests to the material library (#48996)

This contains the test changes for adding TargetPlatform.macOS, which was done in #43457.

The main goal of this PR is to enable tests in the material library that are currently running only on iOS to also run on macOS, but only for the tests where that makes sense. For instance, we don't run any of the haptic feedback tests on macOS.
parent e8222aaf
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
......@@ -83,66 +84,68 @@ void main() {
Size size = tester.getSize(title);
expect(center.dx, lessThan(400 - size.width / 2.0));
// Clear the widget tree to avoid animating between Android and iOS.
await tester.pumpWidget(Container(key: UniqueKey()));
for (final TargetPlatform platform in <TargetPlatform>[TargetPlatform.iOS, TargetPlatform.macOS]) {
// Clear the widget tree to avoid animating between platforms.
await tester.pumpWidget(Container(key: UniqueKey()));
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: TargetPlatform.iOS),
home: Scaffold(
appBar: AppBar(
title: const Text('X'),
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: platform),
home: Scaffold(
appBar: AppBar(
title: const Text('X'),
),
),
),
),
);
);
center = tester.getCenter(title);
size = tester.getSize(title);
expect(center.dx, greaterThan(400 - size.width / 2.0));
expect(center.dx, lessThan(400 + size.width / 2.0));
center = tester.getCenter(title);
size = tester.getSize(title);
expect(center.dx, greaterThan(400 - size.width / 2.0), reason: 'on ${describeEnum(platform)}');
expect(center.dx, lessThan(400 + size.width / 2.0), reason: 'on ${describeEnum(platform)}');
// One action is still centered.
// One action is still centered.
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: TargetPlatform.iOS),
home: Scaffold(
appBar: AppBar(
title: const Text('X'),
actions: const <Widget>[
Icon(Icons.thumb_up),
],
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: platform),
home: Scaffold(
appBar: AppBar(
title: const Text('X'),
actions: const <Widget>[
Icon(Icons.thumb_up),
],
),
),
),
),
);
);
center = tester.getCenter(title);
size = tester.getSize(title);
expect(center.dx, greaterThan(400 - size.width / 2.0));
expect(center.dx, lessThan(400 + size.width / 2.0));
center = tester.getCenter(title);
size = tester.getSize(title);
expect(center.dx, greaterThan(400 - size.width / 2.0), reason: 'on ${describeEnum(platform)}');
expect(center.dx, lessThan(400 + size.width / 2.0), reason: 'on ${describeEnum(platform)}');
// Two actions is left aligned again.
// Two actions is left aligned again.
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: TargetPlatform.iOS),
home: Scaffold(
appBar: AppBar(
title: const Text('X'),
actions: const <Widget>[
Icon(Icons.thumb_up),
Icon(Icons.thumb_up),
],
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: platform),
home: Scaffold(
appBar: AppBar(
title: const Text('X'),
actions: const <Widget>[
Icon(Icons.thumb_up),
Icon(Icons.thumb_up),
],
),
),
),
),
);
);
center = tester.getCenter(title);
size = tester.getSize(title);
expect(center.dx, lessThan(400 - size.width / 2.0));
center = tester.getCenter(title);
size = tester.getSize(title);
expect(center.dx, lessThan(400 - size.width / 2.0), reason: 'on ${describeEnum(platform)}');
}
});
testWidgets('AppBar centerTitle:true centers on Android', (WidgetTester tester) async {
......
......@@ -66,30 +66,37 @@ void main() {
});
testWidgets('BackButton icon', (WidgetTester tester) async {
final Key iOSKey = UniqueKey();
final Key androidKey = UniqueKey();
final Key iOSKey = UniqueKey();
final Key macOSKey = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: Column(
children: <Widget>[
Theme(
data: ThemeData(platform: TargetPlatform.android),
child: BackButtonIcon(key: androidKey),
),
Theme(
data: ThemeData(platform: TargetPlatform.iOS),
child: BackButtonIcon(key: iOSKey),
),
Theme(
data: ThemeData(platform: TargetPlatform.android),
child: BackButtonIcon(key: androidKey),
data: ThemeData(platform: TargetPlatform.macOS),
child: BackButtonIcon(key: macOSKey),
),
],
),
),
);
final Icon iOSIcon = tester.widget(find.descendant(of: find.byKey(iOSKey), matching: find.byType(Icon)));
final Icon androidIcon = tester.widget(find.descendant(of: find.byKey(androidKey), matching: find.byType(Icon)));
expect(iOSIcon == androidIcon, false);
final Icon iOSIcon = tester.widget(find.descendant(of: find.byKey(iOSKey), matching: find.byType(Icon)));
final Icon macOSIcon = tester.widget(find.descendant(of: find.byKey(macOSKey), matching: find.byType(Icon)));
expect(iOSIcon.icon == androidIcon.icon, isFalse);
expect(macOSIcon.icon == androidIcon.icon, isFalse);
expect(macOSIcon.icon == iOSIcon.icon, isTrue);
});
testWidgets('BackButton semantics', (WidgetTester tester) async {
......
......@@ -57,9 +57,8 @@ void main() {
expect(find.text('header'), findsOneWidget);
});
testWidgets('Drawer dismiss barrier has label on iOS', (WidgetTester tester) async {
testWidgets('Drawer dismiss barrier has label', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
await tester.pumpWidget(
const MaterialApp(
home: Scaffold(
......@@ -80,10 +79,9 @@ void main() {
));
semantics.dispose();
debugDefaultTargetPlatformOverride = null;
});
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('Drawer dismiss barrier has no label on Android', (WidgetTester tester) async {
testWidgets('Drawer dismiss barrier has no label', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(
const MaterialApp(
......@@ -105,7 +103,7 @@ void main() {
)));
semantics.dispose();
});
}, variant: TargetPlatformVariant.only(TargetPlatform.android));
testWidgets('Scaffold drawerScrimColor', (WidgetTester tester) async {
// The scrim is a Container within a Semantics node labeled "Dismiss",
......
......@@ -58,7 +58,6 @@ void main() {
await tester.pumpWidget(MaterialApp(
theme: ThemeData(
platform: TargetPlatform.iOS,
dividerColor: _dividerColor,
),
home: Material(
......@@ -154,7 +153,7 @@ void main() {
expect(collapsedContainerDecoration.color, Colors.transparent);
expect(collapsedContainerDecoration.border.top.color, _dividerColor);
expect(collapsedContainerDecoration.border.bottom.color, _dividerColor);
});
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('ListTileTheme', (WidgetTester tester) async {
final Key expandedTitleKey = UniqueKey();
......@@ -165,7 +164,6 @@ void main() {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
platform: TargetPlatform.iOS,
accentColor: _accentColor,
unselectedWidgetColor: _unselectedWidgetColor,
textTheme: const TextTheme(subhead: TextStyle(color: _headerColor)),
......@@ -214,7 +212,7 @@ void main() {
expect(textColor(collapsedTitleKey), _accentColor);
expect(iconColor(expandedIconKey), _unselectedWidgetColor);
expect(iconColor(collapsedIconKey), _accentColor);
});
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('ExpansionTile subtitle', (WidgetTester tester) async {
await tester.pumpWidget(
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
......@@ -10,10 +11,10 @@ const double expandedAppbarHeight = 250.0;
final Key appbarContainerKey = UniqueKey();
void main() {
testWidgets('FlexibleSpaceBar collapse mode none on Android', (WidgetTester tester) async {
testWidgets('FlexibleSpaceBar collapse mode none', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: TargetPlatform.android),
theme: ThemeData(platform: debugDefaultTargetPlatformOverride),
home: Scaffold(
body: CustomScrollView(
key: blockKey,
......@@ -46,88 +47,12 @@ void main() {
expect(topBeforeScroll.dy, equals(0.0));
expect(topAfterScroll.dy, equals(0.0));
});
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('FlexibleSpaceBar collapse mode none on IOS', (WidgetTester tester) async {
testWidgets('FlexibleSpaceBar collapse mode pin', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: TargetPlatform.iOS),
home: Scaffold(
body: CustomScrollView(
key: blockKey,
slivers: <Widget>[
SliverAppBar(
expandedHeight: expandedAppbarHeight,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
background: Container(
key: appbarContainerKey,
),
collapseMode: CollapseMode.none,
),
),
SliverToBoxAdapter(
child: Container(
height: 10000.0,
),
),
],
),
),
),
);
final Finder appbarContainer = find.byKey(appbarContainerKey);
final Offset topBeforeScroll = tester.getTopLeft(appbarContainer);
await slowDrag(tester, blockKey, const Offset(0.0, -100.0));
final Offset topAfterScroll = tester.getTopLeft(appbarContainer);
expect(topBeforeScroll.dy, equals(0.0));
expect(topAfterScroll.dy, equals(0.0));
});
testWidgets('FlexibleSpaceBar collapse mode pin on Android', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: TargetPlatform.android),
home: Scaffold(
body: CustomScrollView(
key: blockKey,
slivers: <Widget>[
SliverAppBar(
expandedHeight: expandedAppbarHeight,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
background: Container(
key: appbarContainerKey,
),
collapseMode: CollapseMode.pin,
),
),
SliverToBoxAdapter(
child: Container(
height: 10000.0,
),
),
],
),
),
),
);
final Finder appbarContainer = find.byKey(appbarContainerKey);
final Offset topBeforeScroll = tester.getTopLeft(appbarContainer);
await slowDrag(tester, blockKey, const Offset(0.0, -100.0));
final Offset topAfterScroll = tester.getTopLeft(appbarContainer);
expect(topBeforeScroll.dy, equals(0.0));
expect(topAfterScroll.dy, equals(-100.0));
});
testWidgets('FlexibleSpaceBar collapse mode pin on IOS', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: TargetPlatform.iOS),
theme: ThemeData(platform: debugDefaultTargetPlatformOverride),
home: Scaffold(
body: CustomScrollView(
key: blockKey,
......@@ -160,53 +85,12 @@ void main() {
expect(topBeforeScroll.dy, equals(0.0));
expect(topAfterScroll.dy, equals(-100.0));
});
testWidgets('FlexibleSpaceBar collapse mode parallax on Android', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: TargetPlatform.android),
home: Scaffold(
body: CustomScrollView(
key: blockKey,
slivers: <Widget>[
SliverAppBar(
expandedHeight: expandedAppbarHeight,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
background: Container(
key: appbarContainerKey,
),
collapseMode: CollapseMode.parallax,
),
),
SliverToBoxAdapter(
child: Container(
height: 10000.0,
),
),
],
),
),
),
);
final Finder appbarContainer = find.byKey(appbarContainerKey);
final Offset topBeforeScroll = tester.getTopLeft(appbarContainer);
await slowDrag(tester, blockKey, const Offset(0.0, -100.0));
final Offset topAfterScroll = tester.getTopLeft(appbarContainer);
expect(topBeforeScroll.dy, equals(0.0));
expect(topAfterScroll.dy, lessThan(10.0));
expect(topAfterScroll.dy, greaterThan(-50.0));
});
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('FlexibleSpaceBar collapse mode parallax on IOS', (WidgetTester tester) async {
testWidgets('FlexibleSpaceBar collapse mode parallax', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: TargetPlatform.iOS),
theme: ThemeData(platform: debugDefaultTargetPlatformOverride),
home: Scaffold(
body: CustomScrollView(
key: blockKey,
......@@ -240,7 +124,7 @@ void main() {
expect(topBeforeScroll.dy, equals(0.0));
expect(topAfterScroll.dy, lessThan(10.0));
expect(topAfterScroll.dy, greaterThan(-50.0));
});
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.iOS, TargetPlatform.macOS }));
}
Future<void> slowDrag(WidgetTester tester, Key widget, Offset offset) async {
......
......@@ -25,26 +25,28 @@ void main() {
Size size = tester.getSize(title);
expect(center.dx, lessThan(400.0 - size.width / 2.0));
// Clear the widget tree to avoid animating between Android and iOS.
await tester.pumpWidget(Container(key: UniqueKey()));
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: TargetPlatform.iOS),
home: Scaffold(
appBar: AppBar(
flexibleSpace: const FlexibleSpaceBar(
title: Text('X'),
for (final TargetPlatform platform in <TargetPlatform>[ TargetPlatform.iOS, TargetPlatform.macOS ]) {
// Clear the widget tree to avoid animating between platforms.
await tester.pumpWidget(Container(key: UniqueKey()));
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: platform),
home: Scaffold(
appBar: AppBar(
flexibleSpace: const FlexibleSpaceBar(
title: Text('X'),
),
),
),
),
),
);
);
center = tester.getCenter(title);
size = tester.getSize(title);
expect(center.dx, greaterThan(400.0 - size.width / 2.0));
expect(center.dx, lessThan(400.0 + size.width / 2.0));
center = tester.getCenter(title);
size = tester.getSize(title);
expect(center.dx, greaterThan(400.0 - size.width / 2.0));
expect(center.dx, lessThan(400.0 + size.width / 2.0));
}
});
testWidgets('FlexibleSpaceBarSettings provides settings to a FlexibleSpaceBar', (WidgetTester tester) async {
......@@ -154,6 +156,15 @@ void main() {
await tester.pumpWidget(buildFrame(TargetPlatform.iOS, false));
expect(getTitleBottomLeft(), const Offset(72.0, 16.0));
// Clear the widget tree to avoid animating between iOS and macOS.
await tester.pumpWidget(Container(key: UniqueKey()));
await tester.pumpWidget(buildFrame(TargetPlatform.macOS, null));
expect(getTitleBottomLeft(), const Offset(390.0, 16.0));
await tester.pumpWidget(buildFrame(TargetPlatform.macOS, false));
expect(getTitleBottomLeft(), const Offset(72.0, 16.0));
}, skip: isBrowser);
testWidgets('FlexibleSpaceBar test titlePadding override', (WidgetTester tester) async {
......@@ -195,6 +206,15 @@ void main() {
await tester.pumpWidget(buildFrame(TargetPlatform.iOS, false));
expect(getTitleBottomLeft(), Offset.zero);
// Clear the widget tree to avoid animating between iOS and macOS.
await tester.pumpWidget(Container(key: UniqueKey()));
await tester.pumpWidget(buildFrame(TargetPlatform.macOS, null));
expect(getTitleBottomLeft(), const Offset(390.0, 0.0));
await tester.pumpWidget(buildFrame(TargetPlatform.macOS, false));
expect(getTitleBottomLeft(), Offset.zero);
}, skip: isBrowser);
}
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
......@@ -11,11 +12,16 @@ void main() {
await tester.pumpWidget(const MaterialApp(home: Text('home')));
final PageTransitionsTheme theme = Theme.of(tester.element(find.text('home'))).pageTransitionsTheme;
expect(theme.builders, isNotNull);
expect(theme.builders[TargetPlatform.android], isNotNull);
expect(theme.builders[TargetPlatform.iOS], isNotNull);
for (final TargetPlatform platform in TargetPlatform.values) {
if (platform == TargetPlatform.fuchsia) {
// No builder on Fuchsia.
continue;
}
expect(theme.builders[platform], isNotNull, reason: 'theme builder for $platform is null');
}
});
testWidgets('Default PageTranstionsTheme builds a CupertionPageTransition for iOS', (WidgetTester tester) async {
testWidgets('Default PageTranstionsTheme builds a CupertionPageTransition', (WidgetTester tester) async {
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
'/': (BuildContext context) => Material(
child: FlatButton(
......@@ -28,19 +34,18 @@ void main() {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: TargetPlatform.iOS),
routes: routes,
),
);
expect(Theme.of(tester.element(find.text('push'))).platform, TargetPlatform.iOS);
expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
expect(find.byType(CupertinoPageTransition), findsOneWidget);
await tester.tap(find.text('push'));
await tester.pumpAndSettle();
expect(find.text('page b'), findsOneWidget);
expect(find.byType(CupertinoPageTransition), findsOneWidget);
});
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('Default PageTranstionsTheme builds a _FadeUpwardsPageTransition for android', (WidgetTester tester) async {
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
......@@ -55,7 +60,6 @@ void main() {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: TargetPlatform.android),
routes: routes,
),
);
......@@ -67,16 +71,16 @@ void main() {
);
}
expect(Theme.of(tester.element(find.text('push'))).platform, TargetPlatform.android);
expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
expect(findFadeUpwardsPageTransition(), findsOneWidget);
await tester.tap(find.text('push'));
await tester.pumpAndSettle();
expect(find.text('page b'), findsOneWidget);
expect(findFadeUpwardsPageTransition(), findsOneWidget);
});
}, variant: TargetPlatformVariant.only(TargetPlatform.android));
testWidgets('pageTranstionsTheme override builds a _OpenUpwardsPageTransition for android', (WidgetTester tester) async {
testWidgets('pageTranstionsTheme override builds a _OpenUpwardsPageTransition', (WidgetTester tester) async {
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
'/': (BuildContext context) => Material(
child: FlatButton(
......@@ -90,7 +94,6 @@ void main() {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
platform: TargetPlatform.android,
pageTransitionsTheme: const PageTransitionsTheme(
builders: <TargetPlatform, PageTransitionsBuilder>{
TargetPlatform.android: OpenUpwardsPageTransitionsBuilder(), // creates a _OpenUpwardsPageTransition
......@@ -108,16 +111,16 @@ void main() {
);
}
expect(Theme.of(tester.element(find.text('push'))).platform, TargetPlatform.android);
expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
expect(findOpenUpwardsPageTransition(), findsOneWidget);
await tester.tap(find.text('push'));
await tester.pumpAndSettle();
expect(find.text('page b'), findsOneWidget);
expect(findOpenUpwardsPageTransition(), findsOneWidget);
});
}, variant: TargetPlatformVariant.only(TargetPlatform.android));
testWidgets('pageTranstionsTheme override builds a _ZoomPageTransition for android', (WidgetTester tester) async {
testWidgets('pageTranstionsTheme override builds a _ZoomPageTransition', (WidgetTester tester) async {
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
'/': (BuildContext context) => Material(
child: FlatButton(
......@@ -131,7 +134,6 @@ void main() {
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
platform: TargetPlatform.android,
pageTransitionsTheme: const PageTransitionsTheme(
builders: <TargetPlatform, PageTransitionsBuilder>{
TargetPlatform.android: ZoomPageTransitionsBuilder(), // creates a _ZoomPageTransition
......@@ -149,12 +151,12 @@ void main() {
);
}
expect(Theme.of(tester.element(find.text('push'))).platform, TargetPlatform.android);
expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
expect(findZoomPageTransition(), findsOneWidget);
await tester.tap(find.text('push'));
await tester.pumpAndSettle();
expect(find.text('page b'), findsOneWidget);
expect(findZoomPageTransition(), findsOneWidget);
});
}, variant: TargetPlatformVariant.only(TargetPlatform.android));
}
......@@ -325,6 +325,12 @@ void main() {
expect(find.byIcon(Icons.more_vert), findsNothing);
expect(find.byIcon(Icons.more_horiz), findsOneWidget);
await tester.pumpWidget(build(TargetPlatform.macOS));
await tester.pumpAndSettle(); // Run theme change animation.
expect(find.byIcon(Icons.more_vert), findsNothing);
expect(find.byIcon(Icons.more_horiz), findsOneWidget);
});
group('PopupMenuButton with Icon', () {
......
......@@ -387,8 +387,7 @@ void main() {
expect(tester.takeException(), isFlutterError);
});
testWidgets('Refresh starts while scroll view moves back to 0.0 after overscroll on iOS', (WidgetTester tester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
testWidgets('Refresh starts while scroll view moves back to 0.0 after overscroll', (WidgetTester tester) async {
refreshCalled = false;
double lastScrollOffset;
final ScrollController controller = ScrollController();
......@@ -420,7 +419,5 @@ void main() {
expect(controller.offset, greaterThan(lastScrollOffset));
expect(controller.offset, lessThan(0.0));
expect(refreshCalled, isTrue);
debugDefaultTargetPlatformOverride = null;
});
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
}
......@@ -320,17 +320,17 @@ void main() {
);
}
testWidgets('Tapping the status bar scrolls to top on iOS', (WidgetTester tester) async {
await tester.pumpWidget(_buildStatusBarTestApp(TargetPlatform.iOS));
testWidgets('Tapping the status bar scrolls to top', (WidgetTester tester) async {
await tester.pumpWidget(_buildStatusBarTestApp(debugDefaultTargetPlatformOverride));
final ScrollableState scrollable = tester.state(find.byType(Scrollable));
scrollable.position.jumpTo(500.0);
expect(scrollable.position.pixels, equals(500.0));
await tester.tapAt(const Offset(100.0, 10.0));
await tester.pumpAndSettle();
expect(scrollable.position.pixels, equals(0.0));
});
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('Tapping the status bar does not scroll to top on Android', (WidgetTester tester) async {
testWidgets('Tapping the status bar does not scroll to top', (WidgetTester tester) async {
await tester.pumpWidget(_buildStatusBarTestApp(TargetPlatform.android));
final ScrollableState scrollable = tester.state(find.byType(Scrollable));
scrollable.position.jumpTo(500.0);
......@@ -339,7 +339,7 @@ void main() {
await tester.pump();
await tester.pump(const Duration(seconds: 1));
expect(scrollable.position.pixels, equals(500.0));
});
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android }));
testWidgets('Bottom sheet cannot overlap app bar', (WidgetTester tester) async {
final Key sheetKey = UniqueKey();
......@@ -506,7 +506,7 @@ void main() {
});
group('back arrow', () {
Future<void> expectBackIcon(WidgetTester tester, TargetPlatform platform, IconData expectedIcon) async {
Future<void> expectBackIcon(WidgetTester tester, IconData expectedIcon) async {
final GlobalKey rootKey = GlobalKey();
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
'/': (_) => Container(key: rootKey, child: const Text('Home')),
......@@ -515,9 +515,7 @@ void main() {
body: const Text('Scaffold'),
),
};
await tester.pumpWidget(
MaterialApp(theme: ThemeData(platform: platform), routes: routes)
);
await tester.pumpWidget(MaterialApp(routes: routes));
Navigator.pushNamed(rootKey.currentContext, '/scaffold');
await tester.pump();
......@@ -527,24 +525,20 @@ void main() {
expect(icon.icon, expectedIcon);
}
testWidgets('Back arrow uses correct default on Android', (WidgetTester tester) async {
await expectBackIcon(tester, TargetPlatform.android, Icons.arrow_back);
});
testWidgets('Back arrow uses correct default on Fuchsia', (WidgetTester tester) async {
await expectBackIcon(tester, TargetPlatform.fuchsia, Icons.arrow_back);
});
testWidgets('Back arrow uses correct default', (WidgetTester tester) async {
await expectBackIcon(tester, Icons.arrow_back);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.fuchsia }));
testWidgets('Back arrow uses correct default on iOS', (WidgetTester tester) async {
await expectBackIcon(tester, TargetPlatform.iOS, Icons.arrow_back_ios);
});
testWidgets('Back arrow uses correct default', (WidgetTester tester) async {
await expectBackIcon(tester, Icons.arrow_back_ios);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
});
group('close button', () {
Future<void> expectCloseIcon(WidgetTester tester, TargetPlatform platform, IconData expectedIcon, PageRoute<void> routeBuilder()) async {
Future<void> expectCloseIcon(WidgetTester tester, PageRoute<void> routeBuilder(), String type) async {
const IconData expectedIcon = Icons.close;
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(platform: platform),
home: Scaffold(appBar: AppBar(), body: const Text('Page 1')),
),
);
......@@ -555,8 +549,8 @@ void main() {
await tester.pump(const Duration(seconds: 1));
final Icon icon = tester.widget(find.byType(Icon));
expect(icon.icon, expectedIcon);
expect(find.byType(CloseButton), findsOneWidget);
expect(icon.icon, expectedIcon, reason: "didn't find close icon for $type");
expect(find.byType(CloseButton), findsOneWidget, reason: "didn't find close button for $type");
}
PageRoute<void> materialRouteBuilder() {
......@@ -586,41 +580,17 @@ void main() {
);
}
testWidgets('Close button shows correctly on Android', (WidgetTester tester) async {
await expectCloseIcon(tester, TargetPlatform.android, Icons.close, materialRouteBuilder);
});
testWidgets('Close button shows correctly on Fuchsia', (WidgetTester tester) async {
await expectCloseIcon(tester, TargetPlatform.fuchsia, Icons.close, materialRouteBuilder);
});
testWidgets('Close button shows correctly on iOS', (WidgetTester tester) async {
await expectCloseIcon(tester, TargetPlatform.iOS, Icons.close, materialRouteBuilder);
});
testWidgets('Close button shows correctly with PageRouteBuilder on Android', (WidgetTester tester) async {
await expectCloseIcon(tester, TargetPlatform.android, Icons.close, pageRouteBuilder);
});
testWidgets('Close button shows correctly with PageRouteBuilder on Fuchsia', (WidgetTester tester) async {
await expectCloseIcon(tester, TargetPlatform.fuchsia, Icons.close, pageRouteBuilder);
});
testWidgets('Close button shows correctly with PageRouteBuilder on iOS', (WidgetTester tester) async {
await expectCloseIcon(tester, TargetPlatform.iOS, Icons.close, pageRouteBuilder);
});
testWidgets('Close button shows correctly with custom page route on Android', (WidgetTester tester) async {
await expectCloseIcon(tester, TargetPlatform.android, Icons.close, customPageRouteBuilder);
});
testWidgets('Close button shows correctly', (WidgetTester tester) async {
await expectCloseIcon(tester, materialRouteBuilder, 'materialRouteBuilder');
}, variant: TargetPlatformVariant.all());
testWidgets('Close button shows correctly with custom page route on Fuchsia', (WidgetTester tester) async {
await expectCloseIcon(tester, TargetPlatform.fuchsia, Icons.close, customPageRouteBuilder);
});
testWidgets('Close button shows correctly with PageRouteBuilder', (WidgetTester tester) async {
await expectCloseIcon(tester, pageRouteBuilder, 'pageRouteBuilder');
}, variant: TargetPlatformVariant.all());
testWidgets('Close button shows correctly with custom page route on iOS', (WidgetTester tester) async {
await expectCloseIcon(tester, TargetPlatform.iOS, Icons.close, customPageRouteBuilder);
});
testWidgets('Close button shows correctly with custom page route', (WidgetTester tester) async {
await expectCloseIcon(tester, customPageRouteBuilder, 'customPageRouteBuilder');
}, variant: TargetPlatformVariant.all());
});
group('body size', () {
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_test/flutter_test.dart';
......@@ -152,6 +153,20 @@ void main() {
await tester.drag(find.byType(SingleChildScrollView), const Offset(0.0, -10.0));
await tester.pump();
await tester.pump(const Duration(milliseconds: 200));
expect(find.byType(Scrollbar), paints..rrect());
expect(find.byType(CupertinoScrollbar), paints..rrect());
await gesture.up();
await tester.pumpAndSettle();
await tester.pumpWidget(viewWithScroll(TargetPlatform.macOS));
await gesture.down(
tester.getCenter(find.byType(SingleChildScrollView)),
);
await gesture.moveBy(const Offset(0.0, -10.0));
await tester.drag(find.byType(SingleChildScrollView), const Offset(0.0, -10.0));
await tester.pump();
await tester.pump(const Duration(milliseconds: 200));
expect(find.byType(Scrollbar), paints..rrect());
expect(find.byType(CupertinoScrollbar), paints..rrect());
});
......@@ -173,7 +188,7 @@ void main() {
);
}
await tester.pumpWidget(viewWithScroll(TargetPlatform.iOS));
await tester.pumpWidget(viewWithScroll(debugDefaultTargetPlatformOverride));
final TestGesture gesture = await tester.startGesture(
tester.getCenter(find.byType(SingleChildScrollView))
);
......@@ -184,6 +199,6 @@ void main() {
expect(find.byType(CupertinoScrollbar), paints..rrect());
final CupertinoScrollbar scrollbar = find.byType(CupertinoScrollbar).evaluate().first.widget as CupertinoScrollbar;
expect(scrollbar.controller, isNotNull);
});
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
}
......@@ -573,7 +573,8 @@ void main() {
SemanticsFlag.isTextField,
SemanticsFlag.isFocused,
SemanticsFlag.isHeader,
if (debugDefaultTargetPlatformOverride != TargetPlatform.iOS) SemanticsFlag.namesRoute,
if (debugDefaultTargetPlatformOverride != TargetPlatform.iOS &&
debugDefaultTargetPlatformOverride != TargetPlatform.macOS) SemanticsFlag.namesRoute,
],
actions: <SemanticsAction>[
SemanticsAction.tap,
......@@ -622,8 +623,7 @@ void main() {
semantics.dispose();
});
testWidgets('does not include routeName on iOS', (WidgetTester tester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
testWidgets('does not include routeName', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
final _TestSearchDelegate delegate = _TestSearchDelegate();
await tester.pumpWidget(TestHomePage(
......@@ -636,9 +636,8 @@ void main() {
expect(semantics, hasSemantics(buildExpected(routeName: ''),
ignoreId: true, ignoreRect: true, ignoreTransform: true));
debugDefaultTargetPlatformOverride = null;
semantics.dispose();
});
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
});
}
......
......@@ -1250,16 +1250,14 @@ void main() {
));
semantics.dispose();
});
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.fuchsia }));
testWidgets('Slider Semantics - iOS', (WidgetTester tester) async {
testWidgets('Slider Semantics', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(
Theme(
data: ThemeData.light().copyWith(
platform: TargetPlatform.iOS,
),
data: ThemeData.light(),
child: Directionality(
textDirection: TextDirection.ltr,
child: MediaQuery(
......@@ -1294,7 +1292,7 @@ void main() {
ignoreTransform: true,
));
semantics.dispose();
});
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('Slider semantics with custom formatter', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
......@@ -1485,27 +1483,34 @@ void main() {
);
}
await tester.pumpWidget(buildFrame(TargetPlatform.iOS));
expect(find.byType(Slider), findsOneWidget);
expect(find.byType(CupertinoSlider), findsOneWidget);
expect(value, 0.5);
TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(CupertinoSlider)));
// Drag to the right end of the track.
await gesture.moveBy(const Offset(600.0, 0.0));
expect(value, 1.0);
value = 0.5;
await tester.pumpWidget(buildFrame(TargetPlatform.android));
await tester.pumpAndSettle(); // Finish the theme change animation.
expect(find.byType(Slider), findsOneWidget);
expect(find.byType(CupertinoSlider), findsNothing);
expect(value, 0.5);
gesture = await tester.startGesture(tester.getCenter(find.byType(Slider)));
// Drag to the right end of the track.
await gesture.moveBy(const Offset(600.0, 0.0));
expect(value, 1.0);
for (final TargetPlatform platform in <TargetPlatform>[TargetPlatform.iOS, TargetPlatform.macOS]) {
value = 0.5;
await tester.pumpWidget(buildFrame(platform));
expect(find.byType(Slider), findsOneWidget);
expect(find.byType(CupertinoSlider), findsOneWidget);
expect(value, 0.5, reason: 'on ${describeEnum(platform)}');
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(CupertinoSlider)));
// Drag to the right end of the track.
await gesture.moveBy(const Offset(600.0, 0.0));
expect(value, 1.0, reason: 'on ${describeEnum(platform)}');
await gesture.up();
}
for (final TargetPlatform platform in <TargetPlatform>[TargetPlatform.android, TargetPlatform.fuchsia]) {
value = 0.5;
await tester.pumpWidget(buildFrame(platform));
await tester.pumpAndSettle(); // Finish the theme change animation.
expect(find.byType(Slider), findsOneWidget);
expect(find.byType(CupertinoSlider), findsNothing);
expect(value, 0.5, reason: 'on ${describeEnum(platform)}');
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(Slider)));
// Drag to the right end of the track.
await gesture.moveBy(const Offset(600.0, 0.0));
expect(value, 1.0, reason: 'on ${describeEnum(platform)}');
await gesture.up();
}
});
testWidgets('Slider respects height from theme', (WidgetTester tester) async {
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import '../rendering/mock_canvas.dart';
......@@ -85,20 +86,26 @@ void main() {
);
}
await tester.pumpWidget(buildFrame(TargetPlatform.iOS));
expect(find.byType(CupertinoSwitch), findsOneWidget);
expect(value, isFalse);
for (final TargetPlatform platform in <TargetPlatform>[ TargetPlatform.iOS, TargetPlatform.macOS ]) {
value = false;
await tester.pumpWidget(buildFrame(platform));
expect(find.byType(CupertinoSwitch), findsOneWidget);
expect(value, isFalse, reason: 'on ${describeEnum(platform)}');
await tester.tap(find.byType(SwitchListTile));
expect(value, isTrue);
await tester.tap(find.byType(SwitchListTile));
expect(value, isTrue, reason: 'on ${describeEnum(platform)}');
}
await tester.pumpWidget(buildFrame(TargetPlatform.android));
await tester.pumpAndSettle(); // Finish the theme change animation.
for (final TargetPlatform platform in <TargetPlatform>[ TargetPlatform.android, TargetPlatform.fuchsia ]) {
value = false;
await tester.pumpWidget(buildFrame(platform));
await tester.pumpAndSettle(); // Finish the theme change animation.
expect(find.byType(CupertinoSwitch), findsNothing);
expect(value, isTrue);
await tester.tap(find.byType(SwitchListTile));
expect(value, isFalse);
expect(find.byType(CupertinoSwitch), findsNothing);
expect(value, isFalse, reason: 'on ${describeEnum(platform)}');
await tester.tap(find.byType(SwitchListTile));
expect(value, isTrue, reason: 'on ${describeEnum(platform)}');
}
});
testWidgets('SwitchListTile contentPadding', (WidgetTester tester) async {
......
......@@ -610,23 +610,28 @@ void main() {
);
}
await tester.pumpWidget(buildFrame(TargetPlatform.iOS));
expect(find.byType(CupertinoSwitch), findsOneWidget);
for (final TargetPlatform platform in <TargetPlatform>[ TargetPlatform.iOS, TargetPlatform.macOS ]) {
value = false;
await tester.pumpWidget(buildFrame(platform));
expect(find.byType(CupertinoSwitch), findsOneWidget, reason: 'on ${describeEnum(platform)}');
final CupertinoSwitch adaptiveSwitch = tester.widget(find.byType(CupertinoSwitch));
expect(adaptiveSwitch.trackColor, inactiveTrackColor);
final CupertinoSwitch adaptiveSwitch = tester.widget(find.byType(CupertinoSwitch));
expect(adaptiveSwitch.trackColor, inactiveTrackColor, reason: 'on ${describeEnum(platform)}');
expect(value, isFalse);
await tester.tap(find.byType(Switch));
expect(value, isTrue);
await tester.pumpWidget(buildFrame(TargetPlatform.android));
await tester.pumpAndSettle(); // Finish the theme change animation.
expect(find.byType(CupertinoSwitch), findsNothing);
expect(value, isTrue);
await tester.tap(find.byType(Switch));
expect(value, isFalse);
expect(value, isFalse, reason: 'on ${describeEnum(platform)}');
await tester.tap(find.byType(Switch));
expect(value, isTrue, reason: 'on ${describeEnum(platform)}');
}
for (final TargetPlatform platform in <TargetPlatform>[ TargetPlatform.android, TargetPlatform.fuchsia ]) {
value = false;
await tester.pumpWidget(buildFrame(platform));
await tester.pumpAndSettle(); // Finish the theme change animation.
expect(find.byType(CupertinoSwitch), findsNothing);
expect(value, isFalse, reason: 'on ${describeEnum(platform)}');
await tester.tap(find.byType(Switch));
expect(value, isTrue, reason: 'on ${describeEnum(platform)}');
}
});
testWidgets('Switch is focusable and has correct focus color', (WidgetTester tester) async {
......
......@@ -196,6 +196,7 @@ void main() {
const PageTransitionsTheme pageTransitionTheme = PageTransitionsTheme(
builders: <TargetPlatform, PageTransitionsBuilder>{
TargetPlatform.iOS: CupertinoPageTransitionsBuilder(),
TargetPlatform.macOS: CupertinoPageTransitionsBuilder(),
},
);
......
......@@ -21,16 +21,16 @@ void main() {
expect(Typography(platform: TargetPlatform.fuchsia).black.title.fontFamily, 'Roboto');
});
test('Typography on iOS defaults to the correct SF font family based on size', () {
// Ref: https://developer.apple.com/ios/human-interface-guidelines/visual-design/typography/
final Matcher isDisplayFont = predicate((TextStyle s) {
return s.fontFamily == '.SF UI Display';
}, 'Uses SF Display font');
// Ref: https://developer.apple.com/ios/human-interface-guidelines/visual-design/typography/
final Matcher isDisplayFont = predicate((TextStyle s) {
return s.fontFamily == '.SF UI Display';
}, 'Uses SF Display font');
final Matcher isTextFont = predicate((TextStyle s) {
return s.fontFamily == '.SF UI Text';
}, 'Uses SF Text font');
final Matcher isTextFont = predicate((TextStyle s) {
return s.fontFamily == '.SF UI Text';
}, 'Uses SF Text font');
test('Typography on iOS defaults to the correct SF font family based on size', () {
final Typography typography = Typography(platform: TargetPlatform.iOS);
for (final TextTheme textTheme in <TextTheme>[typography.black, typography.white]) {
expect(textTheme.display4, isDisplayFont);
......@@ -49,6 +49,25 @@ void main() {
}
});
test('Typography on macOS defaults to the correct SF font family based on size', () {
final Typography typography = Typography(platform: TargetPlatform.macOS);
for (final TextTheme textTheme in <TextTheme>[typography.black, typography.white]) {
expect(textTheme.display4, isDisplayFont);
expect(textTheme.display3, isDisplayFont);
expect(textTheme.display2, isDisplayFont);
expect(textTheme.display1, isDisplayFont);
expect(textTheme.headline, isDisplayFont);
expect(textTheme.title, isDisplayFont);
expect(textTheme.subhead, isTextFont);
expect(textTheme.body2, isTextFont);
expect(textTheme.body1, isTextFont);
expect(textTheme.caption, isTextFont);
expect(textTheme.button, isTextFont);
expect(textTheme.subtitle, isTextFont);
expect(textTheme.overline, isTextFont);
}
});
testWidgets('Typography implements debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
Typography(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment