blob: 16b1a420adab108fe20af5f221933372a508e3d7 [file] [log] [blame]
// 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/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
#include "components/infobars/core/infobar.h"
#include "components/infobars/core/infobar_manager.h"
#import "ios/chrome/app/main_controller.h"
#include "ios/chrome/browser/infobars/infobar_manager_impl.h"
#import "ios/chrome/browser/tabs/tab.h"
#import "ios/chrome/browser/tabs/tab_model.h"
#import "ios/chrome/test/app/chrome_test_util.h"
#import "ios/chrome/test/app/tab_test_util.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
#import "ios/chrome/test/earl_grey/chrome_matchers.h"
#import "ios/chrome/test/earl_grey/chrome_test_case.h"
#import "ios/web/public/test/http_server/http_server.h"
#include "ios/web/public/test/http_server/http_server_util.h"
#include "url/gurl.h"
#include "url/url_constants.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// The title of the test infobar.
const char kTestInfoBarTitle[] = "TestInfoBar";
// Timeout for how long to wait for an infobar to appear or disapper.
const CFTimeInterval kTimeout = 4.0;
// An infobar that displays a single line of text and no buttons.
class TestInfoBarDelegate : public ConfirmInfoBarDelegate {
public:
static bool Create(infobars::InfoBarManager* infobar_manager);
// InfoBarDelegate implementation.
InfoBarIdentifier GetIdentifier() const override { return TEST_INFOBAR; }
// ConfirmInfoBarDelegate implementation.
base::string16 GetMessageText() const override {
return base::ASCIIToUTF16(kTestInfoBarTitle);
}
int GetButtons() const override {
return ConfirmInfoBarDelegate::BUTTON_NONE;
}
};
bool TestInfoBarDelegate::Create(infobars::InfoBarManager* infobar_manager) {
DCHECK(infobar_manager);
return !!infobar_manager->AddInfoBar(infobar_manager->CreateConfirmInfoBar(
std::unique_ptr<ConfirmInfoBarDelegate>(new TestInfoBarDelegate)));
}
// Returns the InfoBarManager for the current tab. Only works in normal
// (non-incognito) mode.
infobars::InfoBarManager* GetCurrentInfoBarManager() {
MainController* main_controller = chrome_test_util::GetMainController();
web::WebState* webState =
[[[[main_controller browserViewInformation] mainTabModel] currentTab]
webState];
if (webState) {
return InfoBarManagerImpl::FromWebState(webState);
}
return nullptr;
}
// Adds a TestInfoBar to the current tab.
bool AddTestInfoBarToCurrentTab() {
infobars::InfoBarManager* manager = GetCurrentInfoBarManager();
return TestInfoBarDelegate::Create(manager);
}
// Verifies that a single TestInfoBar is either present or absent on the current
// tab.
void VerifyTestInfoBarVisibleForCurrentTab(bool visible) {
// Expected values.
bool expected_count = visible ? 1U : 0U;
id<GREYMatcher> expected_visibility =
visible ? grey_sufficientlyVisible() : grey_notVisible();
NSString* condition_name =
visible ? @"Waiting for infobar to show" : @"Waiting for infobar to hide";
infobars::InfoBarManager* manager = GetCurrentInfoBarManager();
GREYAssertEqual(expected_count, manager->infobar_count(),
@"Incorrect number of infobars.");
[[GREYCondition
conditionWithName:condition_name
block:^BOOL {
NSError* error = nil;
[[EarlGrey
selectElementWithMatcher:
chrome_test_util::StaticTextWithAccessibilityLabel(
base::SysUTF8ToNSString(kTestInfoBarTitle))]
assertWithMatcher:expected_visibility
error:&error];
return error == nil;
}] waitWithTimeout:kTimeout];
}
} // namespace
// Tests functionality related to infobars.
@interface InfobarTestCase : ChromeTestCase
@end
@implementation InfobarTestCase
// Tests that page infobars don't persist on navigation.
- (void)testInfobarsDismissOnNavigate {
web::test::SetUpFileBasedHttpServer();
// Open a new tab and navigate to the test page.
const GURL testURL = web::test::HttpServer::MakeUrl(
"http://ios/testing/data/http_server_files/pony.html");
[ChromeEarlGrey loadURL:testURL];
[ChromeEarlGrey waitForMainTabCount:1];
// Add a test infobar to the current tab. Verify that the infobar is present
// in the model and that the infobar view is visible on screen.
GREYAssert(AddTestInfoBarToCurrentTab(),
@"Failed to add infobar to test tab.");
VerifyTestInfoBarVisibleForCurrentTab(true);
// Navigate to a different page. Verify that the infobar is dismissed and no
// longer visible on screen.
[ChromeEarlGrey loadURL:GURL(url::kAboutBlankURL)];
VerifyTestInfoBarVisibleForCurrentTab(false);
}
// Tests that page infobars persist only on the tabs they are opened on, and
// that navigation in other tabs doesn't affect them.
- (void)testInfobarTabSwitch {
const GURL destinationURL = web::test::HttpServer::MakeUrl(
"http://ios/testing/data/http_server_files/destination.html");
const GURL ponyURL = web::test::HttpServer::MakeUrl(
"http://ios/testing/data/http_server_files/pony.html");
web::test::SetUpFileBasedHttpServer();
// Create the first tab and navigate to the test page.
[ChromeEarlGrey loadURL:destinationURL];
[ChromeEarlGrey waitForMainTabCount:1];
// Create the second tab, navigate to the test page, and add the test infobar.
chrome_test_util::OpenNewTab();
[ChromeEarlGrey loadURL:ponyURL];
[ChromeEarlGrey waitForMainTabCount:2];
VerifyTestInfoBarVisibleForCurrentTab(false);
GREYAssert(AddTestInfoBarToCurrentTab(),
@"Failed to add infobar to second tab.");
VerifyTestInfoBarVisibleForCurrentTab(true);
// Switch back to the first tab and make sure no infobar is visible.
chrome_test_util::SelectTabAtIndexInCurrentMode(0U);
VerifyTestInfoBarVisibleForCurrentTab(false);
// Navigate to a different URL in the first tab, to verify that this
// navigation does not hide the infobar in the second tab.
[ChromeEarlGrey loadURL:ponyURL];
// Close the first tab. Verify that there is only one tab remaining and its
// infobar is visible.
chrome_test_util::CloseCurrentTab();
[ChromeEarlGrey waitForMainTabCount:1];
VerifyTestInfoBarVisibleForCurrentTab(true);
}
@end