ChatTester.m 11.5 KB
Newer Older
DanmeiChen's avatar
DanmeiChen committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * Copyright (c) 2010-2019 Belledonne Communications SARL.
 *
 * This file is part of linphone-iphone
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
19 20

#import "ChatTester.h"
21
#include "LinphoneManager.h"
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
22

23
@implementation ChatTester
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
24

25 26
#pragma mark - setup

Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
27
- (void)beforeAll {
28 29
	[super beforeAll];
	[self switchToValidAccountIfNeeded];
30 31 32 33
}

- (void)beforeEach {
	[super beforeEach];
34
	[self goBackFromChat];
35
	[tester tapViewWithAccessibilityLabel:@"Chat"];
36 37 38 39
	[self removeAllRooms];
}

- (void)afterAll {
40
	[super afterAll];
41
	// at the end of tests, go back to chat rooms to display main bar
42
	[self goBackFromChat];
43
	ASSERT_EQ([LinphoneManager instance].fileTransferDelegates.count, 0)
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
44 45
}

46 47
#pragma mark - tools

48 49 50
- (void)dismissKeyboard {
	[tester tapScreenAtPoint:CGPointMake(0, 0)]; // dismiss keyboard, if any
}
51
- (void)goBackFromChat {
52 53 54 55
	[self dismissKeyboard];
	if ([tester tryFindingTappableViewWithAccessibilityLabel:@"Back" error:nil]) {
		[tester tapViewWithAccessibilityLabel:@"Back"];
	}
56 57
}

58
- (void)startChatWith:(NSString *)user {
59 60 61 62 63
	[tester tapViewWithAccessibilityLabel:@"New discussion"];
	[tester clearTextFromFirstResponder];
	[tester enterTextIntoCurrentFirstResponder:user];
	[tester tapRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
		inTableViewWithAccessibilityIdentifier:@"Suggested addresses"];
64 65
}

66
- (void)sendMessage:(NSString *)message {
67
	[tester enterText:message.uppercaseString intoViewWithAccessibilityLabel:@"Message field"];
68
	[tester tapViewWithAccessibilityLabel:@"Send"];
69 70
}

71
- (void)uploadImageWithQuality:(NSString *)quality {
72
	static int ind = 0;
73 74
	[tester tapViewWithAccessibilityLabel:@"Send picture"];
	[tester tapViewWithAccessibilityLabel:@"Photo library"];
75
// if popup "Linphone would access your photo" pops up, click OK.
76
#if TARGET_IPHONE_SIMULATOR
77
	if ([tester acknowledgeSystemAlert]) {
78 79
		[tester waitForTimeInterval:1];
	}
80
#endif
81

82 83 84 85 86
	// select random photo to avoid having the same multiple times.
	// There are 9 photos by default, so lets use just 8 (2 rows, 4 columns).
	LOGI(@"Selecting photo at row %d, column %d", 1 + (ind / 4) % 2, 1 + ind % 4);
	[tester choosePhotoInAlbum:@"Camera Roll" atRow:1 + (ind / 4) % 2 column:1 + ind % 4];
	ind++;
87
	[[UIApplication sharedApplication] writeScreenshotForLine:__LINE__ inFile:@__FILE__ description:nil error:NULL];
88

89
	// wait for the quality popup to show up
90 91 92 93 94 95 96
	UIAccessibilityElement *element = nil;
	float timeout = 10;
	while (!element && timeout > 0.f) {
		[tester waitForTimeInterval:.5];
		timeout -= .5f;
		element =
			[[UIApplication sharedApplication] accessibilityElementMatchingBlock:^BOOL(UIAccessibilityElement *e) {
97
			  return [e.accessibilityLabel containsSubstring:quality];
98 99 100
			}];
	}
	XCTAssertNotNil(element);
101
	[tester tapViewWithAccessibilityLabel:element.accessibilityLabel];
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
102 103
}

104
- (void)downloadImageWithQuality:(NSString *)quality {
105
	[self startChatWith:[self me]];
106
	[self uploadImageWithQuality:quality];
107
	// wait for the upload to terminate...
108
	for (int i = 0; i < 180; i++) {
109
		[tester waitForTimeInterval:1.f];
110
		if (LinphoneManager.instance.fileTransferDelegates.count == 0)
111 112 113 114
			break;
	}
	[tester waitForViewWithAccessibilityLabel:@"Download"];
	[tester tapViewWithAccessibilityLabel:@"Download"];
115
	[tester waitForTimeInterval:.1f]; // just wait a few msecs to start download
116
	ASSERT_EQ(LinphoneManager.instance.fileTransferDelegates.count, 1);
117
}
118

119
#pragma mark - tests
120

121
- (void)testChatFromContactPhoneNumber {
122
	[tester tapViewWithAccessibilityLabel:@"Contacts"];
123 124 125 126
	NSString *name = [UIDevice.currentDevice.identifierForVendor.UUIDString
		substringFromIndex:UIDevice.currentDevice.identifierForVendor.UUIDString.length - 6];
	NSString *fullName = [NSString stringWithFormat:@"Anna %@", name];
	[self createContact:@"Anna" lastName:name phoneNumber:@"555-522-8243" SIPAddress:nil];
127 128 129 130

	[tester tapViewWithAccessibilityLabel:@"Back"];
	[tester tapViewWithAccessibilityLabel:@"All contacts filter"];
	[tester tapViewWithAccessibilityLabel:fullName];
131
	[tester tapViewWithAccessibilityLabel:@"Chat with 5555228243"];
132
	[self goBackFromChat];
133
	UITableView *tv = [self findTableView:@"Chat list"];
134 135
	ASSERT_EQ([tv numberOfRowsInSection:0], 1);
	[tester waitForViewWithAccessibilityLabel:@"Contact name, Message"
136
										value:[NSString stringWithFormat:@"%@ (0)", fullName]
137
									   traits:UIAccessibilityTraitStaticText];
138 139
}

140 141 142 143
- (void)testInvalidSIPAddress {
	[self startChatWith:@"sip://toto"];

	[tester waitForViewWithAccessibilityLabel:@"Invalid address" traits:UIAccessibilityTraitStaticText];
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
144
	[tester tapViewWithAccessibilityLabel:@"OK"];
145
}
146

147
- (void)testMessageRemoval {
148 149 150 151
	NSString *user = [self getUUID];

	[self startChatWith:user];
	[self sendMessage:user];
152 153
	[tester waitForViewWithAccessibilityLabel:@"Delivery failed" traits:UIAccessibilityTraitImage];
	[self dismissKeyboard];
154 155

	[tester tapViewWithAccessibilityLabel:@"Edit" traits:UIAccessibilityTraitButton];
156 157 158 159
	[tester waitForViewWithAccessibilityLabel:@"Checkbox" value:@"Deselected" traits:UIAccessibilityTraitButton];
	[tester tapRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
		inTableViewWithAccessibilityIdentifier:@"ChatRoom list"];
	[tester waitForViewWithAccessibilityLabel:@"Checkbox" value:@"Selected" traits:UIAccessibilityTraitButton];
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
160 161
	[tester tapViewWithAccessibilityLabel:@"Delete all"];
	[tester tapViewWithAccessibilityLabel:@"DELETE" traits:UIAccessibilityTraitButton];
162 163

	// check that the tableview is empty
164 165
	UITableView *tv = [self findTableView:@"ChatRoom list"];
	ASSERT_EQ([tv numberOfRowsInSection:0], 0); // no more messages
166 167

	[self goBackFromChat];
168 169
}

170 171 172 173 174 175
- (void)testPerformanceHugeChatList {
	[tester tapViewWithAccessibilityLabel:@"Dialer"];

	// create lots of chat rooms...
	LinphoneCore *lc = [LinphoneManager getLc];
	for (int i = 0; i < 100; i++) {
176
		linphone_core_get_chat_room_from_uri(lc, [[NSString stringWithFormat:@"%@ - %d", [self me], i] UTF8String]);
177 178 179 180 181 182
	}

	NSTimeInterval before = [[NSDate date] timeIntervalSince1970];
	[tester tapViewWithAccessibilityLabel:@"Chat"];
	NSTimeInterval after = [[NSDate date] timeIntervalSince1970];

183
	XCTAssertEqual([[self findTableView:@"Chat list"] numberOfRowsInSection:0], 100);
184 185 186 187 188
	// conversation loading MUST be less than 1 sec
	XCTAssertLessThan(after - before, 1.);
}

- (void)testPerformanceHugeConversation {
189
	size_t count = 0;
190 191
	LinphoneCore *lc = [LinphoneManager getLc];
	LinphoneChatRoom *room = linphone_core_get_chat_room_from_uri(lc, [[self me] UTF8String]);
192 193 194 195 196 197

	NSTimeInterval beforeEmpty = [[NSDate date] timeIntervalSince1970];
	[self startChatWith:[self me]];
	NSTimeInterval afterEmpty = [[NSDate date] timeIntervalSince1970];
	[self goBackFromChat];

198
	// generate lots of messages...
199
	for (; count < 50; count++) {
200
		LinphoneChatMessage *msg =
201
			linphone_chat_room_create_message(room, [[NSString stringWithFormat:@"Message %lu", count + 1] UTF8String]);
202
		linphone_chat_room_send_chat_message(room, msg);
203
	}
204

205 206 207
	for (int i = 0; i < 50; i++) {
		[tester waitForTimeInterval:.5f];

208
		if (bctbx_list_size(linphone_chat_room_get_history_events(room, 0)) == count) {
209 210 211 212
			break;
		}
	}

213 214 215 216
	[tester
		waitForViewWithAccessibilityLabel:@"Contact name, Message"
									value:[NSString stringWithFormat:@"%@, Message %lu (%lu)", self.me, count, count]
								   traits:UIAccessibilityTraitStaticText];
217 218

	NSTimeInterval before = [[NSDate date] timeIntervalSince1970];
219 220
	[tester tapRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
		inTableViewWithAccessibilityIdentifier:@"Chat list"];
221 222
	NSTimeInterval after = [[NSDate date] timeIntervalSince1970];

223 224
	// conversation loading MUST be less than 1 sec - loading messages only
	XCTAssertLessThan(after - before, afterEmpty - beforeEmpty + 1.);
225 226
}

227
- (void)testRemoveAllChats {
228
	NSArray *uuids = [self getUUIDArrayOfSize:3];
229 230 231 232 233 234 235

	for (NSString *uuid in uuids) {
		[self startChatWith:uuid];
		[self sendMessage:@"Test"];
		[self goBackFromChat];
	}

236
	UITableView *tv = [self findTableView:@"Chat list"];
237

238
	ASSERT_EQ([tv numberOfRowsInSection:0], uuids.count);
239

240
	[self removeAllRooms];
241 242

	// check that the tableview is empty
243
	ASSERT_EQ([tv numberOfRowsInSection:0], 0);
244 245

	// test that there's no more chatrooms in the core
246
	ASSERT_EQ(linphone_core_get_chat_rooms([LinphoneManager getLc]), NULL);
247 248
}

249 250
- (void)testSendMessageToMyself {
	[self startChatWith:[self me]];
251

252 253 254
	[self sendMessage:@"HELLO"];
	[tester waitForViewWithAccessibilityLabel:@"Outgoing message" value:@"HELLO" traits:UIAccessibilityTraitStaticText];
	[tester waitForViewWithAccessibilityLabel:@"Incoming message" value:@"HELLO" traits:UIAccessibilityTraitStaticText];
255
	[tester waitForAbsenceOfViewWithAccessibilityLabel:@"Message status"];
256

257 258 259 260 261 262 263 264 265 266 267
	[self goBackFromChat];
}

- (void)testSendToSIPAddress {
	NSString *sipAddr = [NSString stringWithFormat:@"sip:%@@%@", [self me], [self accountDomain]];

	[self startChatWith:sipAddr];

	[tester waitForViewWithAccessibilityLabel:@"Contact name" value:[self me] traits:0];

	[self goBackFromChat];
268 269
}

270
- (void)testTransferCancelDownloadImage {
271
	[self downloadImageWithQuality:@"Maximum"];
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
	[tester tapViewWithAccessibilityLabel:@"Cancel"];
	ASSERT_EQ([[[LinphoneManager instance] fileTransferDelegates] count], 0);
}

- (void)testTransferCancelUploadImage {
	[self startChatWith:[self me]];
	[self uploadImageWithQuality:@"Minimum"];
	[tester tapViewWithAccessibilityLabel:@"Cancel"];
	ASSERT_EQ([[[LinphoneManager instance] fileTransferDelegates] count], 0);
}

- (void)testTransferDestroyRoomWhileUploading {
	[self startChatWith:[self me]];
	[self uploadImageWithQuality:@"Maximum"];
	[self goBackFromChat];
	[self removeAllRooms];
}

- (void)testTransferDownloadImage {
291
	[self downloadImageWithQuality:@"Minimum"];
292 293 294 295 296
	[tester waitForAbsenceOfViewWithAccessibilityLabel:@"Cancel"];
	ASSERT_EQ([[[LinphoneManager instance] fileTransferDelegates] count], 0);
}

- (void)testTransferSimultanouslyDownload {
297 298
// wait for bugfix
#if 0
299
	[self startChatWith:[self me]];
300
	[self uploadImageWithQuality:@"Minimum"];
301
	[self uploadImageWithQuality:@"Minimum"];
302
	UITableView *tv = [self findTableView:@"ChatRoom list"];
303
	int timeout = 3;
304
	// wait for ALL uploads to terminate...
305
	for (int i = 0; i < 90; i++) {
306
		[tester waitForTimeInterval:1.f];
307
		if ([tv numberOfRowsInSection:0] == 4)
308 309 310 311
			break;
	}
	[tester waitForTimeInterval:.5f];
	ASSERT_EQ([[LinphoneManager instance] fileTransferDelegates].count, 0);
312
	[tester scrollViewWithAccessibilityIdentifier:@"ChatRoom list" byFractionOfSizeHorizontal:0.f vertical:1.f];
313
	for (int i = 0; i < 2; i++) {
314
		// messages order is not known: if upload bitrate is huge, first image can be uploaded before last started
315
		timeout = 3;
316
		while (![tester tryFindingTappableViewWithAccessibilityLabel:@"Download" error:nil] && timeout) {
317 318 319
			[tester scrollViewWithAccessibilityIdentifier:@"ChatRoom list"
							   byFractionOfSizeHorizontal:0.f
												 vertical:-.1f];
320
			timeout--;
321 322 323 324 325
		}
		[tester waitForViewWithAccessibilityLabel:@"Download"];
		[tester tapViewWithAccessibilityLabel:@"Download"];
		[tester waitForTimeInterval:.2f]; // just wait a few secs to start download
	}
326 327
	timeout = 30;
	while ([LinphoneManager instance].fileTransferDelegates.count > 0 && timeout) {
328
		[tester waitForTimeInterval:.5];
329
		timeout--;
330 331
	}
	[self goBackFromChat];
332
#endif
333 334
}

Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
335
@end