OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #import <EarlGrey/EarlGrey.h> |
| 6 #import <UIKit/UIKit.h> |
| 7 #import <XCTest/XCTest.h> |
| 8 |
| 9 #include "base/mac/scoped_nsobject.h" |
| 10 #include "base/strings/sys_string_conversions.h" |
| 11 #include "components/reading_list/ios/reading_list_model.h" |
| 12 #include "ios/chrome/browser/reading_list/reading_list_model_factory.h" |
| 13 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" |
| 14 #include "ios/chrome/browser/ui/commands/ios_command_ids.h" |
| 15 #include "ios/chrome/grit/ios_strings.h" |
| 16 #import "ios/chrome/test/app/chrome_test_util.h" |
| 17 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" |
| 18 #import "ios/chrome/test/earl_grey/chrome_matchers.h" |
| 19 #import "ios/chrome/test/earl_grey/chrome_test_case.h" |
| 20 #import "ios/testing/wait_util.h" |
| 21 |
| 22 namespace { |
| 23 const char kReadTitle[] = "foobar"; |
| 24 const char kReadURL[] = "http://readfoobar.com"; |
| 25 const char kUnreadTitle[] = "I am an unread entry"; |
| 26 const char kUnreadURL[] = "http://unreadfoobar.com"; |
| 27 const char kReadURL2[] = "http://kReadURL2.com"; |
| 28 const char kReadTitle2[] = "read item 2"; |
| 29 const char kUnreadTitle2[] = "I am another unread entry"; |
| 30 const char kUnreadURL2[] = "http://unreadfoobar2.com"; |
| 31 const size_t kNumberReadEntries = 2; |
| 32 const size_t kNumberUnreadEntries = 2; |
| 33 const char kReadHeader[] = "Read"; |
| 34 const char kUnreadHeader[] = "Unread"; |
| 35 |
| 36 // Returns the reading list model. |
| 37 ReadingListModel* GetReadingListModel() { |
| 38 ReadingListModel* model = |
| 39 ReadingListModelFactory::GetInstance()->GetForBrowserState( |
| 40 chrome_test_util::GetOriginalBrowserState()); |
| 41 GREYAssert(testing::WaitUntilConditionOrTimeout(2, |
| 42 ^{ |
| 43 return model->loaded(); |
| 44 }), |
| 45 @"Reading List model did not load"); |
| 46 return model; |
| 47 } |
| 48 |
| 49 // Asserts the |button_id| button is not visible. |
| 50 void AssertButtonNotVisibleWithID(int button_id) { |
| 51 [[EarlGrey |
| 52 selectElementWithMatcher:chrome_test_util::buttonWithAccessibilityLabelId( |
| 53 button_id)] |
| 54 assertWithMatcher:grey_notVisible()]; |
| 55 } |
| 56 |
| 57 // Assert the |button_id| button is visible. |
| 58 void AssertButtonVisibleWithID(int button_id) { |
| 59 [[EarlGrey |
| 60 selectElementWithMatcher:chrome_test_util::buttonWithAccessibilityLabelId( |
| 61 button_id)] |
| 62 assertWithMatcher:grey_sufficientlyVisible()]; |
| 63 } |
| 64 |
| 65 // Taps the |button_id| button. |
| 66 void TapButtonWithID(int button_id) { |
| 67 [[EarlGrey |
| 68 selectElementWithMatcher:chrome_test_util::buttonWithAccessibilityLabelId( |
| 69 button_id)] performAction:grey_tap()]; |
| 70 } |
| 71 |
| 72 // Taps the entry |title|. |
| 73 void TapEntry(std::string title) { |
| 74 [[EarlGrey selectElementWithMatcher: |
| 75 grey_allOf(chrome_test_util::staticTextWithAccessibilityLabel( |
| 76 base::SysUTF8ToNSString(title)), |
| 77 grey_sufficientlyVisible(), nil)] |
| 78 performAction:grey_tap()]; |
| 79 } |
| 80 |
| 81 // Asserts that the entry |title| is visible. |
| 82 void AssertEntryVisible(std::string title) { |
| 83 [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; |
| 84 [[EarlGrey selectElementWithMatcher: |
| 85 grey_allOf(chrome_test_util::staticTextWithAccessibilityLabel( |
| 86 base::SysUTF8ToNSString(title)), |
| 87 grey_sufficientlyVisible(), nil)] |
| 88 assertWithMatcher:grey_sufficientlyVisible()]; |
| 89 } |
| 90 |
| 91 // Asserts that all the entries are visible. |
| 92 void AssertAllEntriesVisible() { |
| 93 AssertEntryVisible(kReadTitle); |
| 94 AssertEntryVisible(kReadTitle2); |
| 95 AssertEntryVisible(kUnreadTitle); |
| 96 AssertEntryVisible(kUnreadTitle2); |
| 97 |
| 98 // If the number of entries changes, make sure this assert gets updated. |
| 99 GREYAssertEqual((size_t)2, kNumberReadEntries, |
| 100 @"The number of entries have changed"); |
| 101 GREYAssertEqual((size_t)2, kNumberUnreadEntries, |
| 102 @"The number of entries have changed"); |
| 103 } |
| 104 |
| 105 // Asserts that the entry |title| is not visible. |
| 106 void AssertEntryNotVisible(std::string title) { |
| 107 [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; |
| 108 [[EarlGrey selectElementWithMatcher: |
| 109 grey_allOf(chrome_test_util::staticTextWithAccessibilityLabel( |
| 110 base::SysUTF8ToNSString(title)), |
| 111 grey_sufficientlyVisible(), nil)] |
| 112 assertWithMatcher:grey_notVisible()]; |
| 113 } |
| 114 |
| 115 // Asserts |header| is visible. |
| 116 void AssertHeaderNotVisible(std::string header) { |
| 117 [[EarlGrey selectElementWithMatcher:chrome_test_util:: |
| 118 staticTextWithAccessibilityLabel( |
| 119 base::SysUTF8ToNSString(header))] |
| 120 assertWithMatcher:grey_notVisible()]; |
| 121 } |
| 122 |
| 123 // Opens the reading list menu using command line. |
| 124 void OpenReadingList() { |
| 125 base::scoped_nsobject<GenericChromeCommand> command( |
| 126 [[GenericChromeCommand alloc] initWithTag:IDC_SHOW_READING_LIST]); |
| 127 chrome_test_util::RunCommandWithActiveViewController(command); |
| 128 } |
| 129 |
| 130 // Adds a read and an unread entry to the model, opens the reading list menu and |
| 131 // enter edit mode. |
| 132 void AddEntriesAndEnterEdit() { |
| 133 ReadingListModel* model = GetReadingListModel(); |
| 134 model->AddEntry(GURL(kReadURL), std::string(kReadTitle)); |
| 135 model->SetReadStatus(GURL(kReadURL), true); |
| 136 model->AddEntry(GURL(kReadURL2), std::string(kReadTitle2)); |
| 137 model->SetReadStatus(GURL(kReadURL2), true); |
| 138 model->AddEntry(GURL(kUnreadURL), std::string(kUnreadTitle)); |
| 139 model->AddEntry(GURL(kUnreadURL2), std::string(kUnreadTitle2)); |
| 140 OpenReadingList(); |
| 141 |
| 142 TapButtonWithID(IDS_IOS_READING_LIST_EDIT_BUTTON); |
| 143 } |
| 144 |
| 145 // Computes the number of read entries in the model. |
| 146 size_t ModelReadSize(ReadingListModel* model) { |
| 147 size_t size = 0; |
| 148 for (const auto& url : model->Keys()) { |
| 149 if (model->GetEntryByURL(url)->IsRead()) { |
| 150 size++; |
| 151 } |
| 152 } |
| 153 return size; |
| 154 } |
| 155 } // namespace |
| 156 |
| 157 // Test class for the Reading List menu. |
| 158 @interface ReadingListTestCase : ChromeTestCase |
| 159 |
| 160 @end |
| 161 |
| 162 @implementation ReadingListTestCase |
| 163 |
| 164 - (void)setUp { |
| 165 [super setUp]; |
| 166 ReadingListModel* model = GetReadingListModel(); |
| 167 for (const GURL& url : model->Keys()) |
| 168 model->RemoveEntryByURL(url); |
| 169 } |
| 170 |
| 171 // Tests that only the "Edit" button is showing when not editing. |
| 172 - (void)testVisibleButtonsNonEditingMode { |
| 173 GetReadingListModel()->AddEntry(GURL(kUnreadURL), std::string(kUnreadTitle)); |
| 174 OpenReadingList(); |
| 175 |
| 176 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_DELETE_BUTTON); |
| 177 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_DELETE_ALL_READ_BUTTON); |
| 178 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_READ_BUTTON); |
| 179 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_UNREAD_BUTTON); |
| 180 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_ALL_BUTTON); |
| 181 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_BUTTON); |
| 182 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_CANCEL_BUTTON); |
| 183 AssertButtonVisibleWithID(IDS_IOS_READING_LIST_EDIT_BUTTON); |
| 184 } |
| 185 |
| 186 // Tests that only the "Cancel", "Delete All Read" and "Mark All…" buttons are |
| 187 // showing when not editing. |
| 188 - (void)testVisibleButtonsEditingModeEmptySelection { |
| 189 AddEntriesAndEnterEdit(); |
| 190 |
| 191 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_DELETE_BUTTON); |
| 192 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_READ_BUTTON); |
| 193 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_UNREAD_BUTTON); |
| 194 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_BUTTON); |
| 195 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_EDIT_BUTTON); |
| 196 AssertButtonVisibleWithID(IDS_IOS_READING_LIST_DELETE_ALL_READ_BUTTON); |
| 197 AssertButtonVisibleWithID(IDS_IOS_READING_LIST_MARK_ALL_BUTTON); |
| 198 AssertButtonVisibleWithID(IDS_IOS_READING_LIST_CANCEL_BUTTON); |
| 199 } |
| 200 |
| 201 // Tests that only the "Cancel", "Delete" and "Mark Unread" buttons are showing |
| 202 // when not editing. |
| 203 - (void)testVisibleButtonsOnlyReadEntrySelected { |
| 204 AddEntriesAndEnterEdit(); |
| 205 TapEntry(kReadTitle); |
| 206 |
| 207 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_DELETE_ALL_READ_BUTTON); |
| 208 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_READ_BUTTON); |
| 209 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_BUTTON); |
| 210 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_EDIT_BUTTON); |
| 211 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_ALL_BUTTON); |
| 212 AssertButtonVisibleWithID(IDS_IOS_READING_LIST_MARK_UNREAD_BUTTON); |
| 213 AssertButtonVisibleWithID(IDS_IOS_READING_LIST_DELETE_BUTTON); |
| 214 AssertButtonVisibleWithID(IDS_IOS_READING_LIST_CANCEL_BUTTON); |
| 215 } |
| 216 |
| 217 // Tests that only the "Cancel", "Delete" and "Mark Read" buttons are showing |
| 218 // when not editing. |
| 219 - (void)testVisibleButtonsOnlyUnreadEntrySelected { |
| 220 AddEntriesAndEnterEdit(); |
| 221 TapEntry(kUnreadTitle); |
| 222 |
| 223 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_DELETE_ALL_READ_BUTTON); |
| 224 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_UNREAD_BUTTON); |
| 225 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_BUTTON); |
| 226 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_EDIT_BUTTON); |
| 227 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_ALL_BUTTON); |
| 228 AssertButtonVisibleWithID(IDS_IOS_READING_LIST_MARK_READ_BUTTON); |
| 229 AssertButtonVisibleWithID(IDS_IOS_READING_LIST_DELETE_BUTTON); |
| 230 AssertButtonVisibleWithID(IDS_IOS_READING_LIST_CANCEL_BUTTON); |
| 231 } |
| 232 |
| 233 // Tests that only the "Cancel", "Delete" and "Mark…" buttons are showing when |
| 234 // not editing. |
| 235 - (void)testVisibleButtonsMixedEntriesSelected { |
| 236 AddEntriesAndEnterEdit(); |
| 237 TapEntry(kReadTitle); |
| 238 TapEntry(kUnreadTitle); |
| 239 |
| 240 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_DELETE_ALL_READ_BUTTON); |
| 241 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_UNREAD_BUTTON); |
| 242 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_READ_BUTTON); |
| 243 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_EDIT_BUTTON); |
| 244 AssertButtonNotVisibleWithID(IDS_IOS_READING_LIST_MARK_ALL_BUTTON); |
| 245 AssertButtonVisibleWithID(IDS_IOS_READING_LIST_MARK_BUTTON); |
| 246 AssertButtonVisibleWithID(IDS_IOS_READING_LIST_DELETE_BUTTON); |
| 247 AssertButtonVisibleWithID(IDS_IOS_READING_LIST_CANCEL_BUTTON); |
| 248 } |
| 249 |
| 250 // Tests the deletion of selected entries. |
| 251 - (void)testDeleteEntries { |
| 252 AddEntriesAndEnterEdit(); |
| 253 |
| 254 TapEntry(kReadTitle2); |
| 255 |
| 256 TapButtonWithID(IDS_IOS_READING_LIST_DELETE_BUTTON); |
| 257 |
| 258 AssertEntryVisible(kReadTitle); |
| 259 AssertEntryNotVisible(kReadTitle2); |
| 260 AssertEntryVisible(kUnreadTitle); |
| 261 AssertEntryVisible(kUnreadTitle2); |
| 262 XCTAssertEqual(kNumberReadEntries - 1, ModelReadSize(GetReadingListModel())); |
| 263 XCTAssertEqual(kNumberUnreadEntries, GetReadingListModel()->unread_size()); |
| 264 } |
| 265 |
| 266 // Tests the deletion of all read entries. |
| 267 - (void)testDeleteAllReadEntries { |
| 268 AddEntriesAndEnterEdit(); |
| 269 |
| 270 TapButtonWithID(IDS_IOS_READING_LIST_DELETE_ALL_READ_BUTTON); |
| 271 |
| 272 AssertEntryNotVisible(kReadTitle); |
| 273 AssertEntryNotVisible(kReadTitle2); |
| 274 AssertHeaderNotVisible(kReadHeader); |
| 275 AssertEntryVisible(kUnreadTitle); |
| 276 AssertEntryVisible(kUnreadTitle2); |
| 277 XCTAssertEqual((size_t)0, ModelReadSize(GetReadingListModel())); |
| 278 XCTAssertEqual(kNumberUnreadEntries, GetReadingListModel()->unread_size()); |
| 279 } |
| 280 |
| 281 // Marks all unread entries as read. |
| 282 - (void)testMarkAllRead { |
| 283 AddEntriesAndEnterEdit(); |
| 284 |
| 285 TapButtonWithID(IDS_IOS_READING_LIST_MARK_ALL_BUTTON); |
| 286 |
| 287 // Tap the action sheet. |
| 288 TapButtonWithID(IDS_IOS_READING_LIST_MARK_ALL_READ_ACTION); |
| 289 |
| 290 AssertHeaderNotVisible(kUnreadHeader); |
| 291 AssertAllEntriesVisible(); |
| 292 XCTAssertEqual(kNumberUnreadEntries + kNumberReadEntries, |
| 293 ModelReadSize(GetReadingListModel())); |
| 294 XCTAssertEqual((size_t)0, GetReadingListModel()->unread_size()); |
| 295 } |
| 296 |
| 297 // Marks all read entries as unread. |
| 298 - (void)testMarkAllUnread { |
| 299 AddEntriesAndEnterEdit(); |
| 300 |
| 301 TapButtonWithID(IDS_IOS_READING_LIST_MARK_ALL_BUTTON); |
| 302 |
| 303 // Tap the action sheet. |
| 304 TapButtonWithID(IDS_IOS_READING_LIST_MARK_ALL_UNREAD_ACTION); |
| 305 |
| 306 AssertHeaderNotVisible(kReadHeader); |
| 307 AssertAllEntriesVisible(); |
| 308 XCTAssertEqual(kNumberUnreadEntries + kNumberReadEntries, |
| 309 GetReadingListModel()->unread_size()); |
| 310 XCTAssertEqual((size_t)0, ModelReadSize(GetReadingListModel())); |
| 311 } |
| 312 |
| 313 // Selects an unread entry and mark it as read. |
| 314 - (void)testMarkEntriesRead { |
| 315 AddEntriesAndEnterEdit(); |
| 316 TapEntry(kUnreadTitle); |
| 317 |
| 318 TapButtonWithID(IDS_IOS_READING_LIST_MARK_READ_BUTTON); |
| 319 |
| 320 AssertAllEntriesVisible(); |
| 321 XCTAssertEqual(kNumberReadEntries + 1, ModelReadSize(GetReadingListModel())); |
| 322 XCTAssertEqual(kNumberUnreadEntries - 1, |
| 323 GetReadingListModel()->unread_size()); |
| 324 } |
| 325 |
| 326 // Selects an read entry and mark it as unread. |
| 327 - (void)testMarkEntriesUnread { |
| 328 AddEntriesAndEnterEdit(); |
| 329 TapEntry(kReadTitle); |
| 330 |
| 331 TapButtonWithID(IDS_IOS_READING_LIST_MARK_UNREAD_BUTTON); |
| 332 |
| 333 AssertAllEntriesVisible(); |
| 334 XCTAssertEqual(kNumberReadEntries - 1, ModelReadSize(GetReadingListModel())); |
| 335 XCTAssertEqual(kNumberUnreadEntries + 1, |
| 336 GetReadingListModel()->unread_size()); |
| 337 } |
| 338 |
| 339 // Selects read and unread entries and mark them as unread. |
| 340 - (void)testMarkMixedEntriesUnread { |
| 341 AddEntriesAndEnterEdit(); |
| 342 TapEntry(kReadTitle); |
| 343 TapEntry(kUnreadTitle); |
| 344 |
| 345 TapButtonWithID(IDS_IOS_READING_LIST_MARK_BUTTON); |
| 346 |
| 347 // Tap the action sheet. |
| 348 TapButtonWithID(IDS_IOS_READING_LIST_MARK_UNREAD_BUTTON); |
| 349 |
| 350 AssertAllEntriesVisible(); |
| 351 XCTAssertEqual(kNumberReadEntries - 1, ModelReadSize(GetReadingListModel())); |
| 352 XCTAssertEqual(kNumberUnreadEntries + 1, |
| 353 GetReadingListModel()->unread_size()); |
| 354 } |
| 355 |
| 356 // Selects read and unread entries and mark them as read. |
| 357 - (void)testMarkMixedEntriesRead { |
| 358 AddEntriesAndEnterEdit(); |
| 359 TapEntry(kReadTitle); |
| 360 TapEntry(kUnreadTitle); |
| 361 |
| 362 TapButtonWithID(IDS_IOS_READING_LIST_MARK_BUTTON); |
| 363 |
| 364 // Tap the action sheet. |
| 365 TapButtonWithID(IDS_IOS_READING_LIST_MARK_READ_BUTTON); |
| 366 |
| 367 AssertAllEntriesVisible(); |
| 368 XCTAssertEqual(kNumberReadEntries + 1, ModelReadSize(GetReadingListModel())); |
| 369 XCTAssertEqual(kNumberUnreadEntries - 1, |
| 370 GetReadingListModel()->unread_size()); |
| 371 } |
| 372 |
| 373 @end |
OLD | NEW |