diff --git a/FlowCrypt/Controllers/Search/SearchViewController.swift b/FlowCrypt/Controllers/Search/SearchViewController.swift index 5f05f88e7..4c906f304 100644 --- a/FlowCrypt/Controllers/Search/SearchViewController.swift +++ b/FlowCrypt/Controllers/Search/SearchViewController.swift @@ -79,7 +79,10 @@ final class SearchViewController: TableNodeViewController { extension SearchViewController { private func setupUI() { view.backgroundColor = .backgroundColor + view.accessibilityIdentifier = "searchViewController" + title = "search_title".localized + node.delegate = self node.dataSource = self } @@ -91,7 +94,7 @@ extension SearchViewController { $0.hidesNavigationBarDuringPresentation = false $0.searchBar.tintColor = .white $0.searchBar.setImage(#imageLiteral(resourceName: "search_icn").tinted(.white), for: .search, state: .normal) - $0.searchBar.setImage(#imageLiteral(resourceName: "cancel.png").tinted(.white), for: .clear, state: .normal) + $0.searchBar.setImage(#imageLiteral(resourceName: "cancel").tinted(.white), for: .clear, state: .normal) $0.searchBar.delegate = self $0.searchBar.searchTextField.textColor = .white } diff --git a/FlowCrypt/Controllers/Threads/ThreadDetailsDecorator.swift b/FlowCrypt/Controllers/Threads/ThreadDetailsDecorator.swift index 5291622f0..e6b012622 100644 --- a/FlowCrypt/Controllers/Threads/ThreadDetailsDecorator.swift +++ b/FlowCrypt/Controllers/Threads/ThreadDetailsDecorator.swift @@ -94,7 +94,8 @@ private func makeEncryptionBadge(_ input: ThreadDetailsViewController.Input) -> return BadgeNode.Input( icon: icon, text: NSAttributedString.text(from: text, style: .regular(12), color: .white), - color: color + color: color, + textAccessibilityIdentifier: "encryptionBadge" ) } @@ -103,16 +104,10 @@ private func makeSignatureBadge(_ input: ThreadDetailsViewController.Input) -> B return nil } - let text: String - if input.processedMessage?.messageType == .encrypted { - text = signature.message - } else { - text = "message_not_signed".localized - } - return BadgeNode.Input( icon: signature.icon, - text: NSAttributedString.text(from: text, style: .regular(12), color: .white), - color: signature.color + text: NSAttributedString.text(from: signature.message, style: .regular(12), color: .white), + color: signature.color, + textAccessibilityIdentifier: "signatureBadge" ) } diff --git a/FlowCryptUI/Nodes/BadgeNode.swift b/FlowCryptUI/Nodes/BadgeNode.swift index 8dc587a4e..63a62f2e6 100644 --- a/FlowCryptUI/Nodes/BadgeNode.swift +++ b/FlowCryptUI/Nodes/BadgeNode.swift @@ -14,13 +14,16 @@ public final class BadgeNode: ASDisplayNode { public let icon: String? public let text: NSAttributedString? public let color: UIColor? + public let textAccessibilityIdentifier: String public init(icon: String?, text: NSAttributedString?, - color: UIColor?) { + color: UIColor?, + textAccessibilityIdentifier: String) { self.icon = icon self.text = text self.color = color + self.textAccessibilityIdentifier = textAccessibilityIdentifier } } @@ -43,6 +46,7 @@ public final class BadgeNode: ASDisplayNode { automaticallyManagesSubnodes = true textNode.attributedText = input.text + textNode.accessibilityIdentifier = input.textAccessibilityIdentifier backgroundColor = input.color cornerRadius = 4 } diff --git a/appium/tests/screenobjects/all-screens.ts b/appium/tests/screenobjects/all-screens.ts index cedb21647..778084ee8 100644 --- a/appium/tests/screenobjects/all-screens.ts +++ b/appium/tests/screenobjects/all-screens.ts @@ -10,6 +10,7 @@ import ContactPublicKeyScreen from './contact-public-key.screen'; import PublicKeyScreen from './public-key.screen'; import AttachmentScreen from './attachment.screen'; import MailFolderScreen from './mail-folder.screen' +import SearchScreen from './search.screen' export { SplashScreen, @@ -23,5 +24,6 @@ export { PublicKeyScreen, ContactScreen, ContactPublicKeyScreen, - MailFolderScreen + MailFolderScreen, + SearchScreen }; diff --git a/appium/tests/screenobjects/email.screen.ts b/appium/tests/screenobjects/email.screen.ts index 3f83e12f1..e6ea1597e 100644 --- a/appium/tests/screenobjects/email.screen.ts +++ b/appium/tests/screenobjects/email.screen.ts @@ -13,7 +13,9 @@ const SELECTORS = { FORWARD_BUTTON: '~Forward', DELETE_BUTTON: '~Delete', CONFIRM_DELETING: '~OK', - SENDER_EMAIL: '~senderEmail' + SENDER_EMAIL: '~senderEmail', + ENCRYPTION_BADGE: '~encryptionBadge', + SIGNATURE_BADGE: '~signatureBadge' }; @@ -63,7 +65,15 @@ class EmailScreen extends BaseScreen { } get senderEmail() { - return $(SELECTORS.SENDER_EMAIL); + return $(SELECTORS.SENDER_EMAIL); + } + + get encryptionBadge() { + return $(SELECTORS.ENCRYPTION_BADGE); + } + + get signatureBadge() { + return $(SELECTORS.SIGNATURE_BADGE); } checkEmailAddress = async (email: string) => { @@ -136,7 +146,17 @@ class EmailScreen extends BaseScreen { } confirmDelete = async () => { - await ElementHelper.waitAndClick(await this.confirmDeletingButton) + await ElementHelper.waitAndClick(await this.confirmDeletingButton); + } + + checkEncryptionBadge = async (value: string) => { + await (await this.encryptionBadge).waitForDisplayed(); + await expect(await this.encryptionBadge).toHaveText(value); + } + + checkSignatureBadge = async (value: string) => { + await (await this.signatureBadge).waitForDisplayed(); + await expect(await this.signatureBadge).toHaveText(value); } } diff --git a/appium/tests/screenobjects/search.screen.ts b/appium/tests/screenobjects/search.screen.ts new file mode 100644 index 000000000..685631457 --- /dev/null +++ b/appium/tests/screenobjects/search.screen.ts @@ -0,0 +1,36 @@ +import BaseScreen from './base.screen'; +import ElementHelper from "../helpers/ElementHelper"; + +const SELECTORS = { + BACK_BUTTON: '~arrow left c', + SCREEN: '~searchViewController', + SEARCH_FIELD: '~searchAllEmailField' +}; + +class SearchScreen extends BaseScreen { + constructor() { + super(SELECTORS.SCREEN); + } + + get backButton() { + return $(SELECTORS.BACK_BUTTON) + } + + get searchField() { + return $(SELECTORS.SEARCH_FIELD); + } + + clickBackButton = async () => { + await browser.pause(2000); + await ElementHelper.waitAndClick(await this.backButton); + } + + searchAndClickEmailBySubject = async (subject: string) => { + await (await this.searchField).setValue(`subject: '${subject}'`); + + const selector = `~${subject}`; + await ElementHelper.waitAndClick(await $(selector), 500); + } +} + +export default new SearchScreen(); diff --git a/appium/tests/specs/inbox/CheckAllEmailSignatureCases.spec.ts b/appium/tests/specs/inbox/CheckAllEmailSignatureCases.spec.ts new file mode 100644 index 000000000..e3af10387 --- /dev/null +++ b/appium/tests/specs/inbox/CheckAllEmailSignatureCases.spec.ts @@ -0,0 +1,75 @@ +import { + SplashScreen, + SetupKeyScreen, + MailFolderScreen, + EmailScreen, + SearchScreen +} from '../../screenobjects/all-screens'; + +describe('INBOX: ', () => { + + it('user is able to view correct signature badge for all cases', async () => { + + await SplashScreen.login(); + await SetupKeyScreen.setPassPhrase(); + await MailFolderScreen.checkInboxScreen(); + + // signed+encrypted message + await MailFolderScreen.clickSearchButton(); + + await SearchScreen.searchAndClickEmailBySubject('Signed and encrypted message'); + + await EmailScreen.checkEncryptionBadge('encrypted'); + await EmailScreen.checkSignatureBadge('signed'); + await EmailScreen.clickBackButton(); + + await SearchScreen.clickBackButton(); + + // singed only message + await MailFolderScreen.clickSearchButton(); + await SearchScreen.searchAndClickEmailBySubject('Signed only message'); + + await EmailScreen.checkEncryptionBadge('not encrypted'); + await EmailScreen.checkSignatureBadge('signed'); + await EmailScreen.clickBackButton(); + + await SearchScreen.clickBackButton(); + + // signed only message with detached signature + await MailFolderScreen.clickSearchButton(); + await SearchScreen.searchAndClickEmailBySubject('Signed only message with detached signature'); + + await EmailScreen.checkEncryptionBadge('not encrypted'); + await EmailScreen.checkSignatureBadge('signed'); + await EmailScreen.clickBackButton(); + + await SearchScreen.clickBackButton(); + + // plain message + await MailFolderScreen.clickSearchButton(); + await SearchScreen.searchAndClickEmailBySubject('Test 1'); + + await EmailScreen.checkEncryptionBadge('not encrypted'); + await EmailScreen.checkSignatureBadge('not signed'); + await EmailScreen.clickBackButton(); + + await SearchScreen.clickBackButton(); + + // signed only message where the pubkey is not available + await MailFolderScreen.clickSearchButton(); + await SearchScreen.searchAndClickEmailBySubject('Signed only message where the pubkey is not available'); + + await EmailScreen.checkEncryptionBadge('decrypt error'); + await EmailScreen.clickBackButton(); + + await SearchScreen.clickBackButton(); + + // signed only message that was tempered during transit + await MailFolderScreen.clickSearchButton(); + await SearchScreen.searchAndClickEmailBySubject('Signed only message that was tempered during transit'); + + await EmailScreen.checkEncryptionBadge('not encrypted'); + await EmailScreen.checkSignatureBadge('bad signature'); + await EmailScreen.clickBackButton(); + }); +});