| Index: ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm
|
| diff --git a/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm b/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..969d354269b60aaabfad9971a9fe0bc1b32e6eb5
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm
|
| @@ -0,0 +1,956 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#import <EarlGrey/EarlGrey.h>
|
| +#import <XCTest/XCTest.h>
|
| +
|
| +#include "base/mac/bind_objc_block.h"
|
| +#include "base/memory/ptr_util.h"
|
| +#include "base/strings/stringprintf.h"
|
| +#include "base/strings/sys_string_conversions.h"
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#import "base/test/ios/wait_util.h"
|
| +#include "components/strings/grit/components_strings.h"
|
| +#include "ios/chrome/browser/experimental_flags.h"
|
| +#import "ios/chrome/browser/metrics/tab_usage_recorder.h"
|
| +#import "ios/chrome/browser/ui/settings/privacy_collection_view_controller.h"
|
| +#import "ios/chrome/browser/ui/settings/settings_collection_view_controller.h"
|
| +#import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
|
| +#import "ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h"
|
| +#include "ios/chrome/browser/ui/ui_util.h"
|
| +#import "ios/chrome/browser/ui/uikit_ui_util.h"
|
| +#include "ios/chrome/grit/ios_strings.h"
|
| +#import "ios/chrome/test/app/chrome_test_util.h"
|
| +#import "ios/chrome/test/app/histogram_test_util.h"
|
| +#include "ios/chrome/test/app/navigation_test_util.h"
|
| +#import "ios/chrome/test/app/tab_test_util.h"
|
| +#include "ios/chrome/test/app/web_view_interaction_test_util.h"
|
| +#import "ios/chrome/test/earl_grey/chrome_assertions.h"
|
| +#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
|
| +#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
|
| +#import "ios/chrome/test/earl_grey/chrome_matchers.h"
|
| +#import "ios/chrome/test/earl_grey/chrome_test_case.h"
|
| +#import "ios/testing/wait_util.h"
|
| +#import "ios/web/public/test/http_server.h"
|
| +#import "ios/web/public/test/http_server_util.h"
|
| +#include "ios/web/public/test/response_providers/delayed_response_provider.h"
|
| +#include "ios/web/public/test/response_providers/html_response_provider.h"
|
| +#include "ui/base/l10n/l10n_util.h"
|
| +#include "ui/base/l10n/l10n_util_mac.h"
|
| +
|
| +namespace {
|
| +
|
| +const char kTestUrl1[] =
|
| + "http://ios/testing/data/http_server_files/memory_usage.html";
|
| +const char kURL1FirstWord[] = "Page";
|
| +const char kTestUrl2[] =
|
| + "http://ios/testing/data/http_server_files/fullscreen.html";
|
| +const char kURL2FirstWord[] = "Rugby";
|
| +const char kClearPageScript[] = "document.body.innerHTML='';";
|
| +
|
| +// The delay to use to serve slow URLs.
|
| +const CGFloat kSlowURLDelay = 3;
|
| +
|
| +// The delay to wait for an element to appear before tapping on it.
|
| +const CGFloat kWaitElementTimeout = 3;
|
| +
|
| +void ResetTabUsageRecorder() {
|
| + GREYAssertTrue(chrome_test_util::ResetTabUsageRecorder(),
|
| + @"Fail to reset the TabUsageRecorder");
|
| +}
|
| +
|
| +// Wait until |matcher| is accessible (not nil).
|
| +void Wait(id<GREYMatcher> matcher, NSString* name) {
|
| + ConditionBlock condition = ^{
|
| + NSError* error = nil;
|
| + [[EarlGrey selectElementWithMatcher:matcher] assertWithMatcher:grey_notNil()
|
| + error:&error];
|
| + return error == nil;
|
| + };
|
| + GREYAssert(
|
| + testing::WaitUntilConditionOrTimeout(kWaitElementTimeout, condition),
|
| + [NSString stringWithFormat:@"Waiting for matcher %@ failed.", name]);
|
| +}
|
| +
|
| +// Wait until |matcher| is accessible (not nil) and tap on it.
|
| +void WaitAndTap(id<GREYMatcher> matcher, NSString* name) {
|
| + Wait(matcher, name);
|
| + [[EarlGrey selectElementWithMatcher:matcher] performAction:grey_tap()];
|
| +}
|
| +
|
| +// Creates a new main tab and load |url|. Wait until |word| is visible on the
|
| +// page.
|
| +void NewMainTabWithURL(const GURL& url, const std::string& word) {
|
| + int number_of_tabs = chrome_test_util::GetMainTabCount();
|
| + chrome_test_util::OpenNewTab();
|
| + [ChromeEarlGrey loadURL:url];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:chrome_test_util::webViewContainingText(word)]
|
| + assertWithMatcher:grey_notNil()];
|
| + chrome_test_util::AssertMainTabCount(number_of_tabs + 1);
|
| +}
|
| +
|
| +// Opens 2 new tabs with different URLs.
|
| +void OpenTwoTabs() {
|
| + chrome_test_util::CloseAllTabsInCurrentMode();
|
| +
|
| + const GURL url1 = web::test::HttpServer::MakeUrl(kTestUrl1);
|
| + const GURL url2 = web::test::HttpServer::MakeUrl(kTestUrl2);
|
| + NewMainTabWithURL(url1, kURL1FirstWord);
|
| + NewMainTabWithURL(url2, kURL2FirstWord);
|
| +}
|
| +
|
| +// Opens a new main tab using the UI. This method is using ad-hoc
|
| +// synchronization.
|
| +void OpenNewMainTabUsingUIUnsynced() {
|
| + int nb_main_tab = chrome_test_util::GetMainTabCount();
|
| + id<GREYMatcher> tool_menu_matcher =
|
| + grey_accessibilityID(kToolbarToolsMenuButtonIdentifier);
|
| + WaitAndTap(tool_menu_matcher, @"Tool menu");
|
| + id<GREYMatcher> new_main_tab_button_matcher =
|
| + grey_accessibilityID(kToolsMenuNewTabId);
|
| + WaitAndTap(new_main_tab_button_matcher, @"New tab button");
|
| +
|
| + chrome_test_util::AssertMainTabCount(nb_main_tab + 1);
|
| +}
|
| +
|
| +// Opens a new incognito tab using the UI and evicts any main tab model tabs.
|
| +void OpenNewIncognitoTabUsingUIAndEvictMainTabs() {
|
| + int nb_incognito_tab = chrome_test_util::GetIncognitoTabCount();
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + id<GREYMatcher> new_incognito_tab_button_matcher =
|
| + grey_accessibilityID(kToolsMenuNewIncognitoTabId);
|
| + [[EarlGrey selectElementWithMatcher:new_incognito_tab_button_matcher]
|
| + performAction:grey_tap()];
|
| + chrome_test_util::AssertIncognitoTabCount(nb_incognito_tab + 1);
|
| +
|
| + chrome_test_util::EvictOtherTabModelTabs();
|
| +}
|
| +
|
| +// Closes a tab in the current tab model. Synchronize on tab number afterwards.
|
| +void CloseTabAtIndexAndSync(NSUInteger i) {
|
| + NSUInteger nb_main_tab = chrome_test_util::GetMainTabCount();
|
| + chrome_test_util::CloseTabAtIndex(i);
|
| + ConditionBlock condition = ^{
|
| + return chrome_test_util::GetMainTabCount() == (nb_main_tab - 1);
|
| + };
|
| + GREYAssert(
|
| + testing::WaitUntilConditionOrTimeout(kWaitElementTimeout, condition),
|
| + @"Waiting for tab to close");
|
| +}
|
| +
|
| +// Closes the tabs switcher.
|
| +void CloseTabSwitcher() {
|
| + id<GREYMatcher> matcher = chrome_test_util::buttonWithAccessibilityLabelId(
|
| + IDS_IOS_TAB_STRIP_LEAVE_TAB_SWITCHER);
|
| + [[EarlGrey selectElementWithMatcher:matcher] performAction:grey_tap()];
|
| +}
|
| +
|
| +// Swithches to normal mode using swith button (iPad) or stack view (iPhone).
|
| +// Assumes current mode is Incognito.
|
| +void SwitchToNormalMode() {
|
| + GREYAssertTrue(chrome_test_util::IsIncognitoMode(),
|
| + @"Switching to normal mode is only allowed from Incognito.");
|
| + if (IsIPadIdiom()) {
|
| + if (experimental_flags::IsTabSwitcherEnabled()) {
|
| + // Enter the tab switcher.
|
| + id<GREYMatcher> tabSwitcherEnterButton =
|
| + grey_accessibilityLabel(l10n_util::GetNSStringWithFixup(
|
| + IDS_IOS_TAB_STRIP_ENTER_TAB_SWITCHER));
|
| + [[EarlGrey selectElementWithMatcher:tabSwitcherEnterButton]
|
| + performAction:grey_tap()];
|
| +
|
| + // Select the non incognito panel.
|
| + id<GREYMatcher> tabSwitcherHeaderPanelButton =
|
| + grey_accessibilityLabel(l10n_util::GetNSStringWithFixup(
|
| + IDS_IOS_TAB_SWITCHER_HEADER_NON_INCOGNITO_TABS));
|
| + [[EarlGrey selectElementWithMatcher:tabSwitcherHeaderPanelButton]
|
| + performAction:grey_tap()];
|
| +
|
| + // Leave the tab switcher.
|
| + CloseTabSwitcher();
|
| + } else {
|
| + [[EarlGrey selectElementWithMatcher:
|
| + chrome_test_util::buttonWithAccessibilityLabelId(
|
| + IDS_IOS_SWITCH_BROWSER_MODE_LEAVE_INCOGNITO)]
|
| + performAction:grey_tap()];
|
| + }
|
| + } else {
|
| + [[EarlGrey selectElementWithMatcher:
|
| + chrome_test_util::buttonWithAccessibilityLabelId(
|
| + IDS_IOS_TOOLBAR_SHOW_TABS)] performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:
|
| + chrome_test_util::buttonWithAccessibilityLabelId(
|
| + IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB)]
|
| + performAction:grey_swipeFastInDirection(kGREYDirectionRight)];
|
| + [[EarlGrey selectElementWithMatcher:
|
| + chrome_test_util::buttonWithAccessibilityLabelId(
|
| + IDS_IOS_TOOLBAR_SHOW_TABS)] performAction:grey_tap()];
|
| + }
|
| + GREYAssertFalse(chrome_test_util::IsIncognitoMode(),
|
| + @"Switching to normal mode failed.");
|
| +}
|
| +
|
| +// Check that the error page is visible.
|
| +void CheckErrorPageIsVisible() {
|
| + // The DNS error page is static HTML content, so it isn't part of the webview
|
| + // owned by the webstate.
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::
|
| + webViewBelongingToWebController()]
|
| + assertWithMatcher:grey_nil()];
|
| + NSString* const kError =
|
| + l10n_util::GetNSString(IDS_ERRORPAGES_HEADING_NOT_AVAILABLE);
|
| + [[EarlGrey
|
| + selectElementWithMatcher:chrome_test_util::staticHtmlViewContainingText(
|
| + kError)] assertWithMatcher:grey_notNil()];
|
| +}
|
| +
|
| +// Open the settings submenu. Assumes that settings menu is visible.
|
| +void OpenSettingsSubMenuUnsynced(int submenu) {
|
| + id<GREYMatcher> settings_button_matcher =
|
| + grey_text(l10n_util::GetNSString(submenu));
|
| + [[[EarlGrey selectElementWithMatcher:settings_button_matcher]
|
| + usingSearchAction:grey_swipeSlowInDirection(kGREYDirectionUp)
|
| + onElementWithMatcher:grey_accessibilityID(kSettingsCollectionViewId)]
|
| + performAction:grey_tap()];
|
| +}
|
| +
|
| +// Open the settings menu. Wait for the settings menu to appear.
|
| +void OpenSettingsMenuUnsynced() {
|
| + id<GREYMatcher> tool_menu_matcher =
|
| + grey_accessibilityID(kToolbarToolsMenuButtonIdentifier);
|
| + WaitAndTap(tool_menu_matcher, @"Tool menu");
|
| +
|
| + id<GREYMatcher> settings_button_matcher =
|
| + grey_accessibilityID(kToolsMenuSettingsId);
|
| +
|
| + WaitAndTap(settings_button_matcher, @"Settings menu");
|
| + Wait(grey_accessibilityID(kSettingsCollectionViewId), @"Setting view");
|
| +}
|
| +
|
| +// Select the tab with title |title| using UI (tab strip on iPad, stack view on
|
| +// iPhone).
|
| +void SelectTabUsingUI(NSString* title) {
|
| + if (IsCompact()) {
|
| + WaitAndTap(chrome_test_util::buttonWithAccessibilityLabelId(
|
| + IDS_IOS_TOOLBAR_SHOW_TABS),
|
| + @"Tab switcher");
|
| + }
|
| + WaitAndTap(grey_text(title),
|
| + [NSString stringWithFormat:@"tab with title %@", title]);
|
| +}
|
| +} // namespace
|
| +
|
| +// Test for the TabUsageRecorder class.
|
| +@interface TabUsageRecorderTestCase : ChromeTestCase
|
| +@end
|
| +
|
| +@implementation TabUsageRecorderTestCase
|
| +
|
| +- (void)tearDown {
|
| + [[GREYConfiguration sharedInstance]
|
| + setValue:@(YES)
|
| + forConfigKey:kGREYConfigKeySynchronizationEnabled];
|
| + [super tearDown];
|
| +}
|
| +
|
| +// Tests that the recorder actual recorde tab state.
|
| +- (void)testTabSwitchRecorder {
|
| + web::test::SetUpFileBasedHttpServer();
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + ResetTabUsageRecorder();
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| +
|
| + // Open two tabs with urls.
|
| + OpenTwoTabs();
|
| + chrome_test_util::AssertMainTabCount(2);
|
| + // Switch between the two tabs. Both are currently in memory.
|
| + chrome_test_util::SelectTabAtIndexInCurrentMode(0);
|
| +
|
| + // Verify that one in-memory tab switch has been recorded.
|
| + // histogramTester.ExpectTotalCount(kSelectedTabHistogramName, 1,
|
| + // failureBlock);
|
| + histogramTester.ExpectUniqueSample(
|
| + kSelectedTabHistogramName, TabUsageRecorder::IN_MEMORY, 1, failureBlock);
|
| +
|
| + // Evict the tab.
|
| + OpenNewIncognitoTabUsingUIAndEvictMainTabs();
|
| + GREYAssertTrue(chrome_test_util::IsIncognitoMode(),
|
| + @"Failed to switch to incognito mode");
|
| +
|
| + // Switch back to the normal tabs. Should be on tab one.
|
| + SwitchToNormalMode();
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kURL1FirstWord)]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + histogramTester.ExpectTotalCount(kSelectedTabHistogramName, 2, failureBlock);
|
| + histogramTester.ExpectBucketCount(kSelectedTabHistogramName,
|
| + TabUsageRecorder::EVICTED, 1, failureBlock);
|
| +}
|
| +
|
| +// Verifies the UMA metric for page loads before a tab eviction by loading
|
| +// some tabs, forcing a tab eviction, then checking the histogram.
|
| +- (void)testPageLoadCountBeforeEvictedTab {
|
| + web::test::SetUpFileBasedHttpServer();
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + ResetTabUsageRecorder();
|
| + const GURL url1 = web::test::HttpServer::MakeUrl(kTestUrl1);
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| +
|
| + // This test opens three tabs.
|
| + const int numberOfTabs = 3;
|
| + chrome_test_util::CloseAllTabsInCurrentMode();
|
| + // Open three tabs with http:// urls.
|
| + for (NSUInteger i = 0; i < numberOfTabs; i++) {
|
| + chrome_test_util::OpenNewTab();
|
| + [ChromeEarlGrey loadURL:url1];
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kURL1FirstWord)]
|
| + assertWithMatcher:grey_notNil()];
|
| + }
|
| + chrome_test_util::AssertMainTabCount(numberOfTabs);
|
| +
|
| + // Switch between the tabs. They are currently in memory.
|
| + chrome_test_util::SelectTabAtIndexInCurrentMode(0);
|
| +
|
| + // Verify that no page-load count has been recorded.
|
| + histogramTester.ExpectTotalCount(kPageLoadsBeforeEvictedTabSelected, 0,
|
| + failureBlock);
|
| +
|
| + // Reload each tab.
|
| + for (NSUInteger i = 0; i < numberOfTabs; i++) {
|
| + chrome_test_util::SelectTabAtIndexInCurrentMode(i);
|
| + // Clear the page so that we can check when pade reload is complete.
|
| + __block bool finished = false;
|
| + chrome_test_util::GetCurrentWebState()->ExecuteJavaScript(
|
| + base::UTF8ToUTF16(kClearPageScript),
|
| + base::BindBlock(^(const base::Value*) {
|
| + finished = true;
|
| + }));
|
| +
|
| + GREYAssert(testing::WaitUntilConditionOrTimeout(1.0,
|
| + ^{
|
| + return finished;
|
| + }),
|
| + @"JavaScript to reload each tab did not finish");
|
| + [ChromeEarlGreyUI reload];
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kURL1FirstWord)]
|
| + assertWithMatcher:grey_notNil()];
|
| + }
|
| +
|
| + // Evict the tab. Create a dummy tab so that switching back to normal mode
|
| + // does not trigger a reload immediatly.
|
| + chrome_test_util::OpenNewTab();
|
| + OpenNewIncognitoTabUsingUIAndEvictMainTabs();
|
| + chrome_test_util::AssertIncognitoTabCount(1);
|
| +
|
| + // Switch back to the normal tabs. Should be on tab one.
|
| + SwitchToNormalMode();
|
| + chrome_test_util::SelectTabAtIndexInCurrentMode(0);
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kURL1FirstWord)]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + // Verify that one page-load count has been recorded. It should contain two
|
| + // page loads for each tab created.
|
| + histogramTester.ExpectTotalCount(kPageLoadsBeforeEvictedTabSelected, 1,
|
| + failureBlock);
|
| +
|
| + std::unique_ptr<base::HistogramSamples> samples =
|
| + histogramTester.GetHistogramSamplesSinceCreation(
|
| + kPageLoadsBeforeEvictedTabSelected);
|
| + int sampleSum = samples ? samples->sum() : 0;
|
| + GREYAssertEqual(
|
| + sampleSum, numberOfTabs * 2,
|
| + [NSString stringWithFormat:@"Expected page loads is %d, actual %d.",
|
| + numberOfTabs * 2, sampleSum]);
|
| +}
|
| +
|
| +// Tests that tabs reloaded on cold start are reported as
|
| +// EVICTED_DUE_TO_COLD_START.
|
| +- (void)testColdLaunchReloadCount {
|
| + web::test::SetUpFileBasedHttpServer();
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + ResetTabUsageRecorder();
|
| +
|
| + // Open two tabs with urls.
|
| + OpenTwoTabs();
|
| + chrome_test_util::AssertMainTabCount(2);
|
| + // Set the normal tabs as 'cold start' tabs.
|
| + GREYAssertTrue(chrome_test_util::SetCurrentTabsToBeColdStartTabs(),
|
| + @"Fail to state tabs as cold start tabs");
|
| +
|
| + // Open two incognito tabs with urls, clearing normal tabs from memory.
|
| + OpenNewIncognitoTabUsingUIAndEvictMainTabs();
|
| + OpenNewIncognitoTabUsingUIAndEvictMainTabs();
|
| + chrome_test_util::AssertIncognitoTabCount(2);
|
| +
|
| + // Switch back to the normal tabs.
|
| + SwitchToNormalMode();
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kURL2FirstWord)]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + // Select the other one so it also reloads.
|
| + chrome_test_util::SelectTabAtIndexInCurrentMode(0);
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kURL1FirstWord)]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| + // Make sure that one of the 2 tab loads (excluding the selected tab) is
|
| + // counted as a cold start eviction.
|
| + histogramTester.ExpectBucketCount(kSelectedTabHistogramName,
|
| + TabUsageRecorder::EVICTED_DUE_TO_COLD_START,
|
| + 1, failureBlock);
|
| +
|
| + histogramTester.ExpectBucketCount(
|
| + kSelectedTabHistogramName, TabUsageRecorder::IN_MEMORY, 0, failureBlock);
|
| + // Re-select the same tab and make sure it is not counted again as evicted.
|
| + chrome_test_util::SelectTabAtIndexInCurrentMode(1);
|
| + chrome_test_util::SelectTabAtIndexInCurrentMode(0);
|
| +
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kURL1FirstWord)]
|
| + assertWithMatcher:grey_notNil()];
|
| + histogramTester.ExpectBucketCount(kSelectedTabHistogramName,
|
| + TabUsageRecorder::EVICTED_DUE_TO_COLD_START,
|
| + 1, failureBlock);
|
| +
|
| + histogramTester.ExpectBucketCount(
|
| + kSelectedTabHistogramName, TabUsageRecorder::IN_MEMORY, 2, failureBlock);
|
| +}
|
| +
|
| +// Tests that tabs reloads after backgrounding and eviction.
|
| +- (void)testBackgroundingReloadCount {
|
| + web::test::SetUpFileBasedHttpServer();
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + ResetTabUsageRecorder();
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| +
|
| + // Open two tabs with urls.
|
| + OpenTwoTabs();
|
| + chrome_test_util::AssertMainTabCount(2);
|
| +
|
| + // Simulate going into the background.
|
| + GREYAssertTrue(chrome_test_util::SimulateTabsBackgrounding(),
|
| + @"Fail to simulate tab backgrounding.");
|
| +
|
| + // Open incognito and clear normal tabs from memory.
|
| + OpenNewIncognitoTabUsingUIAndEvictMainTabs();
|
| + GREYAssertTrue(chrome_test_util::IsIncognitoMode(),
|
| + @"Failed to switch to incognito mode");
|
| + histogramTester.ExpectTotalCount(kEvictedTabReloadTime, 0, failureBlock);
|
| +
|
| + // Switch back to the normal tabs.
|
| + SwitchToNormalMode();
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kURL2FirstWord)]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + const GURL url1 = web::test::HttpServer::MakeUrl(kTestUrl1);
|
| + const GURL url2 = web::test::HttpServer::MakeUrl(kTestUrl2);
|
| + [[EarlGrey
|
| + selectElementWithMatcher:chrome_test_util::omniboxText(url2.GetContent())]
|
| + assertWithMatcher:grey_notNil()];
|
| + histogramTester.ExpectTotalCount(kEvictedTabReloadTime, 1, failureBlock);
|
| +
|
| + chrome_test_util::SelectTabAtIndexInCurrentMode(0);
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kURL1FirstWord)]
|
| + assertWithMatcher:grey_notNil()];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:chrome_test_util::omniboxText(url1.GetContent())]
|
| + assertWithMatcher:grey_notNil()];
|
| + histogramTester.ExpectTotalCount(kEvictedTabReloadTime, 2, failureBlock);
|
| +}
|
| +
|
| +// Verify correct recording of metrics when the reloading of an evicted tab
|
| +// succeeds.
|
| +- (void)testEvictedTabReloadSuccess {
|
| + web::test::SetUpFileBasedHttpServer();
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| +
|
| + GURL URL = web::test::HttpServer::MakeUrl(kTestUrl1);
|
| + NewMainTabWithURL(URL, kURL1FirstWord);
|
| + OpenNewIncognitoTabUsingUIAndEvictMainTabs();
|
| + SwitchToNormalMode();
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kURL1FirstWord)]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + histogramTester.ExpectUniqueSample(kEvictedTabReloadSuccessRate,
|
| + TabUsageRecorder::LOAD_SUCCESS, 1,
|
| + failureBlock);
|
| + histogramTester.ExpectUniqueSample(kDidUserWaitForEvictedTabReload,
|
| + TabUsageRecorder::USER_WAITED, 1,
|
| + failureBlock);
|
| + histogramTester.ExpectTotalCount(kEvictedTabReloadTime, 1, failureBlock);
|
| +}
|
| +
|
| +// Verify correct recording of metrics when the reloading of an evicted tab
|
| +// fails.
|
| +- (void)testEvictedTabReloadFailure {
|
| + web::test::SetUpFileBasedHttpServer();
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| +
|
| + // This URL is purposely invalid so it triggers a navigation error.
|
| + GURL invalidURL(kTestUrl1);
|
| +
|
| + chrome_test_util::OpenNewTab();
|
| + [ChromeEarlGrey loadURL:invalidURL];
|
| + CheckErrorPageIsVisible();
|
| + OpenNewIncognitoTabUsingUIAndEvictMainTabs();
|
| +
|
| + SwitchToNormalMode();
|
| + CheckErrorPageIsVisible();
|
| +
|
| + histogramTester.ExpectUniqueSample(kEvictedTabReloadSuccessRate,
|
| + TabUsageRecorder::LOAD_FAILURE, 1,
|
| + failureBlock);
|
| + histogramTester.ExpectUniqueSample(kDidUserWaitForEvictedTabReload,
|
| + TabUsageRecorder::USER_WAITED, 1,
|
| + failureBlock);
|
| + histogramTester.ExpectTotalCount(kEvictedTabReloadTime, 0, failureBlock);
|
| +}
|
| +
|
| +// Test that USER_DID_NOT_WAIT is reported if the user does not wait for the
|
| +// reload to be complete after eviction.
|
| +- (void)testEvictedTabSlowReload {
|
| + std::map<GURL, std::string> responses;
|
| + const GURL slowURL = web::test::HttpServer::MakeUrl("http://slow");
|
| + responses[slowURL] = "Slow Page";
|
| +
|
| + web::test::SetUpHttpServer(base::MakeUnique<web::DelayedResponseProvider>(
|
| + base::MakeUnique<HtmlResponseProvider>(responses), kSlowURLDelay));
|
| +
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| +
|
| + // A blank tab needed to switch to it after reloading.
|
| + chrome_test_util::OpenNewTab();
|
| + chrome_test_util::OpenNewTab();
|
| + chrome_test_util::LoadUrl(slowURL);
|
| + OpenNewIncognitoTabUsingUIAndEvictMainTabs();
|
| +
|
| + web::test::SetUpHttpServer(base::MakeUnique<web::DelayedResponseProvider>(
|
| + base::MakeUnique<HtmlResponseProvider>(responses), kSlowURLDelay));
|
| +
|
| + SwitchToNormalMode();
|
| +
|
| + GREYAssert(
|
| + [[GREYCondition conditionWithName:@"Wait for tab to restart loading."
|
| + block:^BOOL() {
|
| + return chrome_test_util::IsLoading();
|
| + }] waitWithTimeout:kWaitElementTimeout],
|
| + @"Tab did not start loading.");
|
| +
|
| + // This method is not synced on EarlGrey.
|
| + chrome_test_util::SelectTabAtIndexInCurrentMode(0);
|
| +
|
| + // Do not test the kEvictedTabReloadSuccessRate, as the timing of the two
|
| + // page loads cannot be guaranteed. The test would be flaky.
|
| + histogramTester.ExpectBucketCount(kDidUserWaitForEvictedTabReload,
|
| + TabUsageRecorder::USER_DID_NOT_WAIT, 1,
|
| + failureBlock);
|
| +}
|
| +
|
| +// Test that the USER_DID_NOT_WAIT metric is logged when the user opens an NTP
|
| +// while the evicted tab is still reloading.
|
| +- (void)testEvictedTabReloadSwitchToNTP {
|
| + std::map<GURL, std::string> responses;
|
| + const GURL slowURL = web::test::HttpServer::MakeUrl("http://slow");
|
| + responses[slowURL] = "Slow Page";
|
| +
|
| + web::test::SetUpHttpServer(base::MakeUnique<HtmlResponseProvider>(responses));
|
| +
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| +
|
| + NewMainTabWithURL(slowURL, "Slow");
|
| +
|
| + OpenNewIncognitoTabUsingUIAndEvictMainTabs();
|
| + web::test::SetUpHttpServer(base::MakeUnique<web::DelayedResponseProvider>(
|
| + base::MakeUnique<HtmlResponseProvider>(responses), kSlowURLDelay));
|
| +
|
| + SwitchToNormalMode();
|
| +
|
| + // TODO(crbug.com/640977): EarlGrey synchronize on some animations when a
|
| + // page is loading. Need to handle synchronization manually for this test.
|
| + [[GREYConfiguration sharedInstance]
|
| + setValue:@(NO)
|
| + forConfigKey:kGREYConfigKeySynchronizationEnabled];
|
| + OpenNewMainTabUsingUIUnsynced();
|
| + [[GREYConfiguration sharedInstance]
|
| + setValue:@(YES)
|
| + forConfigKey:kGREYConfigKeySynchronizationEnabled];
|
| + histogramTester.ExpectBucketCount(kDidUserWaitForEvictedTabReload,
|
| + TabUsageRecorder::USER_DID_NOT_WAIT, 1,
|
| + failureBlock);
|
| +}
|
| +
|
| +// Test that the USER_DID_NOT_WAIT metric is not logged when the user opens
|
| +// and closes the settings UI while the evicted tab is still reloading.
|
| +- (void)testEvictedTabReloadSettingsAndBack {
|
| + std::map<GURL, std::string> responses;
|
| + const GURL slowURL = web::test::HttpServer::MakeUrl("http://slow");
|
| + responses[slowURL] = "Slow Page";
|
| +
|
| + web::test::SetUpHttpServer(base::MakeUnique<web::DelayedResponseProvider>(
|
| + base::MakeUnique<HtmlResponseProvider>(responses), kSlowURLDelay));
|
| +
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| +
|
| + NewMainTabWithURL(slowURL, responses[slowURL]);
|
| +
|
| + OpenNewIncognitoTabUsingUIAndEvictMainTabs();
|
| +
|
| + SwitchToNormalMode();
|
| + // TODO(crbug.com/640977): EarlGrey synchronize on some animations when a
|
| + // page is loading. Need to handle synchronization manually for this test.
|
| + [[GREYConfiguration sharedInstance]
|
| + setValue:@(NO)
|
| + forConfigKey:kGREYConfigKeySynchronizationEnabled];
|
| + OpenSettingsMenuUnsynced();
|
| + OpenSettingsSubMenuUnsynced(IDS_OPTIONS_ADVANCED_SECTION_TITLE_PRIVACY);
|
| + Wait(grey_accessibilityID(kPrivacyCollectionViewId),
|
| + @"Privacy settings view.");
|
| +
|
| + WaitAndTap(grey_accessibilityLabel(
|
| + l10n_util::GetNSString(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON)),
|
| + @"Close settings");
|
| + [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + responses[slowURL])]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + [[GREYConfiguration sharedInstance]
|
| + setValue:@(YES)
|
| + forConfigKey:kGREYConfigKeySynchronizationEnabled];
|
| +
|
| + histogramTester.ExpectBucketCount(kDidUserWaitForEvictedTabReload,
|
| + TabUsageRecorder::USER_DID_NOT_WAIT, 0,
|
| + failureBlock);
|
| + histogramTester.ExpectBucketCount(kDidUserWaitForEvictedTabReload,
|
| + TabUsageRecorder::USER_WAITED, 1,
|
| + failureBlock);
|
| +}
|
| +
|
| +// Tests that leaving Chrome while an evicted tab is reloading triggers the
|
| +// recording of the USER_LEFT_CHROME metric.
|
| +- (void)testEvictedTabReloadBackgrounded {
|
| + std::map<GURL, std::string> responses;
|
| + const GURL slowURL = web::test::HttpServer::MakeUrl("http://slow");
|
| + responses[slowURL] = "Slow Page";
|
| +
|
| + web::test::SetUpHttpServer(base::MakeUnique<HtmlResponseProvider>(responses));
|
| +
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + chrome_test_util::OpenNewTab();
|
| + chrome_test_util::LoadUrl(slowURL);
|
| +
|
| + OpenNewIncognitoTabUsingUIAndEvictMainTabs();
|
| +
|
| + web::test::SetUpHttpServer(base::MakeUnique<web::DelayedResponseProvider>(
|
| + base::MakeUnique<HtmlResponseProvider>(responses), kSlowURLDelay));
|
| + SwitchToNormalMode();
|
| +
|
| + // TODO(crbug.com/640977): EarlGrey synchronize on some animations when a
|
| + // page is loading. Need to handle synchronization manually for this test.
|
| + [[GREYConfiguration sharedInstance]
|
| + setValue:@(NO)
|
| + forConfigKey:kGREYConfigKeySynchronizationEnabled];
|
| + id<GREYMatcher> toolMenuMatcher =
|
| + grey_accessibilityID(kToolbarToolsMenuButtonIdentifier);
|
| + Wait(toolMenuMatcher, @"Tool Menu");
|
| +
|
| + GREYAssertTrue(chrome_test_util::SimulateTabsBackgrounding(),
|
| + @"Failed to simulate tab backgrounding.");
|
| + [[GREYConfiguration sharedInstance]
|
| + setValue:@(YES)
|
| + forConfigKey:kGREYConfigKeySynchronizationEnabled];
|
| +
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| + histogramTester.ExpectBucketCount(kDidUserWaitForEvictedTabReload,
|
| + TabUsageRecorder::USER_LEFT_CHROME, 1,
|
| + failureBlock);
|
| +}
|
| +
|
| +// Tests that backgrounding a tab that was not evicted while it is loading does
|
| +// not record the USER_LEFT_CHROME metric.
|
| +- (void)testLiveTabReloadBackgrounded {
|
| + std::map<GURL, std::string> responses;
|
| + const GURL slowURL = web::test::HttpServer::MakeUrl("http://slow");
|
| + responses[slowURL] = "Slow Page";
|
| +
|
| + web::test::SetUpHttpServer(base::MakeUnique<web::DelayedResponseProvider>(
|
| + base::MakeUnique<HtmlResponseProvider>(responses), kSlowURLDelay));
|
| +
|
| + chrome_test_util::HistogramTester histogramTester;
|
| +
|
| + // We need two tabs to be able to switch.
|
| + chrome_test_util::OpenNewTab();
|
| + [[GREYConfiguration sharedInstance]
|
| + setValue:@(NO)
|
| + forConfigKey:kGREYConfigKeySynchronizationEnabled];
|
| + chrome_test_util::LoadUrl(slowURL);
|
| +
|
| + // Ensure loading starts but is not finished.
|
| + base::test::ios::SpinRunLoopWithMaxDelay(base::TimeDelta::FromSeconds(1));
|
| + chrome_test_util::SelectTabAtIndexInCurrentMode(0);
|
| + [[GREYConfiguration sharedInstance]
|
| + setValue:@(YES)
|
| + forConfigKey:kGREYConfigKeySynchronizationEnabled];
|
| +
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| + histogramTester.ExpectBucketCount(kDidUserWaitForEvictedTabReload,
|
| + TabUsageRecorder::USER_LEFT_CHROME, 0,
|
| + failureBlock);
|
| +}
|
| +
|
| +// Tests that redirecting pages are not reloaded after eviction.
|
| +- (void)testPageRedirect {
|
| + GURL redirectURL = web::test::HttpServer::MakeUrl(
|
| + "http://ios/testing/data/http_server_files/redirect_refresh.html");
|
| + GURL destinationURL = web::test::HttpServer::MakeUrl(
|
| + "http://ios/testing/data/http_server_files/destination.html");
|
| + web::test::SetUpFileBasedHttpServer();
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + ResetTabUsageRecorder();
|
| +
|
| + NewMainTabWithURL(redirectURL, "arrived");
|
| +
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::omniboxText(
|
| + destinationURL.GetContent())]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + NSUInteger tabIndex = chrome_test_util::GetMainTabCount() - 1;
|
| + chrome_test_util::OpenNewTab();
|
| + OpenNewIncognitoTabUsingUIAndEvictMainTabs();
|
| + SwitchToNormalMode();
|
| + chrome_test_util::SelectTabAtIndexInCurrentMode(tabIndex);
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + "arrived")]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| + // Verify that one page-load count has been recorded. It should contain a
|
| + // sum of 1 - one sample with 1 page load.
|
| + histogramTester.ExpectTotalCount(kPageLoadsBeforeEvictedTabSelected, 1,
|
| + failureBlock);
|
| +
|
| + std::unique_ptr<base::HistogramSamples> samples =
|
| + histogramTester.GetHistogramSamplesSinceCreation(
|
| + kPageLoadsBeforeEvictedTabSelected);
|
| + int sampleSum = samples->sum();
|
| + GREYAssertEqual(
|
| + sampleSum, 1,
|
| + [NSString stringWithFormat:@"Expected page loads is %d, actual is %d.", 1,
|
| + sampleSum]);
|
| +}
|
| +
|
| +// Tests that navigations are correctly reported in
|
| +// Tab.PageLoadsSinceLastSwitchToEvictedTab histogram.
|
| +- (void)testLinkClickNavigation {
|
| + // Create map of canned responses and set up the test HTML server.
|
| + std::map<GURL, std::string> responses;
|
| + const GURL initialURL =
|
| + web::test::HttpServer::MakeUrl("http://scenarioTestLinkClickNavigation");
|
| + const GURL destinationURL =
|
| + web::test::HttpServer::MakeUrl("http://destination");
|
| + responses[initialURL] = base::StringPrintf(
|
| + "<body><a style='margin-left:50px' href='%s' id='link'>link</a></body>",
|
| + destinationURL.spec().c_str());
|
| + responses[destinationURL] = "Whee!";
|
| + web::test::SetUpHttpServer(base::MakeUnique<HtmlResponseProvider>(responses));
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + ResetTabUsageRecorder();
|
| +
|
| + // Open a tab with a link to click.
|
| + NewMainTabWithURL(initialURL, "link");
|
| + // Click the link.
|
| + chrome_test_util::TapWebViewElementWithId("link");
|
| +
|
| + [[EarlGrey
|
| + selectElementWithMatcher:chrome_test_util::webViewContainingText("Whee")]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + NSUInteger tabIndex = chrome_test_util::GetMainTabCount() - 1;
|
| + chrome_test_util::OpenNewTab();
|
| + OpenNewIncognitoTabUsingUIAndEvictMainTabs();
|
| + SwitchToNormalMode();
|
| + chrome_test_util::SelectTabAtIndexInCurrentMode(tabIndex);
|
| + [[EarlGrey
|
| + selectElementWithMatcher:chrome_test_util::webViewContainingText("Whee")]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + // Verify that the page-load count has been recorded. It should contain a
|
| + // sum of 2 - one sample with 2 page loads.
|
| + std::unique_ptr<base::HistogramSamples> samples =
|
| + histogramTester.GetHistogramSamplesSinceCreation(
|
| + kPageLoadsBeforeEvictedTabSelected);
|
| + int sampleSum = samples->sum();
|
| + GREYAssertEqual(
|
| + sampleSum, 2,
|
| + [NSString stringWithFormat:@"Expected page loads is %d, actual %d.", 2,
|
| + sampleSum]);
|
| +
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| + // Verify that only one evicted tab was selected. This is to make sure the
|
| + // link click did not generate an evicted-tab-reload count.
|
| + histogramTester.ExpectBucketCount(kSelectedTabHistogramName,
|
| + TabUsageRecorder::EVICTED, 1, failureBlock);
|
| +}
|
| +
|
| +// Tests that opening links in a new tab will not evict the source tab.
|
| +- (void)testOpenLinkInNewTab {
|
| + // Create map of canned responses and set up the test HTML server.
|
| + std::map<GURL, std::string> responses;
|
| + const GURL initialURL =
|
| + web::test::HttpServer::MakeUrl("http://scenarioTestOpenLinkInNewTab");
|
| + const GURL destinationURL =
|
| + web::test::HttpServer::MakeUrl("http://destination");
|
| + // Make the link that cover the whole page so that long pressing the web view
|
| + // will trigger the link context menu.
|
| + responses[initialURL] = base::StringPrintf(
|
| + "<body style='width:auto; height:auto;'><a href='%s' "
|
| + "id='link'><div style='width:100%%; "
|
| + "height:100%%;'>link</div></a></body>",
|
| + destinationURL.spec().c_str());
|
| + responses[destinationURL] = "Whee!";
|
| + web::test::SetUpHttpServer(base::MakeUnique<HtmlResponseProvider>(responses));
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + ResetTabUsageRecorder();
|
| +
|
| + // Open a tab with a link to click.
|
| + NewMainTabWithURL(initialURL, "link");
|
| +
|
| + int numberOfTabs = chrome_test_util::GetMainTabCount();
|
| + [[EarlGrey
|
| + selectElementWithMatcher:chrome_test_util::webViewContainingText("link")]
|
| + performAction:grey_longPress()];
|
| +
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_text(l10n_util::GetNSString(
|
| + IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB))]
|
| + performAction:grey_tap()];
|
| + chrome_test_util::AssertMainTabCount(numberOfTabs + 1);
|
| +
|
| + SelectTabUsingUI(base::SysUTF8ToNSString(destinationURL.GetContent()));
|
| +
|
| + [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:chrome_test_util::webViewContainingText("Whee")]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| + histogramTester.ExpectTotalCount(kSelectedTabHistogramName, 1, failureBlock);
|
| + histogramTester.ExpectBucketCount(
|
| + kSelectedTabHistogramName, TabUsageRecorder::IN_MEMORY, 1, failureBlock);
|
| +}
|
| +
|
| +// Tests that opening tabs from external app will not cause tab eviction.
|
| +- (void)testOpenFromApp {
|
| + web::test::SetUpFileBasedHttpServer();
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + ResetTabUsageRecorder();
|
| +
|
| + chrome_test_util::OpenNewTab();
|
| + GURL url(kTestUrl1);
|
| +
|
| + chrome_test_util::OpenChromeFromExternalApp(url);
|
| +
|
| + // Add a delay to ensure the tab has fully opened. Because the check below
|
| + // is for zero metrics recorded, it adds no flakiness. However, this pause
|
| + // makes the step more likely to fail in failure cases. I.e. without it, this
|
| + // test would sometimes pass even when it should fail.
|
| + base::test::ios::SpinRunLoopWithMaxDelay(
|
| + base::TimeDelta::FromMilliseconds(500));
|
| +
|
| + FailureBlock failureBlock = ^(NSString* error) {
|
| + GREYFail(error);
|
| + };
|
| + // Verify that zero Tab.StatusWhenSwitchedBackToForeground metrics were
|
| + // recorded. Tabs created at the time the user switches to them should not
|
| + // be counted in this metric.
|
| + histogramTester.ExpectTotalCount(kSelectedTabHistogramName, 0, failureBlock);
|
| +}
|
| +
|
| +// Verify that evicted tabs that are deleted are removed from the evicted tabs
|
| +// map.
|
| +- (void)testTabDeletion {
|
| + web::test::SetUpFileBasedHttpServer();
|
| + chrome_test_util::HistogramTester histogramTester;
|
| + ResetTabUsageRecorder();
|
| + // Add an autorelease pool to delete the closed tabs before the end of the
|
| + // test.
|
| + @autoreleasepool {
|
| + // Open two tabs with urls.
|
| + OpenTwoTabs();
|
| + // Set the normal tabs as 'cold start' tabs.
|
| + chrome_test_util::SetCurrentTabsToBeColdStartTabs();
|
| + // One more tab.
|
| + const GURL url1 = web::test::HttpServer::MakeUrl(kTestUrl1);
|
| + NewMainTabWithURL(url1, kURL1FirstWord);
|
| +
|
| + GREYAssertEqual(chrome_test_util::GetMainTabCount(), 3,
|
| + @"Check number of normal tabs");
|
| + // The cold start tab which was not active will still be evicted.
|
| + GREYAssertEqual(chrome_test_util::GetEvictedMainTabCount(), 1,
|
| + @"Check number of evicted tabs");
|
| +
|
| + // Close two of the three open tabs without selecting them first.
|
| + // This should delete the tab objects, even though they're still being
|
| + // tracked
|
| + // by the tab usage recorder in its |evicted_tabs_| map.
|
| + CloseTabAtIndexAndSync(1);
|
| +
|
| + GREYAssertEqual(chrome_test_util::GetMainTabCount(), 2,
|
| + @"Check number of normal tabs");
|
| + CloseTabAtIndexAndSync(0);
|
| + GREYAssertEqual(chrome_test_util::GetMainTabCount(), 1,
|
| + @"Check number of normal tabs");
|
| + [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
|
| + }
|
| + // The deleted tabs are purged during foregrounding and backgrounding.
|
| + chrome_test_util::SimulateTabsBackgrounding();
|
| + // Make sure |evicted_tabs_| purged the deleted tabs.
|
| + int evicted = chrome_test_util::GetEvictedMainTabCount();
|
| + GREYAssertEqual(evicted, 0, @"Check number of evicted tabs");
|
| +}
|
| +
|
| +@end
|
|
|