From 97a9fd4cb7b1ecd40d0fcbcc3dafefefe95034b4 Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Wed, 27 Aug 2025 00:39:18 +0530 Subject: [PATCH] Search test --- .../auth/integration_test/auth_flow_test.dart | 322 ++++++++++++++++++ 1 file changed, 322 insertions(+) diff --git a/mobile/apps/auth/integration_test/auth_flow_test.dart b/mobile/apps/auth/integration_test/auth_flow_test.dart index 794f305a30..69ae5dbe53 100644 --- a/mobile/apps/auth/integration_test/auth_flow_test.dart +++ b/mobile/apps/auth/integration_test/auth_flow_test.dart @@ -1,7 +1,9 @@ import 'package:ente_auth/app/view/app.dart'; import 'package:ente_auth/bootstrap.dart'; import 'package:ente_auth/main.dart'; +import 'package:ente_auth/onboarding/view/common/add_chip.dart'; import 'package:ente_auth/services/update_service.dart'; +import 'package:ente_lock_screen/local_authentication_service.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; @@ -243,8 +245,328 @@ void main() { print('- testIssuer and testIssuer2 entries are visible'); print('- testAccount and testAccount2 are visible'); + // Step 9: Test search functionality + print('🔍 Testing search functionality...'); + + // Click on search icon to activate search + final searchIcon = find.byIcon(Icons.search); + expect(searchIcon, findsOneWidget, reason: 'Search icon not found'); + await tester.tap(searchIcon); + await tester.pumpAndSettle(); + + // Find the search text field + final searchField = find.byType(TextField); + expect(searchField, findsOneWidget, + reason: 'Search text field not found'); + + // Enter search term "issuer2" + await tester.tap(searchField); + await tester.enterText(searchField, 'issuer2'); + await tester.pumpAndSettle(); + + // Verify only one result is shown (testIssuer2) + final searchResults = find.textContaining('testIssuer'); + final issuer2Results = find.textContaining('testIssuer2'); + + // Should find testIssuer2 but not testIssuer when searching for "issuer2" + expect(issuer2Results, findsAtLeastNWidgets(1), + reason: 'testIssuer2 not found in search results'); + + // Verify total results - should only show the matching entry + final allVisibleIssuers = find.textContaining('testIssuer'); + expect(allVisibleIssuers.evaluate().length, equals(1), + reason: 'Search should show only one result for "issuer2"'); + + print('✅ Search results verified: only testIssuer2 is visible'); + + // Clear search bar + final clearIcon = find.byIcon(Icons.clear); + expect(clearIcon, findsOneWidget, + reason: 'Clear search icon not found'); + await tester.tap(clearIcon); + await tester.pumpAndSettle(); + + // Verify both entries are visible again after clearing search + final allIssuer1 = find.textContaining('testIssuer'); + final allIssuer2 = find.textContaining('testIssuer2'); + expect(allIssuer1, findsAtLeastNWidgets(1), + reason: 'testIssuer not visible after clearing search'); + expect(allIssuer2, findsAtLeastNWidgets(1), + reason: 'testIssuer2 not visible after clearing search'); + + print('✅ Search cleared: both entries visible again'); + print('✅ Step 3 completed: Search functionality working correctly'); + + // Step 10: Long press on issuer2 to edit and add tags + print('🏷️ Testing tag functionality...'); + + // Long press on testIssuer2 entry to bring up edit menu + final issuer2Entry = find.textContaining('testIssuer2'); + expect(issuer2Entry, findsOneWidget, + reason: 'testIssuer2 entry not found for long press'); + await tester.longPress(issuer2Entry); + await tester.pumpAndSettle(); + LocalAuthenticationService.instance.lastAuthTime = DateTime.now() + .add(const Duration(minutes: 10)) + .millisecondsSinceEpoch; + + // Look for edit option and tap it + final editOption = find.text('Edit'); + expect(editOption, findsOneWidget, reason: 'Edit option not found'); + await tester.tap(editOption); + await tester.pumpAndSettle(); + + // Wait for edit page to load + await tester.pumpAndSettle(const Duration(seconds: 2)); + + // Look for AddChip widget to add first tag + final addChip = find.byType(AddChip); + expect(addChip, findsOneWidget, reason: 'AddChip widget not found'); + await tester.tap(addChip); + await tester.pumpAndSettle(); + + // Enter first tag name "tag1" + final tagInputField = find.byType(TextField).last; + await tester.tap(tagInputField); + await tester.enterText(tagInputField, 'tag1'); + await tester.pumpAndSettle(); + + // Tap create/save button for first tag + final createButton = find.text('Create'); + expect(createButton, findsOneWidget, + reason: 'Create button not found for first tag'); + await tester.tap(createButton); + await tester.pumpAndSettle(); + + // Add second tag + final addChip2 = find.byType(AddChip); + await tester.tap(addChip2); + await tester.pumpAndSettle(); + + // Enter second tag name "tag2" + final tagInputField2 = find.byType(TextField).last; + await tester.tap(tagInputField2); + await tester.enterText(tagInputField2, 'tag2'); + await tester.pumpAndSettle(); + + // Tap create button for second tag + final createButton2 = find.text('Create'); + await tester.tap(createButton2); + await tester.pumpAndSettle(); + + // Verify tags are selected/visible + final tag1Chip = find.text('tag1'); + final tag2Chip = find.text('tag2'); + expect(tag1Chip, findsOneWidget, + reason: 'tag1 not found after creation'); + expect(tag2Chip, findsOneWidget, + reason: 'tag2 not found after creation'); + + print('✅ Tags created: tag1 and tag2 are visible'); + + // Save the edited entry + final saveEditButton = find.text('Save'); + expect(saveEditButton, findsOneWidget, + reason: 'Save button not found on edit page'); + await tester.tap(saveEditButton); + await tester.pumpAndSettle(); + + // Wait for navigation back to home + await tester.pumpAndSettle(const Duration(seconds: 2)); + + print('✅ Entry saved with tags'); + + // Step 11: Test tag filtering functionality + print('🏷️ Testing tag filtering...'); + + // Click on tag1 to filter entries + final tag1Filter = find.textContaining('tag1'); + if (tag1Filter.evaluate().isNotEmpty) { + await tester.tap(tag1Filter.first); + await tester.pumpAndSettle(); + + // Verify only testIssuer2 is visible (the one with tag1) + final filteredIssuer2 = find.textContaining('testIssuer2'); + final filteredIssuer1 = find.textContaining('testIssuer').evaluate().where( + (element) => !element.widget.toString().contains('testIssuer2') + ).length; + + expect(filteredIssuer2, findsAtLeastNWidgets(1), + reason: 'testIssuer2 not visible when filtering by tag1'); + expect(filteredIssuer1, equals(0), + reason: 'testIssuer should not be visible when filtering by tag1'); + + print('✅ Tag1 filtering verified: only testIssuer2 is visible'); + + // Click "All" to clear tag filter + final allFilter = find.text('All'); + if (allFilter.evaluate().isNotEmpty) { + await tester.tap(allFilter); + await tester.pumpAndSettle(); + + // Verify both entries are visible again + final allEntriesIssuer1 = find.textContaining('testIssuer'); + final allEntriesIssuer2 = find.textContaining('testIssuer2'); + expect(allEntriesIssuer1, findsAtLeastNWidgets(1)); + expect(allEntriesIssuer2, findsAtLeastNWidgets(1)); + + print('✅ Tag filter cleared: both entries visible again'); + } + } + + print('✅ Step 4 completed: Tag functionality working correctly'); + + // Step 12: Test trash functionality + print('🗑️ Testing trash functionality...'); + + // Long press on testIssuer2 entry to bring up context menu + final issuer2EntryForTrash = find.textContaining('testIssuer2').first; + await tester.longPress(issuer2EntryForTrash); + await tester.pumpAndSettle(); + + // Look for trash/delete option and tap it + final trashOption = find.text('Trash'); + if (trashOption.evaluate().isEmpty) { + // Try alternative delete options + final deleteOption = find.text('Delete'); + expect(deleteOption, findsOneWidget, reason: 'Delete/Trash option not found'); + await tester.tap(deleteOption); + } else { + await tester.tap(trashOption); + } + await tester.pumpAndSettle(); + + // Confirm deletion if dialog appears + final confirmButtons = [ + find.text('Yes'), + find.text('OK'), + find.text('Confirm'), + find.text('Delete'), + find.text('Trash'), + ]; + + for (final button in confirmButtons) { + if (button.evaluate().isNotEmpty) { + await tester.tap(button); + await tester.pumpAndSettle(); + break; + } + } + + print('✅ Issuer2 entry trashed'); + + // Step 13: Verify tags are no longer visible and trash tag appears + print('🏷️ Verifying tag visibility after trash...'); + + // Wait for UI to update + await tester.pumpAndSettle(const Duration(seconds: 1)); + + // Verify tag1 and tag2 are no longer visible (since issuer2 was the only entry with these tags) + final tag1Visible = find.textContaining('tag1'); + final tag2Visible = find.textContaining('tag2'); + + // Tags should not be visible anymore since the only entry with these tags was trashed + expect(tag1Visible.evaluate().isEmpty, isTrue, reason: 'tag1 should not be visible after trashing issuer2'); + expect(tag2Visible.evaluate().isEmpty, isTrue, reason: 'tag2 should not be visible after trashing issuer2'); + + // Verify trash tag is now visible + final trashTag = find.text('Trash'); + expect(trashTag, findsOneWidget, reason: 'Trash tag not visible after trashing entry'); + + print('✅ Tags hidden and Trash tag visible'); + + // Step 14: Test trash filtering + print('🗑️ Testing trash tag filtering...'); + + // Click on Trash tag to show trashed items + await tester.tap(trashTag); + await tester.pumpAndSettle(); + + // Verify issuer2 is visible in trash + final trashedIssuer2 = find.textContaining('testIssuer2'); + expect(trashedIssuer2, findsOneWidget, reason: 'testIssuer2 not visible in trash'); + + // Verify issuer1 is not visible (should be filtered out) + final issuer1InTrash = find.textContaining('testIssuer').evaluate().where( + (element) => !element.widget.toString().contains('testIssuer2') + ).length; + expect(issuer1InTrash, equals(0), reason: 'testIssuer should not be visible in trash filter'); + + print('✅ Trash filtering working: only trashed items visible'); + + // Step 15: Test All filter (should not show trashed items) + print('📋 Testing All filter excludes trash...'); + + // Click on "All" to show all non-trashed items + final allTag = find.text('All'); + await tester.tap(allTag); + await tester.pumpAndSettle(); + + // Verify issuer1 is visible + final allFilterIssuer1 = find.textContaining('testIssuer').evaluate().where( + (element) => !element.widget.toString().contains('testIssuer2') + ).length; + expect(allFilterIssuer1, greaterThan(0), reason: 'testIssuer should be visible in All filter'); + + // Verify issuer2 is NOT visible in All + final allFilterIssuer2 = find.textContaining('testIssuer2'); + expect(allFilterIssuer2.evaluate().isEmpty, isTrue, reason: 'testIssuer2 should not be visible in All filter'); + + print('✅ All filter working: trashed items excluded'); + + // Step 16: Test restore functionality + print('♻️ Testing restore functionality...'); + + // Go back to trash view + await tester.tap(trashTag); + await tester.pumpAndSettle(); + + // Long press on trashed issuer2 entry + final trashedEntryForRestore = find.textContaining('testIssuer2'); + await tester.longPress(trashedEntryForRestore); + await tester.pumpAndSettle(); + + // Look for restore option + final restoreOption = find.text('Restore'); + expect(restoreOption, findsOneWidget, reason: 'Restore option not found'); + await tester.tap(restoreOption); + await tester.pumpAndSettle(); + + print('✅ Restore option tapped'); + + // Step 17: Verify restoration worked + print('✅ Verifying restoration...'); + + // Wait for restoration to complete + await tester.pumpAndSettle(const Duration(seconds: 1)); + + // Go to All view to check if issuer2 is restored + await tester.tap(allTag); + await tester.pumpAndSettle(); + + // Verify both entries are now visible in All + final restoredIssuer1 = find.textContaining('testIssuer'); + final restoredIssuer2 = find.textContaining('testIssuer2'); + + expect(restoredIssuer1, findsAtLeastNWidgets(1), reason: 'testIssuer not visible after restore'); + expect(restoredIssuer2, findsAtLeastNWidgets(1), reason: 'testIssuer2 not visible after restore'); + + // Verify tags are visible again + final restoredTag1 = find.textContaining('tag1'); + final restoredTag2 = find.textContaining('tag2'); + + if (restoredTag1.evaluate().isNotEmpty && restoredTag2.evaluate().isNotEmpty) { + print('✅ Tags restored and visible again'); + } + + print('✅ Step 5 completed: Trash and restore functionality working correctly'); + print('✅ Integration test completed successfully!'); print('- Both entries created and verified'); + print('- Search functionality tested and working'); + print('- Tag functionality tested and working'); + print('- Trash functionality tested and working'); + print('- Restore functionality tested and working'); print('- Multiple TOTP codes are being generated'); print('- Data persistence is working correctly'); },