// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'package:flutter/cupertino.dart'; import 'package:flutter_test/flutter_test.dart'; import '../painting/mocks_for_image_cache.dart'; /// Integration tests testing both [CupertinoPageScaffold] and [CupertinoTabScaffold]. void main() { testWidgets('Contents are behind translucent bar', (WidgetTester tester) async { await tester.pumpWidget( new WidgetsApp( color: const Color(0xFFFFFFFF), onGenerateRoute: (RouteSettings settings) { return new CupertinoPageRoute<void>( settings: settings, builder: (BuildContext context) { return const CupertinoPageScaffold( // Default nav bar is translucent. navigationBar: const CupertinoNavigationBar( middle: const Text('Title'), ), child: const Center(), ); }, ); }, ), ); expect(tester.getTopLeft(find.byType(Center)), const Offset(0.0, 0.0)); }); testWidgets('Contents are between opaque bars', (WidgetTester tester) async { const Center page1Center = const Center(); await tester.pumpWidget( new WidgetsApp( color: const Color(0xFFFFFFFF), onGenerateRoute: (RouteSettings settings) { return new CupertinoPageRoute<void>( settings: settings, builder: (BuildContext context) { return new CupertinoTabScaffold( tabBar: new CupertinoTabBar( backgroundColor: CupertinoColors.white, items: const <BottomNavigationBarItem>[ const BottomNavigationBarItem( icon: const ImageIcon(const TestImageProvider(24, 24)), title: const Text('Tab 1'), ), const BottomNavigationBarItem( icon: const ImageIcon(const TestImageProvider(24, 24)), title: const Text('Tab 2'), ), ], ), tabBuilder: (BuildContext context, int index) { return index == 0 ? const CupertinoPageScaffold( navigationBar: const CupertinoNavigationBar( backgroundColor: CupertinoColors.white, middle: const Text('Title'), ), child: page1Center, ) : new Stack(); } ); }, ); }, ), ); expect(tester.getSize(find.byWidget(page1Center)).height, 600.0 - 44.0 - 50.0); }); testWidgets('Contents have automatic sliver padding between translucent bars', (WidgetTester tester) async { final Container content = new Container(height: 600.0, width: 600.0); await tester.pumpWidget( new WidgetsApp( color: const Color(0xFFFFFFFF), onGenerateRoute: (RouteSettings settings) { return new CupertinoPageRoute<void>( settings: settings, builder: (BuildContext context) { return new MediaQuery( data: const MediaQueryData( padding: const EdgeInsets.symmetric(vertical: 20.0), ), child: new CupertinoTabScaffold( tabBar: new CupertinoTabBar( items: const <BottomNavigationBarItem>[ const BottomNavigationBarItem( icon: const ImageIcon(const TestImageProvider(24, 24)), title: const Text('Tab 1'), ), const BottomNavigationBarItem( icon: const ImageIcon(const TestImageProvider(24, 24)), title: const Text('Tab 2'), ), ], ), tabBuilder: (BuildContext context, int index) { return index == 0 ? new CupertinoPageScaffold( navigationBar: const CupertinoNavigationBar( middle: const Text('Title'), ), child: new ListView( children: <Widget>[ content, ], ), ) : new Stack(); } ), ); }, ); }, ), ); // List content automatically padded by nav bar and top media query padding. expect(tester.getTopLeft(find.byWidget(content)).dy, 20.0 + 44.0); // Overscroll to the bottom. await tester.drag(find.byWidget(content), const Offset(0.0, -400.0)); await tester.pump(const Duration(seconds: 1)); // List content automatically padded by tab bar and bottom media query padding. expect(tester.getBottomLeft(find.byWidget(content)).dy, 600 - 20.0 - 50.0); }); testWidgets('iOS independent tab navigation', (WidgetTester tester) async { // A full on iOS information architecture app with 2 tabs, and 2 pages // in each with independent navigation states. await tester.pumpWidget( new WidgetsApp( color: const Color(0xFFFFFFFF), onGenerateRoute: (RouteSettings settings) { return new CupertinoPageRoute<void>( settings: settings, builder: (BuildContext context) { return new CupertinoTabScaffold( tabBar: new CupertinoTabBar( items: const <BottomNavigationBarItem>[ const BottomNavigationBarItem( icon: const ImageIcon(const TestImageProvider(24, 24)), title: const Text('Tab 1'), ), const BottomNavigationBarItem( icon: const ImageIcon(const TestImageProvider(24, 24)), title: const Text('Tab 2'), ), ], ), tabBuilder: (BuildContext context, int index) { // For 1-indexed readability. ++index; return new CupertinoTabView( builder: (BuildContext context) { return new CupertinoPageScaffold( navigationBar: new CupertinoNavigationBar( middle: new Text('Page 1 of tab $index'), ), child: new Center( child: new CupertinoButton( child: const Text('Next'), onPressed: () { Navigator.of(context).push( new CupertinoPageRoute<void>( builder: (BuildContext context) { return new CupertinoPageScaffold( navigationBar: new CupertinoNavigationBar( middle: new Text('Page 2 of tab $index'), ), child: new Center( child: new CupertinoButton( child: const Text('Back'), onPressed: () { Navigator.of(context).pop(); }, ), ), ); }, ), ); }, ), ), ); }, ); }, ); }, ); }, ), ); expect(find.text('Page 1 of tab 1'), findsOneWidget); expect(find.text('Page 1 of tab 2'), findsNothing); // Lazy building so not built yet. await tester.tap(find.text('Tab 2')); await tester.pump(); expect(find.text('Page 1 of tab 1'), findsNothing); // It's offstage now. expect(find.text('Page 1 of tab 1', skipOffstage: false), findsOneWidget); expect(find.text('Page 1 of tab 2'), findsOneWidget); // Navigate in tab 2. await tester.tap(find.text('Next')); await tester.pump(); await tester.pump(const Duration(milliseconds: 300)); expect(find.text('Page 2 of tab 2'), isOnstage); expect(find.text('Page 1 of tab 1', skipOffstage: false), isOffstage); await tester.tap(find.text('Tab 1')); await tester.pump(); // Independent navigation stacks. expect(find.text('Page 1 of tab 1'), isOnstage); expect(find.text('Page 2 of tab 2', skipOffstage: false), isOffstage); // Navigate in tab 1. await tester.tap(find.text('Next')); await tester.pump(); await tester.pump(const Duration(milliseconds: 300)); expect(find.text('Page 2 of tab 1'), isOnstage); expect(find.text('Page 2 of tab 2', skipOffstage: false), isOffstage); await tester.tap(find.text('Tab 2')); await tester.pump(); expect(find.text('Page 2 of tab 2'), isOnstage); expect(find.text('Page 2 of tab 1', skipOffstage: false), isOffstage); // Pop in tab 2 await tester.tap(find.text('Back')); await tester.pump(); await tester.pump(const Duration(milliseconds: 300)); expect(find.text('Page 1 of tab 2'), isOnstage); expect(find.text('Page 2 of tab 1', skipOffstage: false), isOffstage); }); testWidgets('Decorated with white background by default', (WidgetTester tester) async { await tester.pumpWidget( new WidgetsApp( color: const Color(0xFFFFFFFF), onGenerateRoute: (RouteSettings settings) { return new CupertinoPageRoute<void>( settings: settings, builder: (BuildContext context) { return const CupertinoPageScaffold( child: const Center(), ); }, ); }, ), ); final DecoratedBox decoratedBox = tester.widgetList(find.byType(DecoratedBox)).elementAt(1); expect(decoratedBox.decoration.runtimeType, BoxDecoration); final BoxDecoration decoration = decoratedBox.decoration; expect(decoration.color, CupertinoColors.white); }); testWidgets('Overrides background color', (WidgetTester tester) async { await tester.pumpWidget( new WidgetsApp( color: const Color(0xFFFFFFFF), onGenerateRoute: (RouteSettings settings) { return new CupertinoPageRoute<void>( settings: settings, builder: (BuildContext context) { return const CupertinoPageScaffold( child: const Center(), backgroundColor: const Color(0xFF010203), ); }, ); }, ), ); final DecoratedBox decoratedBox = tester.widgetList(find.byType(DecoratedBox)).elementAt(1); expect(decoratedBox.decoration.runtimeType, BoxDecoration); final BoxDecoration decoration = decoratedBox.decoration; expect(decoration.color, const Color(0xFF010203)); }); }