Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions FlowCrypt/Controllers/Threads/ThreadDetailsDecorator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import FlowCryptUI
import UIKit

extension ThreadMessageInfoCellNode.Input {
init(threadMessage: ThreadDetailsViewController.Input) {
init(threadMessage: ThreadDetailsViewController.Input, index: Int) {
let sender = threadMessage.rawMessage.sender ?? "message_unknown_sender".localized
let recipientPrefix = "to".localized
let recipientsList = threadMessage.rawMessage
Expand Down Expand Up @@ -40,7 +40,8 @@ extension ThreadMessageInfoCellNode.Input {
date: .text(from: date, style: style, color: dateColor),
isExpanded: threadMessage.isExpanded,
shouldShowRecipientsList: threadMessage.shouldShowRecipientsList,
buttonColor: .colorFor(darkStyle: .white, lightStyle: .main)
buttonColor: .colorFor(darkStyle: .white, lightStyle: .main),
index: index
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -449,9 +449,11 @@ extension ThreadDetailsViewController {
}
}

private func retryVerifyingSignatureWithRemotelyFetchedKeys(message: Message,
folder: String,
indexPath: IndexPath) {
private func retryVerifyingSignatureWithRemotelyFetchedKeys(
message: Message,
folder: String,
indexPath: IndexPath
) {
Task {
do {
let processedMessage = try await messageService.getAndProcessMessage(
Expand Down Expand Up @@ -561,11 +563,12 @@ extension ThreadDetailsViewController: ASTableDelegate, ASTableDataSource {
return MessageSubjectNode(subject.attributed(.medium(18)))
}

let message = self.input[indexPath.section - 1]
let messageIndex = indexPath.section - 1
let message = self.input[messageIndex]

if indexPath.row == 0 {
return ThreadMessageInfoCellNode(
input: .init(threadMessage: message),
input: .init(threadMessage: message, index: messageIndex),
onReplyTap: { [weak self] _ in self?.handleReplyTap(at: indexPath) },
onMenuTap: { [weak self] _ in self?.handleMenuTap(at: indexPath) },
onRecipientsTap: { [weak self] _ in self?.handleRecipientsTap(at: indexPath) }
Expand All @@ -577,7 +580,7 @@ extension ThreadDetailsViewController: ASTableDelegate, ASTableDataSource {
}

guard indexPath.row > 1 else {
return MessageTextSubjectNode(processedMessage.attributedMessage)
return MessageTextSubjectNode(processedMessage.attributedMessage, index: messageIndex)
}

let attachmentIndex = indexPath.row - 2
Expand Down
6 changes: 5 additions & 1 deletion FlowCryptUI/Cell Nodes/MessageTextSubjectNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@ import AsyncDisplayKit
public final class MessageTextSubjectNode: CellNode {
private let textNode = ASEditableTextNode()

public init(_ text: NSAttributedString?) {
public init(_ text: NSAttributedString?, index: Int) {
super.init()
textNode.attributedText = text
textNode.isAccessibilityElement = true
textNode.accessibilityIdentifier = "aid-message-\(index)"
textNode.accessibilityValue = text?.string

DispatchQueue.main.async {
self.textNode.textView.isSelectable = true
self.textNode.textView.isEditable = false
Expand Down
55 changes: 31 additions & 24 deletions FlowCryptUI/Cell Nodes/ThreadMessageInfoCellNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public final class ThreadMessageInfoCellNode: CellNode {
public let isExpanded: Bool
public let shouldShowRecipientsList: Bool
public let buttonColor: UIColor
public let index: Int

public init(
encryptionBadge: BadgeNode.Input,
Expand All @@ -35,7 +36,8 @@ public final class ThreadMessageInfoCellNode: CellNode {
date: NSAttributedString,
isExpanded: Bool,
shouldShowRecipientsList: Bool,
buttonColor: UIColor
buttonColor: UIColor,
index: Int
) {
self.encryptionBadge = encryptionBadge
self.signatureBadge = signatureBadge
Expand All @@ -48,6 +50,7 @@ public final class ThreadMessageInfoCellNode: CellNode {
self.isExpanded = isExpanded
self.shouldShowRecipientsList = shouldShowRecipientsList
self.buttonColor = buttonColor
self.index = index
}

var replyImage: UIImage? { createButtonImage("arrow.turn.up.left") }
Expand Down Expand Up @@ -138,23 +141,15 @@ public final class ThreadMessageInfoCellNode: CellNode {
public private(set) var menuNode = ASButtonNode()
public private(set) var expandNode = ASImageNode()

private lazy var recipientsListNode: ASDisplayNode = {
MessageRecipientsNode(
input: .init(
recipients: input.recipients,
ccRecipients: input.ccRecipients,
bccRecipients: input.bccRecipients
)
private lazy var recipientsListNode: ASDisplayNode = MessageRecipientsNode(
input: .init(
recipients: input.recipients,
ccRecipients: input.ccRecipients,
bccRecipients: input.bccRecipients
)
}()

private lazy var encryptionNode: BadgeNode = {
BadgeNode(input: input.encryptionBadge)
}()

private lazy var signatureNode: BadgeNode? = {
input.signatureBadge.map(BadgeNode.init)
}()
)
private lazy var encryptionNode = BadgeNode(input: input.encryptionBadge)
private lazy var signatureNode: BadgeNode? = input.signatureBadge.map(BadgeNode.init)

// MARK: - Properties
private let input: ThreadMessageInfoCellNode.Input
Expand All @@ -170,10 +165,12 @@ public final class ThreadMessageInfoCellNode: CellNode {
}

// MARK: - Init
public init(input: ThreadMessageInfoCellNode.Input,
onReplyTap: ((ThreadMessageInfoCellNode) -> Void)?,
onMenuTap: ((ThreadMessageInfoCellNode) -> Void)?,
onRecipientsTap: ((ThreadMessageInfoCellNode) -> Void)?) {
public init(
input: ThreadMessageInfoCellNode.Input,
onReplyTap: ((ThreadMessageInfoCellNode) -> Void)?,
onMenuTap: ((ThreadMessageInfoCellNode) -> Void)?,
onRecipientsTap: ((ThreadMessageInfoCellNode) -> Void)?
) {
self.input = input
self.onReplyTap = onReplyTap
self.onMenuTap = onMenuTap
Expand All @@ -183,14 +180,13 @@ public final class ThreadMessageInfoCellNode: CellNode {
automaticallyManagesSubnodes = true

senderNode.attributedText = input.sender
senderNode.accessibilityIdentifier = "aid-message-sender-label"

dateNode.attributedText = input.date

setupRecipientButton()
setupReplyNode()
setupMenuNode()
setupExpandNode()
setupAccessibilityIdentifiers()
}

// MARK: - Setup
Expand All @@ -205,7 +201,6 @@ public final class ThreadMessageInfoCellNode: CellNode {
recipientButtonNode.contentSpacing = 4

recipientButtonNode.addTarget(self, action: #selector(onRecipientsNodeTap), forControlEvents: .touchUpInside)
recipientButtonNode.accessibilityIdentifier = "aid-message-recipients-tappable-area"
}

private func setupReplyNode() {
Expand Down Expand Up @@ -244,6 +239,18 @@ public final class ThreadMessageInfoCellNode: CellNode {
expandNode.contentMode = .center
}

// MARK: - AccessibilityIdentifiers
private func setupAccessibilityIdentifiers() {
recipientButtonNode.accessibilityIdentifier = "aid-message-recipients-tappable-area"

expandNode.accessibilityIdentifier = "aid-expand-image-\(input.index)"
senderNode.accessibilityIdentifier = "aid-sender-\(input.index)"
dateNode.accessibilityIdentifier = "aid-date-\(input.index)"

[senderNode, recipientButtonNode, senderNode, dateNode]
.forEach { $0.isAccessibilityElement = true }
}

// MARK: - Callbacks
@objc private func onReplyNodeTap() {
onReplyTap?(self)
Expand Down
1 change: 0 additions & 1 deletion FlowCryptUI/Nodes/MessageRecipientsNode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public final class MessageRecipientsNode: ASDisplayNode {
super.init()

automaticallyManagesSubnodes = true

setupBorder()
}

Expand Down
19 changes: 19 additions & 0 deletions appium/tests/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,25 @@ export const CommonData = {
message: 'test email from gmail',
sender: 'e2e.enterprise.test@flowcrypt.com'
},
threadMessage: {
subject: 'test thread rendering',
sender: 'dmitry@flowcrypt.com',
firstThreadMessage: 'first message',
secondThreadMessage: 'Second thread rendering message\n' +
'\n' +
'On 04.02.2022 at 11:12 dmitry@flowcrypt.com wrote:\n' +
' > first message',
thirdThreadMessage: 'Third thread rendering message\n' +
'\n' +
'On 2022-02-07 at 06:56, e2e.enterprise.test@flowcrypt.com wrote:\n' +
'> Second thread rendering message\n' +
'>\n' +
'> On 04.02.2022 at 11:12 dmitry@flowcrypt.com wrote:\n' +
'> > first message',
firstDate: 'Feb 04',
secondDate: 'Feb 06',
thirdDate: 'Feb 07',
},
sender: {
email: 'dmitry@flowcrypt.com',
},
Expand Down
44 changes: 36 additions & 8 deletions appium/tests/screenobjects/email.screen.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import BaseScreen from './base.screen';
import { CommonData } from "../data";
import ElementHelper from "../helpers/ElementHelper";
import moment from "moment";

const SELECTORS = {
BACK_BTN: '~aid-back-button',
Expand Down Expand Up @@ -105,10 +106,6 @@ class EmailScreen extends BaseScreen {
return $(SELECTORS.CANCEL_BUTTON);
}

get senderEmail() {
return $(SELECTORS.SENDER_EMAIL);
}

get encryptionBadge() {
return $(SELECTORS.ENCRYPTION_BADGE);
}
Expand All @@ -121,18 +118,27 @@ class EmailScreen extends BaseScreen {
return $(SELECTORS.ATTACHMENT_TEXT_VIEW);
}

checkEmailAddress = async (email: string) => {
await ElementHelper.checkStaticText(await this.senderEmail, email);
senderEmail = async (index = 0) =>{
return $(`~aid-sender-${index}`)
}

checkEmailAddress = async (email: string, index = 0)=> {
const element = await this.senderEmail(index);
await (await element).waitForDisplayed();
await expect(await (await element).getValue()).toEqual(email);
}

checkEmailSubject = async (subject: string) => {
const selector = `~${subject}`;
await (await $(selector)).waitForDisplayed();
}

checkEmailText = async (text: string) => {
const selector = `~${text}`;
checkEmailText = async (text: string, index = 0) => {
const selector = `~aid-message-${index}`;
await (await $(selector)).waitForDisplayed();
console.log(await $(selector).getValue());

await expect(await $(selector).getValue()).toContain(text)
}

checkOpenedEmail = async (email: string, subject: string, text: string) => {
Expand All @@ -141,6 +147,28 @@ class EmailScreen extends BaseScreen {
await this.checkEmailText(text);
}

checkThreadMessage = async (email: string, subject: string, text: string, date: string, index = 0) => {
await this.checkEmailSubject(subject);
await this.checkEmailAddress(email, index);
await this.clickExpandButtonByIndex(index);
await this.checkEmailText(text, index);
await this.checkDate(date, index);
}

clickExpandButtonByIndex = async (index: any) => {
const element = (`~aid-expand-image-${index}`);
if(await (await $(element)).isDisplayed()) {
await ElementHelper.waitAndClick(await $(element));
}
}

checkDate = async (date: string, index: any) => {
const element = `~aid-date-${index}`;
await (await $(element)).waitForDisplayed();
const convertedDate = moment(await $(element).getValue()).utcOffset(0).format('MMM DD');
await expect(convertedDate).toEqual(date)
}

clickBackButton = async () => {
await ElementHelper.waitAndClick(await this.backButton);
}
Expand Down
2 changes: 1 addition & 1 deletion appium/tests/screenobjects/old-version-app.screen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class OldVersionAppScreen extends BaseScreen {
}

clickBackButton = async () => {
await ElementHelper.waitAndClick(await this.backButton);
await ElementHelper.waitAndClick(await this.backButton, 500);
}

checkEmailAddress = async (email: string) => {
Expand Down
31 changes: 31 additions & 0 deletions appium/tests/specs/live/inbox/CheckThreadRendering.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
SplashScreen,
SetupKeyScreen,
MailFolderScreen,
EmailScreen
} from '../../../screenobjects/all-screens';
import { CommonData } from '../../../data';

describe('INBOX: ', () => {

it('check thread rendering', async () => {
const senderEmail = CommonData.threadMessage.sender;
const emailSubject = CommonData.threadMessage.subject;
const firstMessage = CommonData.threadMessage.firstThreadMessage;
const secondMessage = CommonData.threadMessage.secondThreadMessage;
const thirdMessage = CommonData.threadMessage.thirdThreadMessage;
const userEmail = CommonData.account.email;
const dateFirst = CommonData.threadMessage.firstDate;
const dateSecond = CommonData.threadMessage.secondDate;
const dateThird = CommonData.threadMessage.thirdDate;

await SplashScreen.login();
await SetupKeyScreen.setPassPhrase();
await MailFolderScreen.checkInboxScreen();

await MailFolderScreen.clickOnEmailBySubject(emailSubject);
await EmailScreen.checkThreadMessage(senderEmail, emailSubject, thirdMessage, dateThird, 2);
await EmailScreen.checkThreadMessage(userEmail, emailSubject, secondMessage, dateSecond, 1);
await EmailScreen.checkThreadMessage(senderEmail, emailSubject, firstMessage, dateFirst);
});
});