Chromium Code Reviews| Index: ios/chrome/browser/ui/reading_list/reading_list_egtest.mm |
| diff --git a/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm b/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm |
| index 6195877d983dcc15e856d8604c9b76256d74b725..9a2095d98476f9216539debaed20e1e4efa74352 100644 |
| --- a/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm |
| +++ b/ios/chrome/browser/ui/reading_list/reading_list_egtest.mm |
| @@ -6,8 +6,10 @@ |
| #import <UIKit/UIKit.h> |
| #import <XCTest/XCTest.h> |
| +#include "base/memory/ptr_util.h" |
| #include "base/strings/sys_string_conversions.h" |
| #include "base/strings/utf_string_conversions.h" |
| +#include "base/test/ios/wait_util.h" |
| #include "components/reading_list/ios/reading_list_model.h" |
| #include "ios/chrome/browser/reading_list/reading_list_model_factory.h" |
| #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" |
| @@ -18,6 +20,8 @@ |
| #include "ios/chrome/grit/ios_strings.h" |
| #include "ios/chrome/grit/ios_theme_resources.h" |
| #import "ios/chrome/test/app/chrome_test_util.h" |
| +#include "ios/chrome/test/app/navigation_test_util.h" |
| +#import "ios/chrome/test/app/tab_test_util.h" |
| #import "ios/chrome/test/earl_grey/accessibility_util.h" |
| #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" |
| #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" |
| @@ -25,8 +29,12 @@ |
| #import "ios/chrome/test/earl_grey/chrome_test_case.h" |
| #import "ios/testing/wait_util.h" |
| #import "ios/third_party/material_components_ios/src/components/Snackbar/src/MaterialSnackbar.h" |
| +#import "ios/web/public/navigation_manager.h" |
| +#import "ios/web/public/reload_type.h" |
| #import "ios/web/public/test/http_server.h" |
| #import "ios/web/public/test/http_server_util.h" |
| +#import "ios/web/public/test/response_providers/delayed_response_provider.h" |
| +#import "ios/web/public/test/response_providers/html_response_provider.h" |
| #if !defined(__has_feature) || !__has_feature(objc_arc) |
| #error "This file requires ARC support." |
| @@ -46,6 +54,7 @@ const size_t kNumberUnreadEntries = 2; |
| const CFTimeInterval kSnackbarAppearanceTimeout = 5; |
| const CFTimeInterval kSnackbarDisappearanceTimeout = |
| MDCSnackbarMessageDurationMax + 1; |
| +const CFTimeInterval kLoadOfflineTimeout = 5; |
| const CFTimeInterval kLongPressDuration = 1.0; |
| const char kReadHeader[] = "Read"; |
| const char kUnreadHeader[] = "Unread"; |
| @@ -201,6 +210,40 @@ id<GREYMatcher> EmptyBackground() { |
| return grey_accessibilityID( |
| [ReadingListEmptyCollectionBackground accessibilityIdentifier]); |
| } |
| + |
| +// Adds an the current page to the Reading List. |
| +void AddCurrentPageToReadingList() { |
| + // Add the page to the reading list. |
| + [ChromeEarlGreyUI openShareMenu]; |
| + TapButtonWithID(IDS_IOS_SHARE_MENU_READING_LIST_ACTION); |
| + |
| + // Wait for the snackbar to appear. |
| + id<GREYMatcher> snackbarMatcher = |
| + chrome_test_util::ButtonWithAccessibilityLabelId( |
| + IDS_IOS_READING_LIST_SNACKBAR_MESSAGE); |
| + ConditionBlock waitForAppearance = ^{ |
| + NSError* error = nil; |
| + [[EarlGrey selectElementWithMatcher:snackbarMatcher] |
| + assertWithMatcher:grey_notNil() |
| + error:&error]; |
| + return error == nil; |
| + }; |
| + GREYAssert(testing::WaitUntilConditionOrTimeout(kSnackbarAppearanceTimeout, |
| + waitForAppearance), |
| + @"Snackbar did not appear."); |
| + |
| + // Wait for the snackbar to disappear. |
| + ConditionBlock waitForDisappearance = ^{ |
| + NSError* error = nil; |
| + [[EarlGrey selectElementWithMatcher:snackbarMatcher] |
| + assertWithMatcher:grey_nil() |
| + error:&error]; |
| + return error == nil; |
| + }; |
| + GREYAssert(testing::WaitUntilConditionOrTimeout(kSnackbarDisappearanceTimeout, |
| + waitForDisappearance), |
| + @"Snackbar did not disappear."); |
| +} |
| } // namespace |
| // Test class for the Reading List menu. |
| @@ -217,6 +260,14 @@ id<GREYMatcher> EmptyBackground() { |
| model->RemoveEntryByURL(url); |
| } |
| +- (void)tearDown { |
| + web::test::HttpServer& server = web::test::HttpServer::GetSharedInstance(); |
| + if (!server.IsRunning()) { |
| + server.StartOrDie(); |
| + } |
| + [super tearDown]; |
| +} |
| + |
| // Tests that the Reading List view is accessible. |
| - (void)testAccessibility { |
| AddEntriesAndEnterEdit(); |
| @@ -228,13 +279,14 @@ id<GREYMatcher> EmptyBackground() { |
| // Tests that sharing a web page to the Reading List results in a snackbar |
| // appearing, and that the Reading List entry is present in the Reading List. |
| -- (void)testSavingToReadingList { |
| +// Loads offline version via context menu. |
| +- (void)testSavingToReadingListAndLoadDistilled { |
| // Setup a server serving a distillable page at http://potato with the title |
| // "tomato", and a non distillable page at http://beans |
| std::map<GURL, std::string> responses; |
| + std::string pageTitle = "Tomato"; |
| const GURL distillablePageURL = |
| web::test::HttpServer::MakeUrl("http://potato"); |
| - std::string pageTitle = "tomato"; |
| std::string contentToRemove = "Text that distillation should remove."; |
| std::string contentToKeep = "Text that distillation should keep."; |
| @@ -253,36 +305,7 @@ id<GREYMatcher> EmptyBackground() { |
| // Open http://potato |
| [ChromeEarlGrey loadURL:distillablePageURL]; |
| - // Add the page to the reading list. |
| - [ChromeEarlGreyUI openShareMenu]; |
| - TapButtonWithID(IDS_IOS_SHARE_MENU_READING_LIST_ACTION); |
| - |
| - // Wait for the snackbar to appear. |
| - id<GREYMatcher> snackbarMatcher = |
| - chrome_test_util::ButtonWithAccessibilityLabelId( |
| - IDS_IOS_READING_LIST_SNACKBAR_MESSAGE); |
| - ConditionBlock waitForAppearance = ^{ |
| - NSError* error = nil; |
| - [[EarlGrey selectElementWithMatcher:snackbarMatcher] |
| - assertWithMatcher:grey_notNil() |
| - error:&error]; |
| - return error == nil; |
| - }; |
| - GREYAssert(testing::WaitUntilConditionOrTimeout(kSnackbarAppearanceTimeout, |
| - waitForAppearance), |
| - @"Snackbar did not appear."); |
| - |
| - // Wait for the snackbar to disappear. |
| - ConditionBlock waitForDisappearance = ^{ |
| - NSError* error = nil; |
| - [[EarlGrey selectElementWithMatcher:snackbarMatcher] |
| - assertWithMatcher:grey_nil() |
| - error:&error]; |
| - return error == nil; |
| - }; |
| - GREYAssert(testing::WaitUntilConditionOrTimeout(kSnackbarDisappearanceTimeout, |
| - waitForDisappearance), |
| - @"Snackbar did not disappear."); |
| + AddCurrentPageToReadingList(); |
| // Navigate to http://beans |
| [ChromeEarlGrey loadURL:nonDistillablePageURL]; |
| @@ -319,6 +342,11 @@ id<GREYMatcher> EmptyBackground() { |
| selectElementWithMatcher:chrome_test_util::PageSecurityInfoButton()] |
| performAction:grey_tap()]; |
| + // Test Omnibox URL |
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText( |
| + "localhost:8080/potato/")] |
| + assertWithMatcher:grey_notNil()]; |
| + |
| // Verify that the Page Info is about offline pages. |
| id<GREYMatcher> pageInfoTitleMatcher = |
| chrome_test_util::StaticTextWithAccessibilityLabelId( |
| @@ -331,6 +359,248 @@ id<GREYMatcher> EmptyBackground() { |
| base::ASCIIToUTF16(pageTitle.c_str())); |
| } |
| +// Tests that sharing a web page to the Reading List results in a snackbar |
| +// appearing, and that the Reading List entry is present in the Reading List. |
| +// Loads online version by tapping on entry. |
| +- (void)testSavingToReadingListAndLoadNormal { |
| + // Setup a server serving a distillable page at http://potato with the title |
|
jif
2017/03/21 13:11:01
Move the code creating the server and the pages to
|
| + // "tomato", and a non distillable page at http://beans |
| + std::map<GURL, std::string> responses; |
| + std::string pageTitle = "Tomato"; |
| + const GURL distillablePageURL = |
| + web::test::HttpServer::MakeUrl("http://potato"); |
| + const GURL nonDistillablePageURL = |
| + web::test::HttpServer::MakeUrl("http://beans"); |
| + responses[nonDistillablePageURL] = |
| + "<html><head><title>greens</title></head></html>"; |
| + |
| + std::string contentToRemove = "Text that distillation should remove."; |
| + std::string contentToKeep = "Text that distillation should keep."; |
| + // Distillation only occurs on pages that are not too small. |
| + responses[distillablePageURL] = |
| + "<html><head><title>" + pageTitle + "</title></head>" + |
| + contentToRemove * 20 + "<article>" + contentToKeep * 20 + "</article>" + |
| + contentToRemove * 20 + "</html>"; |
| + |
| + web::test::SetUpSimpleHttpServer(responses); |
| + web::test::HttpServer& server = web::test::HttpServer::GetSharedInstance(); |
| + |
| + // Open http://potato |
| + [ChromeEarlGrey loadURL:distillablePageURL]; |
| + |
| + AddCurrentPageToReadingList(); |
| + |
| + // Navigate to http://beans |
| + [ChromeEarlGrey loadURL:nonDistillablePageURL]; |
| + [ChromeEarlGrey waitForPageToFinishLoading]; |
| + |
| + // Verify that an entry with the correct title is present in the reading list. |
| + OpenReadingList(); |
| + AssertEntryVisible(pageTitle); |
| + // Long press the entry, and open it offline. |
| + TapEntry(pageTitle); |
| + |
| + // Verify there is no offline page. |
| + [[EarlGrey |
| + selectElementWithMatcher:chrome_test_util::StaticHtmlViewContainingText( |
| + base::SysUTF8ToNSString( |
| + contentToKeep.c_str()))] |
| + assertWithMatcher:grey_nil()]; |
| + |
| + // Verify there is an online page. |
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewContainingText( |
| + contentToKeep.c_str())] |
| + assertWithMatcher:grey_notNil()]; |
| + |
| + // Test Omnibox URL |
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText( |
| + "localhost:8080/potato/")] |
| + assertWithMatcher:grey_notNil()]; |
| + |
| + // Stop server to reload offline. |
| + server.Stop(); |
| + |
| + chrome_test_util::GetCurrentWebState()->GetNavigationManager()->Reload( |
| + web::ReloadType::NORMAL, false); |
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewContainingText( |
| + contentToKeep.c_str())] |
| + assertWithMatcher:grey_nil()]; |
| + |
| + [[EarlGrey |
| + selectElementWithMatcher:chrome_test_util::StaticHtmlViewContainingText( |
| + base::SysUTF8ToNSString( |
| + contentToKeep.c_str()))] |
| + assertWithMatcher:grey_notNil()]; |
| +} |
| + |
| +// Tests that sharing a web page to the Reading List results in a snackbar |
| +// appearing, and that the Reading List entry is present in the Reading List. |
| +// Loads offline version by tapping on entry without web server. |
| +- (void)testSavingToReadingListAndLoadNoNetwork { |
| + // Setup a server serving a distillable page at http://potato with the title |
| + // "tomato", and a non distillable page at http://beans |
| + std::map<GURL, std::string> responses; |
| + std::string pageTitle = "Tomato"; |
| + const GURL distillablePageURL = |
| + web::test::HttpServer::MakeUrl("http://potato"); |
| + const GURL nonDistillablePageURL = |
| + web::test::HttpServer::MakeUrl("http://beans"); |
| + responses[nonDistillablePageURL] = |
| + "<html><head><title>greens</title></head></html>"; |
| + web::test::HttpServer& server = web::test::HttpServer::GetSharedInstance(); |
| + |
| + std::string contentToRemove = "Text that distillation should remove."; |
| + std::string contentToKeep = "Text that distillation should keep."; |
| + // Distillation only occurs on pages that are not too small. |
| + responses[distillablePageURL] = |
| + "<html><head><title>" + pageTitle + "</title></head>" + |
| + contentToRemove * 20 + "<article>" + contentToKeep * 20 + "</article>" + |
| + contentToRemove * 20 + "</html>"; |
| + |
| + web::test::SetUpSimpleHttpServer(responses); |
| + |
| + // Open http://potato |
| + [ChromeEarlGrey loadURL:distillablePageURL]; |
| + |
| + AddCurrentPageToReadingList(); |
| + |
| + // Navigate to http://beans |
| + [ChromeEarlGrey loadURL:nonDistillablePageURL]; |
| + [ChromeEarlGrey waitForPageToFinishLoading]; |
| + |
| + // Stop server to generate error. |
| + server.Stop(); |
| + |
| + // Verify that an entry with the correct title is present in the reading list. |
| + OpenReadingList(); |
| + AssertEntryVisible(pageTitle); |
| + // Long press the entry, and open it offline. |
| + TapEntry(pageTitle); |
| + |
| + // There will be multiple reload. Wait. |
| + ConditionBlock waitForLoading = ^{ |
| + NSError* error = nil; |
| + [[EarlGrey |
| + selectElementWithMatcher:chrome_test_util::StaticHtmlViewContainingText( |
| + base::SysUTF8ToNSString( |
| + contentToKeep.c_str()))] |
| + assertWithMatcher:grey_notNil() |
| + error:&error]; |
| + return error == nil; |
| + }; |
| + GREYAssert( |
| + testing::WaitUntilConditionOrTimeout(kLoadOfflineTimeout, waitForLoading), |
| + @"Offline page did not load."); |
| + |
| + // Verify there is no online page. |
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewContainingText( |
| + contentToKeep.c_str())] |
| + assertWithMatcher:grey_nil()]; |
| + |
| + // Test Omnibox URL |
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText( |
| + "localhost:8080/potato/")] |
| + assertWithMatcher:grey_notNil()]; |
| + |
| + // Start server to reload online error. |
| + server.StartOrDie(); |
| + web::test::SetUpSimpleHttpServer(responses); |
| + |
| + chrome_test_util::GetCurrentWebState()->GetNavigationManager()->Reload( |
| + web::ReloadType::NORMAL, false); |
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewContainingText( |
| + contentToKeep.c_str())] |
| + assertWithMatcher:grey_notNil()]; |
| + |
| + [[EarlGrey |
| + selectElementWithMatcher:chrome_test_util::StaticHtmlViewContainingText( |
| + base::SysUTF8ToNSString( |
| + contentToKeep.c_str()))] |
| + assertWithMatcher:grey_nil()]; |
| +} |
| + |
| +// Tests that sharing a web page to the Reading List results in a snackbar |
| +// appearing, and that the Reading List entry is present in the Reading List. |
| +// Loads offline version by tapping on entry with delayed web server. |
| +- (void)testSavingToReadingListAndLoadBadNetwork { |
| + // Setup a server serving a distillable page at http://potato with the title |
| + // "tomato", and a non distillable page at http://beans |
| + std::map<GURL, std::string> responses; |
| + std::string pageTitle = "Tomato"; |
| + const GURL distillablePageURL = |
| + web::test::HttpServer::MakeUrl("http://potato"); |
| + const GURL nonDistillablePageURL = |
| + web::test::HttpServer::MakeUrl("http://beans"); |
| + responses[nonDistillablePageURL] = |
| + "<html><head><title>greens</title></head></html>"; |
| + |
| + std::string contentToRemove = "Text that distillation should remove."; |
| + std::string contentToKeep = "Text that distillation should keep."; |
| + // Distillation only occurs on pages that are not too small. |
| + responses[distillablePageURL] = |
| + "<html><head><title>" + pageTitle + "</title></head>" + |
| + contentToRemove * 20 + "<article>" + contentToKeep * 20 + "</article>" + |
| + contentToRemove * 20 + "</html>"; |
| + |
| + web::test::SetUpSimpleHttpServer(responses); |
| + |
| + // Open http://potato |
| + [ChromeEarlGrey loadURL:distillablePageURL]; |
| + |
| + AddCurrentPageToReadingList(); |
| + |
| + // Navigate to http://beans |
| + [ChromeEarlGrey loadURL:nonDistillablePageURL]; |
| + [ChromeEarlGrey waitForPageToFinishLoading]; |
| + |
| + web::test::SetUpHttpServer(base::MakeUnique<web::DelayedResponseProvider>( |
| + base::MakeUnique<HtmlResponseProvider>(responses), 5)); |
| + |
| + // Verify that an entry with the correct title is present in the reading list. |
| + OpenReadingList(); |
| + AssertEntryVisible(pageTitle); |
| + // Long press the entry, and open it offline. |
| + TapEntry(pageTitle); |
| + |
| + // There will be multiple reload. Wait. |
| + ConditionBlock waitForLoading = ^{ |
| + NSError* error = nil; |
| + [[EarlGrey |
| + selectElementWithMatcher:chrome_test_util::StaticHtmlViewContainingText( |
| + base::SysUTF8ToNSString( |
| + contentToKeep.c_str()))] |
| + assertWithMatcher:grey_notNil() |
| + error:&error]; |
| + return error == nil; |
| + }; |
| + GREYAssert( |
| + testing::WaitUntilConditionOrTimeout(kLoadOfflineTimeout, waitForLoading), |
| + @"Offline page did not load."); |
| + |
| + // Verify there is no online page. |
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewContainingText( |
| + contentToKeep.c_str())] |
| + assertWithMatcher:grey_nil()]; |
| + |
| + // Test Omnibox URL |
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText( |
| + "localhost:8080/potato/")] |
| + assertWithMatcher:grey_notNil()]; |
| + |
| + // Reload should lod online page. |
| + chrome_test_util::GetCurrentWebState()->GetNavigationManager()->Reload( |
| + web::ReloadType::NORMAL, false); |
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewContainingText( |
| + contentToKeep.c_str())] |
| + assertWithMatcher:grey_notNil()]; |
| + |
| + [[EarlGrey |
| + selectElementWithMatcher:chrome_test_util::StaticHtmlViewContainingText( |
| + base::SysUTF8ToNSString( |
| + contentToKeep.c_str()))] |
| + assertWithMatcher:grey_nil()]; |
| +} |
| + |
| // Tests that only the "Edit" button is showing when not editing. |
| - (void)testVisibleButtonsNonEditingMode { |
| GetReadingListModel()->AddEntry(GURL(kUnreadURL), std::string(kUnreadTitle), |