fix: ui tests

This commit is contained in:
DenserMeerkat
2024-07-23 16:02:46 +05:30
parent 3265269c25
commit dace495264
19 changed files with 108 additions and 69 deletions

View File

@ -71,6 +71,10 @@ final kCodeStyle = TextStyle(
fontFamilyFallback: kFontFamilyFallback,
);
final kHomeScaffoldKey = GlobalKey<ScaffoldState>();
final kEnvScaffoldKey = GlobalKey<ScaffoldState>();
final kHisScaffoldKey = GlobalKey<ScaffoldState>();
const kHintOpacity = 0.6;
const kForegroundOpacity = 0.05;
const kOverlayBackgroundOpacity = 0.5;
@ -82,7 +86,7 @@ const kFormDataButtonLabelTextStyle = TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
);
const kTextStylePopupMenuItem = TextStyle(fontSize: 16);
const kTextStylePopupMenuItem = TextStyle(fontSize: 14);
final kButtonSidebarStyle = ElevatedButton.styleFrom(padding: kPh12);

View File

@ -2,8 +2,8 @@ import 'package:apidash/consts.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final mobileScaffoldKeyStateProvider = StateProvider<GlobalKey<ScaffoldState>>(
(ref) => GlobalKey<ScaffoldState>());
final mobileScaffoldKeyStateProvider =
StateProvider<GlobalKey<ScaffoldState>>((ref) => kHomeScaffoldKey);
final leftDrawerStateProvider = StateProvider<bool>((ref) => false);
final navRailIndexStateProvider = StateProvider<int>((ref) => 0);
final selectedIdEditStateProvider = StateProvider<String?>((ref) => null);

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/utils/utils.dart';
class NavbarButton extends ConsumerWidget {
const NavbarButton({
@ -25,19 +26,20 @@ class NavbarButton extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final mobileScaffoldKey = ref.watch(mobileScaffoldKeyStateProvider);
final mobileScaffoldKeyNotifier =
ref.watch(mobileScaffoldKeyStateProvider.notifier);
final bool isSelected = railIdx == buttonIdx;
final Size size = isCompact ? const Size(56, 32) : const Size(65, 32);
var onPress = isSelected
? null
: () {
if (buttonIdx != null) {
ref.read(navRailIndexStateProvider.notifier).state = buttonIdx!;
final scaffoldKey = getScaffoldKey(buttonIdx!);
ref.watch(navRailIndexStateProvider.notifier).state = buttonIdx!;
mobileScaffoldKeyNotifier.state = scaffoldKey;
if ((railIdx > 2 && buttonIdx! <= 2) ||
!(ref
.read(mobileScaffoldKeyStateProvider)
.currentState
?.isDrawerOpen ??
true)) {
!(mobileScaffoldKey.currentState?.isDrawerOpen ?? true)) {
ref.read(leftDrawerStateProvider.notifier).state = false;
}
}

View File

@ -1,4 +1,3 @@
import 'package:apidash/screens/history/history_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:apidash/providers/providers.dart';
@ -7,6 +6,7 @@ import 'package:apidash/consts.dart';
import 'common_widgets/common_widgets.dart';
import 'envvar/environment_page.dart';
import 'home_page/home_page.dart';
import 'history/history_page.dart';
import 'settings_page.dart';
class Dashboard extends ConsumerWidget {
@ -15,7 +15,6 @@ class Dashboard extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final railIdx = ref.watch(navRailIndexStateProvider);
final mobileScaffoldKey = ref.watch(mobileScaffoldKeyStateProvider);
return Scaffold(
body: SafeArea(
child: Row(
@ -61,7 +60,7 @@ class Dashboard extends ConsumerWidget {
ref.read(navRailIndexStateProvider.notifier).state = 2;
},
icon: const Icon(Icons.history_outlined),
selectedIcon: const Icon(Icons.history),
selectedIcon: const Icon(Icons.history_rounded),
),
Text(
'History',
@ -113,15 +112,11 @@ class Dashboard extends ConsumerWidget {
child: IndexedStack(
alignment: AlignmentDirectional.topCenter,
index: railIdx,
children: [
const HomePage(),
EnvironmentPage(
scaffoldKey: mobileScaffoldKey,
),
HistoryPage(
scaffoldKey: mobileScaffoldKey,
),
const SettingsPage(),
children: const [
HomePage(),
EnvironmentPage(),
HistoryPage(),
SettingsPage(),
],
),
)

View File

@ -12,10 +12,8 @@ import 'environment_editor.dart';
class EnvironmentPage extends ConsumerWidget {
const EnvironmentPage({
super.key,
required this.scaffoldKey,
});
final GlobalKey<ScaffoldState> scaffoldKey;
@override
Widget build(BuildContext context, WidgetRef ref) {
final id = ref.watch(selectedEnvironmentIdStateProvider);
@ -23,7 +21,7 @@ class EnvironmentPage extends ConsumerWidget {
selectedEnvironmentModelProvider.select((value) => value?.name)));
if (context.isMediumWindow) {
return DrawerSplitView(
scaffoldKey: scaffoldKey,
scaffoldKey: kEnvScaffoldKey,
mainContent: const EnvironmentEditor(),
title: EditorTitle(
title: name,

View File

@ -191,7 +191,7 @@ class EnvironmentItem extends ConsumerWidget {
},
onTap: () {
ref.read(selectedEnvironmentIdStateProvider.notifier).state = id;
ref.read(mobileScaffoldKeyStateProvider).currentState?.closeDrawer();
kEnvScaffoldKey.currentState?.closeDrawer();
},
focusNode: ref.watch(nameTextFieldFocusNodeProvider),
onChangedNameEditor: (value) {

View File

@ -4,16 +4,15 @@ import 'package:apidash/widgets/widgets.dart';
import 'package:apidash/extensions/extensions.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/utils/utils.dart';
import 'package:apidash/consts.dart';
import 'history_pane.dart';
import 'history_viewer.dart';
class HistoryPage extends ConsumerWidget {
const HistoryPage({
super.key,
required this.scaffoldKey,
});
final GlobalKey<ScaffoldState> scaffoldKey;
@override
Widget build(BuildContext context, WidgetRef ref) {
final historyModel = ref.watch(selectedHistoryRequestModelProvider);
@ -22,7 +21,7 @@ class HistoryPage extends ConsumerWidget {
: 'History';
if (context.isMediumWindow) {
return DrawerSplitView(
scaffoldKey: scaffoldKey,
scaffoldKey: kHisScaffoldKey,
mainContent: const HistoryViewer(),
title: Text(title),
leftDrawerContent: const HistoryPane(),

View File

@ -150,10 +150,7 @@ class _HistoryExpansionTileState extends ConsumerState<HistoryExpansionTile>
ref
.read(historyMetaStateNotifier.notifier)
.loadHistoryRequest(item.first.historyId);
ref
.read(mobileScaffoldKeyStateProvider)
.currentState
?.closeDrawer();
kHisScaffoldKey.currentState?.closeDrawer();
},
),
);

View File

@ -1,7 +1,7 @@
import 'package:apidash/importer/importer.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:apidash/providers/providers.dart';
import 'package:apidash/importer/importer.dart';
import 'package:apidash/extensions/extensions.dart';
import 'package:apidash/widgets/widgets.dart';
import 'package:apidash/models/models.dart';
@ -221,7 +221,7 @@ class RequestItem extends ConsumerWidget {
editRequestId: editRequestId,
onTap: () {
ref.read(selectedIdStateProvider.notifier).state = id;
ref.read(mobileScaffoldKeyStateProvider).currentState?.closeDrawer();
kHomeScaffoldKey.currentState?.closeDrawer();
},
// onDoubleTap: () {
// ref.read(selectedIdStateProvider.notifier).state = id;

View File

@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:apidash/widgets/widgets.dart';
import 'package:apidash/extensions/extensions.dart';
import '../mobile/requests_page/requests_page.dart';
import 'editor_pane/editor_pane.dart';
import 'collection_pane.dart';
@ -8,7 +10,9 @@ class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return const Column(
return context.isMediumWindow
? const RequestResponsePage()
: const Column(
children: [
Expanded(
child: DashboardSplitView(

View File

@ -67,25 +67,18 @@ class PageBranch extends ConsumerWidget {
final int pageIndex;
@override
Widget build(BuildContext context, WidgetRef ref) {
final scaffoldKey = ref.watch(mobileScaffoldKeyStateProvider);
switch (pageIndex) {
case 1:
return EnvironmentPage(
scaffoldKey: scaffoldKey,
);
return const EnvironmentPage();
case 2:
return HistoryPage(
scaffoldKey: scaffoldKey,
);
return const HistoryPage();
case 3:
return const PageBase(
title: 'Settings',
scaffoldBody: SettingsPage(),
);
default:
return RequestResponsePage(
scaffoldKey: scaffoldKey,
);
return const RequestResponsePage();
}
}
}

View File

@ -52,7 +52,7 @@ class BottomNavBar extends ConsumerWidget {
child: NavbarButton(
railIdx: railIdx,
buttonIdx: 2,
selectedIcon: Icons.history,
selectedIcon: Icons.history_rounded,
icon: Icons.history_outlined,
label: 'History',
),

View File

@ -15,11 +15,8 @@ import 'request_response_tabs.dart';
class RequestResponsePage extends StatefulHookConsumerWidget {
const RequestResponsePage({
super.key,
required this.scaffoldKey,
});
final GlobalKey<ScaffoldState> scaffoldKey;
@override
ConsumerState<RequestResponsePage> createState() =>
_RequestResponsePageState();
@ -35,7 +32,7 @@ class _RequestResponsePageState extends ConsumerState<RequestResponsePage>
final TabController requestResponseTabController =
useTabController(initialLength: 2, vsync: this);
return DrawerSplitView(
scaffoldKey: widget.scaffoldKey,
scaffoldKey: kHomeScaffoldKey,
title: EditorTitle(
title: name,
onSelected: (ItemMenuOption item) {

View File

@ -149,7 +149,7 @@ class SettingsPage extends ConsumerWidget {
hoverColor: kColorTransparent,
title: const Text('History Retention Period'),
subtitle: Text(
'Your request history will be retained for ${settings.historyRetentionPeriod.label}'),
'Your request history will be retained${settings.historyRetentionPeriod == HistoryRetentionPeriod.forever ? "" : " for"} ${settings.historyRetentionPeriod.label}'),
trailing: Container(
decoration: BoxDecoration(
border: Border.all(

View File

@ -69,3 +69,14 @@ double? getJsonPreviewerMaxRootNodeWidth(double w) {
}
return w - 150;
}
GlobalKey<ScaffoldState> getScaffoldKey(int railIdx) {
switch (railIdx) {
case 1:
return kEnvScaffoldKey;
case 2:
return kHisScaffoldKey;
default:
return kHomeScaffoldKey;
}
}

View File

@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:apidash/extensions/extensions.dart';
import 'package:apidash/consts.dart';
class HistoryRetentionPopupMenu extends StatelessWidget {
@ -15,11 +14,11 @@ class HistoryRetentionPopupMenu extends StatelessWidget {
final List<HistoryRetentionPeriod>? items;
@override
Widget build(BuildContext context) {
final double boxLength = context.isCompactWindow ? 110 : 130;
const double boxLength = 120;
return PopupMenuButton(
tooltip: "Select retention period",
surfaceTintColor: kColorTransparent,
constraints: BoxConstraints(minWidth: boxLength),
constraints: const BoxConstraints(minWidth: boxLength),
itemBuilder: (BuildContext context) {
return [
...items!.map((period) {
@ -44,6 +43,7 @@ class HistoryRetentionPopupMenu extends StatelessWidget {
Text(
value.label,
style: kTextStylePopupMenuItem,
overflow: TextOverflow.ellipsis,
),
const Icon(
Icons.unfold_more,

View File

@ -15,7 +15,7 @@ class URIPopupMenu extends StatelessWidget {
final List<String>? items;
@override
Widget build(BuildContext context) {
final double boxLength = context.isCompactWindow ? 90 : 130;
final double boxLength = context.isCompactWindow ? 90 : 110;
return PopupMenuButton(
tooltip: "Select URI Scheme",
surfaceTintColor: kColorTransparent,

View File

@ -14,6 +14,7 @@ void main() {
saveResponses: true,
promptBeforeClosing: true,
activeEnvironmentId: null,
historyRetentionPeriod: HistoryRetentionPeriod.oneWeek,
);
test('Testing toJson()', () {
@ -28,7 +29,8 @@ void main() {
"defaultCodeGenLang": "curl",
"saveResponses": true,
"promptBeforeClosing": true,
'activeEnvironmentId': null
"activeEnvironmentId": null,
"historyRetentionPeriod": "oneWeek",
};
expect(sm.toJson(), expectedResult);
});
@ -45,7 +47,8 @@ void main() {
"defaultCodeGenLang": "curl",
"saveResponses": true,
"promptBeforeClosing": true,
'activeEnvironmentId': null
"activeEnvironmentId": null,
"historyRetentionPeriod": "oneWeek",
};
expect(SettingsModel.fromJson(input), sm);
});
@ -61,6 +64,7 @@ void main() {
saveResponses: false,
promptBeforeClosing: true,
activeEnvironmentId: null,
historyRetentionPeriod: HistoryRetentionPeriod.oneWeek,
);
expect(
sm.copyWith(
@ -72,7 +76,7 @@ void main() {
test('Testing toString()', () {
const expectedResult =
"{isDark: false, alwaysShowCollectionPaneScrollbar: true, width: 300.0, height: 200.0, dx: 100.0, dy: 150.0, defaultUriScheme: http, defaultCodeGenLang: curl, saveResponses: true, promptBeforeClosing: true, activeEnvironmentId: null}";
"{isDark: false, alwaysShowCollectionPaneScrollbar: true, width: 300.0, height: 200.0, dx: 100.0, dy: 150.0, defaultUriScheme: http, defaultCodeGenLang: curl, saveResponses: true, promptBeforeClosing: true, activeEnvironmentId: null, historyRetentionPeriod: oneWeek}";
expect(sm.toString(), expectedResult);
});

View File

@ -12,6 +12,7 @@ import 'package:apidash/screens/home_page/editor_pane/editor_pane.dart';
import 'package:apidash/screens/home_page/editor_pane/url_card.dart';
import 'package:apidash/screens/home_page/home_page.dart';
import 'package:apidash/screens/settings_page.dart';
import 'package:apidash/screens/history/history_page.dart';
import 'package:apidash/services/hive_services.dart';
import 'package:apidash/widgets/widgets.dart';
import 'package:extended_text_field/extended_text_field.dart';
@ -59,6 +60,7 @@ void main() {
// Verify that the HomePage is displayed initially
expect(find.byType(HomePage), findsOneWidget);
expect(find.byType(EnvironmentPage), findsNothing);
expect(find.byType(HistoryPage), findsNothing);
expect(find.byType(SettingsPage), findsNothing);
});
@ -79,9 +81,32 @@ void main() {
// Verify that the EnvironmentPage is displayed
expect(find.byType(HomePage), findsNothing);
expect(find.byType(EnvironmentPage), findsOneWidget);
expect(find.byType(HistoryPage), findsNothing);
expect(find.byType(SettingsPage), findsNothing);
});
testWidgets(
"Dashboard should display HistorPage when navRailIndexStateProvider is 2",
(WidgetTester tester) async {
await tester.pumpWidget(
ProviderScope(
overrides: [
navRailIndexStateProvider.overrideWith((ref) => 2),
],
child: const Portal(
child: MaterialApp(
home: Dashboard(),
),
),
),
);
// Verify that the SettingsPage is displayed
expect(find.byType(HomePage), findsNothing);
expect(find.byType(EnvironmentPage), findsNothing);
expect(find.byType(HistoryPage), findsOneWidget);
expect(find.byType(SettingsPage), findsNothing);
});
testWidgets(
"Dashboard should display SettingsPage when navRailIndexStateProvider is 3",
(WidgetTester tester) async {
@ -101,6 +126,7 @@ void main() {
// Verify that the SettingsPage is displayed
expect(find.byType(HomePage), findsNothing);
expect(find.byType(EnvironmentPage), findsNothing);
expect(find.byType(HistoryPage), findsNothing);
expect(find.byType(SettingsPage), findsOneWidget);
});
@ -159,7 +185,7 @@ void main() {
// Verify that the navRailIndexStateProvider still has the updated value
final dashboard = tester.element(find.byType(Dashboard));
final container = ProviderScope.containerOf(dashboard);
expect(container.read(navRailIndexStateProvider), 2);
expect(container.read(navRailIndexStateProvider), 3);
// Verify that the SettingsPage is still displayed after the rebuild
expect(find.byType(SettingsPage), findsOneWidget);
@ -193,10 +219,19 @@ void main() {
// Verify that the selected icon is the filled version (selectedIcon)
expect(find.byIcon(Icons.computer_rounded), findsOneWidget);
// Go to SettingsPage
// Go to HistoryPage
container.read(navRailIndexStateProvider.notifier).state = 2;
await tester.pump();
// Verify that the HistoryPage is displayed
expect(find.byType(HistoryPage), findsOneWidget);
// Verify that the selected icon is the filled version (selectedIcon)
expect(find.byIcon(Icons.history_rounded), findsOneWidget);
// Go to SettingsPage
container.read(navRailIndexStateProvider.notifier).state = 3;
await tester.pump();
// Verify that the SettingsPage is displayed
expect(find.byType(SettingsPage), findsOneWidget);
// Verify that the selected icon is the filled version (selectedIcon)