content/test: Add new functionality to TestNavigationObserver
Adds three features to TestNavigationObserver: 1. A new constructor that takes a |target_url|. When TestNavigationObserver is instantiated with this constructor Wait/WaitForNavigationFinished will quit when a navigation to target_url has loaded or finished. 2. WaitForNavigationFinished. TestNavigationObserver will wait for navigations to finish rather than waiting for loading to stop. 3. WatchExistingWebContents. Adds TestNavigationObserver as an observer of all previously created WebContents. Change-Id: Ic11098dd77dcdca9e3f144c9afea9eff90727348 Reviewed-on: https://chromium-review.googlesource.com/706741 Commit-Queue: Giovanni Ortuño Urquidi <ortuno@chromium.org> Reviewed-by: Scott Violet <sky@chromium.org> Cr-Commit-Position: refs/heads/master@{#507872}
This commit is contained in:

committed by
Commit Bot

parent
65e7acb2c5
commit
436c1fabb9
chrome/browser/extensions
content/public/test
@ -25,6 +25,7 @@
|
||||
#include "content/public/common/context_menu_params.h"
|
||||
#include "content/public/test/browser_test_utils.h"
|
||||
#include "content/public/test/test_frame_navigation_observer.h"
|
||||
#include "content/public/test/test_navigation_observer.h"
|
||||
#include "content/public/test/test_utils.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/browser/notification_types.h"
|
||||
@ -57,6 +58,14 @@ std::string CreateClientRedirect(const GURL& target_url) {
|
||||
net::EscapeQueryParamValue(target_url.spec(), false);
|
||||
}
|
||||
|
||||
std::unique_ptr<content::TestNavigationObserver> GetTestNavigationObserver(
|
||||
const GURL& target_url) {
|
||||
auto observer = std::make_unique<content::TestNavigationObserver>(target_url);
|
||||
observer->WatchExistingWebContents();
|
||||
observer->StartWatchingNewWebContents();
|
||||
return observer;
|
||||
}
|
||||
|
||||
// Inserts an iframe in the main frame of |web_contents|.
|
||||
void InsertIFrame(content::WebContents* web_contents) {
|
||||
ASSERT_TRUE(
|
||||
@ -82,12 +91,11 @@ content::RenderFrameHost* GetIFrame(content::WebContents* web_contents) {
|
||||
// Creates an <a> element, sets its href and target to |link_url| and |target|
|
||||
// respectively, adds it to the DOM, and clicks on it. Returns once |target_url|
|
||||
// has loaded.
|
||||
void ClickLinkAndWaitForURLLoad(content::WebContents* web_contents,
|
||||
const GURL& link_url,
|
||||
const GURL& target_url,
|
||||
LinkTarget target) {
|
||||
ui_test_utils::UrlLoadObserver url_observer(
|
||||
target_url, content::NotificationService::AllSources());
|
||||
void ClickLinkAndWaitForURL(content::WebContents* web_contents,
|
||||
const GURL& link_url,
|
||||
const GURL& target_url,
|
||||
LinkTarget target) {
|
||||
auto observer = GetTestNavigationObserver(target_url);
|
||||
std::string script = base::StringPrintf(
|
||||
"(() => {"
|
||||
"const link = document.createElement('a');"
|
||||
@ -99,7 +107,7 @@ void ClickLinkAndWaitForURLLoad(content::WebContents* web_contents,
|
||||
"})();",
|
||||
link_url.spec().c_str(), target == LinkTarget::SELF ? "_self" : "_blank");
|
||||
ASSERT_TRUE(content::ExecuteScript(web_contents, script));
|
||||
url_observer.Wait();
|
||||
observer->WaitForNavigationFinished();
|
||||
}
|
||||
|
||||
// Creates an <a> element, sets its href and target to |link_url| and |target|
|
||||
@ -108,7 +116,7 @@ void ClickLinkAndWaitForURLLoad(content::WebContents* web_contents,
|
||||
void ClickLinkAndWait(content::WebContents* web_contents,
|
||||
const GURL& link_url,
|
||||
LinkTarget target) {
|
||||
ClickLinkAndWaitForURLLoad(web_contents, link_url, link_url, target);
|
||||
ClickLinkAndWaitForURL(web_contents, link_url, link_url, target);
|
||||
}
|
||||
|
||||
// Creates a <form> element with a |target_url| action and |method| method. Adds
|
||||
@ -126,8 +134,7 @@ void SubmitFormAndWait(content::WebContents* web_contents,
|
||||
ASSERT_TRUE(target_url.query().empty());
|
||||
}
|
||||
|
||||
ui_test_utils::UrlLoadObserver url_observer(
|
||||
target_url, content::NotificationService::AllSources());
|
||||
auto observer = GetTestNavigationObserver(target_url);
|
||||
std::string script = base::StringPrintf(
|
||||
"(() => {"
|
||||
"const form = document.createElement('form');"
|
||||
@ -142,15 +149,14 @@ void SubmitFormAndWait(content::WebContents* web_contents,
|
||||
target_url.spec().c_str(),
|
||||
method == net::URLFetcher::RequestType::POST ? "post" : "get");
|
||||
ASSERT_TRUE(content::ExecuteScript(web_contents, script));
|
||||
url_observer.Wait();
|
||||
observer->WaitForNavigationFinished();
|
||||
}
|
||||
|
||||
// Uses |params| to navigate to a URL. Blocks until the URL is loaded.
|
||||
void NavigateToURLAndWait(chrome::NavigateParams* params) {
|
||||
ui_test_utils::UrlLoadObserver url_observer(
|
||||
params->url, content::NotificationService::AllSources());
|
||||
auto observer = GetTestNavigationObserver(params->url);
|
||||
ui_test_utils::NavigateToURL(params);
|
||||
url_observer.Wait();
|
||||
observer->WaitForNavigationFinished();
|
||||
}
|
||||
|
||||
// Wrapper so that we can use base::Bind with NavigateToURL.
|
||||
@ -221,14 +227,13 @@ class BookmarkAppNavigationThrottleBrowserTest : public ExtensionBrowserTest {
|
||||
|
||||
Browser* OpenTestBookmarkApp() {
|
||||
GURL app_url = embedded_test_server()->GetURL(kAppUrlPath);
|
||||
ui_test_utils::UrlLoadObserver url_observer(
|
||||
app_url, content::NotificationService::AllSources());
|
||||
auto observer = GetTestNavigationObserver(app_url);
|
||||
|
||||
OpenApplication(AppLaunchParams(
|
||||
profile(), test_bookmark_app_, extensions::LAUNCH_CONTAINER_WINDOW,
|
||||
WindowOpenDisposition::CURRENT_TAB, SOURCE_CHROME_INTERNAL));
|
||||
|
||||
url_observer.Wait();
|
||||
observer->WaitForNavigationFinished();
|
||||
|
||||
return chrome::FindLastActive();
|
||||
}
|
||||
@ -510,7 +515,7 @@ IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleBrowserTest,
|
||||
const GURL redirecting_url = embedded_test_server()->GetURL(
|
||||
"localhost", CreateServerRedirect(app_url));
|
||||
TestTabActionOpensAppWindow(
|
||||
app_url, base::Bind(&ClickLinkAndWaitForURLLoad,
|
||||
app_url, base::Bind(&ClickLinkAndWaitForURL,
|
||||
browser()->tab_strip_model()->GetActiveWebContents(),
|
||||
redirecting_url, app_url, LinkTarget::SELF));
|
||||
}
|
||||
@ -531,9 +536,8 @@ IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleBrowserTest,
|
||||
const GURL app_url = embedded_test_server()->GetURL(kAppUrlPath);
|
||||
const GURL redirecting_url = embedded_test_server()->GetURL(
|
||||
"localhost", CreateClientRedirect(app_url));
|
||||
ClickLinkAndWaitForURLLoad(
|
||||
browser()->tab_strip_model()->GetActiveWebContents(), redirecting_url,
|
||||
app_url, LinkTarget::SELF);
|
||||
ClickLinkAndWaitForURL(browser()->tab_strip_model()->GetActiveWebContents(),
|
||||
redirecting_url, app_url, LinkTarget::SELF);
|
||||
|
||||
EXPECT_EQ(num_tabs, browser()->tab_strip_model()->count());
|
||||
EXPECT_EQ(++num_browsers, chrome::GetBrowserCount(profile()));
|
||||
@ -676,8 +680,7 @@ IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleBrowserTest,
|
||||
GURL initial_url = initial_tab->GetLastCommittedURL();
|
||||
|
||||
const GURL in_scope_url = embedded_test_server()->GetURL(kInScopeUrlPath);
|
||||
ui_test_utils::UrlLoadObserver url_observer(
|
||||
in_scope_url, content::NotificationService::AllSources());
|
||||
auto observer = GetTestNavigationObserver(in_scope_url);
|
||||
content::ContextMenuParams params;
|
||||
params.page_url = initial_url;
|
||||
params.link_url = in_scope_url;
|
||||
@ -685,7 +688,7 @@ IN_PROC_BROWSER_TEST_F(BookmarkAppNavigationThrottleBrowserTest,
|
||||
menu.Init();
|
||||
menu.ExecuteCommand(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD,
|
||||
0 /* event_flags */);
|
||||
url_observer.Wait();
|
||||
observer->WaitForNavigationFinished();
|
||||
|
||||
Browser* incognito_browser = chrome::FindLastActive();
|
||||
EXPECT_EQ(incognito_browser->profile(), profile()->GetOffTheRecordProfile());
|
||||
|
@ -69,24 +69,24 @@ TestNavigationObserver::TestNavigationObserver(
|
||||
WebContents* web_contents,
|
||||
int number_of_navigations,
|
||||
MessageLoopRunner::QuitMode quit_mode)
|
||||
: navigation_started_(false),
|
||||
navigations_completed_(0),
|
||||
number_of_navigations_(number_of_navigations),
|
||||
last_navigation_succeeded_(false),
|
||||
last_net_error_code_(net::OK),
|
||||
message_loop_runner_(new MessageLoopRunner(quit_mode)),
|
||||
web_contents_created_callback_(
|
||||
base::Bind(&TestNavigationObserver::OnWebContentsCreated,
|
||||
base::Unretained(this))) {
|
||||
if (web_contents)
|
||||
RegisterAsObserver(web_contents);
|
||||
}
|
||||
: TestNavigationObserver(web_contents,
|
||||
number_of_navigations,
|
||||
GURL(),
|
||||
quit_mode) {}
|
||||
|
||||
TestNavigationObserver::TestNavigationObserver(
|
||||
WebContents* web_contents,
|
||||
MessageLoopRunner::QuitMode quit_mode)
|
||||
: TestNavigationObserver(web_contents, 1, quit_mode) {}
|
||||
|
||||
TestNavigationObserver::TestNavigationObserver(
|
||||
const GURL& target_url,
|
||||
MessageLoopRunner::QuitMode quit_mode)
|
||||
: TestNavigationObserver(nullptr,
|
||||
-1 /* num_of_navigations */,
|
||||
target_url,
|
||||
quit_mode) {}
|
||||
|
||||
TestNavigationObserver::~TestNavigationObserver() {
|
||||
StopWatchingNewWebContents();
|
||||
}
|
||||
@ -95,6 +95,11 @@ void TestNavigationObserver::Wait() {
|
||||
message_loop_runner_->Run();
|
||||
}
|
||||
|
||||
void TestNavigationObserver::WaitForNavigationFinished() {
|
||||
wait_event_ = WaitEvent::kNavigationFinished;
|
||||
message_loop_runner_->Run();
|
||||
}
|
||||
|
||||
void TestNavigationObserver::StartWatchingNewWebContents() {
|
||||
WebContentsImpl::FriendWrapper::AddCreatedCallbackForTesting(
|
||||
web_contents_created_callback_);
|
||||
@ -105,11 +110,36 @@ void TestNavigationObserver::StopWatchingNewWebContents() {
|
||||
web_contents_created_callback_);
|
||||
}
|
||||
|
||||
void TestNavigationObserver::WatchExistingWebContents() {
|
||||
for (auto* web_contents : WebContentsImpl::GetAllWebContents())
|
||||
RegisterAsObserver(web_contents);
|
||||
}
|
||||
|
||||
void TestNavigationObserver::RegisterAsObserver(WebContents* web_contents) {
|
||||
web_contents_observers_.insert(
|
||||
base::MakeUnique<TestWebContentsObserver>(this, web_contents));
|
||||
}
|
||||
|
||||
TestNavigationObserver::TestNavigationObserver(
|
||||
WebContents* web_contents,
|
||||
int number_of_navigations,
|
||||
const GURL& target_url,
|
||||
MessageLoopRunner::QuitMode quit_mode)
|
||||
: wait_event_(WaitEvent::kLoadStopped),
|
||||
navigation_started_(false),
|
||||
navigations_completed_(0),
|
||||
number_of_navigations_(number_of_navigations),
|
||||
target_url_(target_url),
|
||||
last_navigation_succeeded_(false),
|
||||
last_net_error_code_(net::OK),
|
||||
message_loop_runner_(new MessageLoopRunner(quit_mode)),
|
||||
web_contents_created_callback_(
|
||||
base::Bind(&TestNavigationObserver::OnWebContentsCreated,
|
||||
base::Unretained(this))) {
|
||||
if (web_contents)
|
||||
RegisterAsObserver(web_contents);
|
||||
}
|
||||
|
||||
void TestNavigationObserver::OnWebContentsCreated(WebContents* web_contents) {
|
||||
RegisterAsObserver(web_contents);
|
||||
}
|
||||
@ -146,11 +176,8 @@ void TestNavigationObserver::OnDidStopLoading(WebContents* web_contents) {
|
||||
if (!navigation_started_)
|
||||
return;
|
||||
|
||||
++navigations_completed_;
|
||||
if (navigations_completed_ == number_of_navigations_) {
|
||||
navigation_started_ = false;
|
||||
message_loop_runner_->Quit();
|
||||
}
|
||||
if (wait_event_ == WaitEvent::kLoadStopped)
|
||||
EventTriggered();
|
||||
}
|
||||
|
||||
void TestNavigationObserver::OnDidStartNavigation() {
|
||||
@ -163,6 +190,25 @@ void TestNavigationObserver::OnDidFinishNavigation(bool is_error_page,
|
||||
last_navigation_url_ = url;
|
||||
last_navigation_succeeded_ = !is_error_page;
|
||||
last_net_error_code_ = error_code;
|
||||
|
||||
if (wait_event_ == WaitEvent::kNavigationFinished)
|
||||
EventTriggered();
|
||||
}
|
||||
|
||||
void TestNavigationObserver::EventTriggered() {
|
||||
if (target_url_ == GURL()) {
|
||||
DCHECK_GE(navigations_completed_, 0);
|
||||
|
||||
++navigations_completed_;
|
||||
if (navigations_completed_ != number_of_navigations_) {
|
||||
return;
|
||||
}
|
||||
} else if (target_url_ != last_navigation_url_) {
|
||||
return;
|
||||
}
|
||||
|
||||
navigation_started_ = false;
|
||||
message_loop_runner_->Quit();
|
||||
}
|
||||
|
||||
} // namespace content
|
||||
|
@ -21,6 +21,11 @@ class WebContents;
|
||||
// MessageLoop and quit when the navigation completes loading.
|
||||
class TestNavigationObserver {
|
||||
public:
|
||||
enum class WaitEvent {
|
||||
kLoadStopped,
|
||||
kNavigationFinished,
|
||||
};
|
||||
|
||||
// Create and register a new TestNavigationObserver against the
|
||||
// |web_contents|.
|
||||
TestNavigationObserver(WebContents* web_contents,
|
||||
@ -31,17 +36,31 @@ class TestNavigationObserver {
|
||||
explicit TestNavigationObserver(WebContents* web_contents,
|
||||
MessageLoopRunner::QuitMode quit_mode =
|
||||
MessageLoopRunner::QuitMode::IMMEDIATE);
|
||||
// Create and register a new TestNavigationObserver that will wait for
|
||||
// |target_url| to complete loading or for a committed navigation to
|
||||
// |target_url|.
|
||||
explicit TestNavigationObserver(const GURL& target_url,
|
||||
MessageLoopRunner::QuitMode quit_mode =
|
||||
MessageLoopRunner::QuitMode::IMMEDIATE);
|
||||
|
||||
virtual ~TestNavigationObserver();
|
||||
|
||||
// Runs a nested run loop and blocks until the expected number of
|
||||
// navigations are complete.
|
||||
// Runs a nested run loop and blocks until the expected number of navigations
|
||||
// stop loading or |target_url| has loaded.
|
||||
void Wait();
|
||||
|
||||
// Runs a nested run loop and blocks until the expected number of navigations
|
||||
// finished or a navigation to |target_url| has finished.
|
||||
void WaitForNavigationFinished();
|
||||
|
||||
// Start/stop watching newly created WebContents.
|
||||
void StartWatchingNewWebContents();
|
||||
void StopWatchingNewWebContents();
|
||||
|
||||
// Makes this TestNavigationObserver an observer of all previously created
|
||||
// WebContents.
|
||||
void WatchExistingWebContents();
|
||||
|
||||
const GURL& last_navigation_url() const { return last_navigation_url_; }
|
||||
|
||||
bool last_navigation_succeeded() const { return last_navigation_succeeded_; }
|
||||
@ -55,6 +74,12 @@ class TestNavigationObserver {
|
||||
private:
|
||||
class TestWebContentsObserver;
|
||||
|
||||
TestNavigationObserver(WebContents* web_contents,
|
||||
int number_of_navigations,
|
||||
const GURL& target_url,
|
||||
MessageLoopRunner::QuitMode quit_mode =
|
||||
MessageLoopRunner::QuitMode::IMMEDIATE);
|
||||
|
||||
// Callbacks for WebContents-related events.
|
||||
void OnWebContentsCreated(WebContents* web_contents);
|
||||
void OnWebContentsDestroyed(TestWebContentsObserver* observer,
|
||||
@ -70,6 +95,10 @@ class TestNavigationObserver {
|
||||
void OnDidFinishNavigation(bool is_error_page,
|
||||
const GURL& url,
|
||||
net::Error error_code);
|
||||
void EventTriggered();
|
||||
|
||||
// The event that once triggered will quit the run loop.
|
||||
WaitEvent wait_event_;
|
||||
|
||||
// If true the navigation has started.
|
||||
bool navigation_started_;
|
||||
@ -80,6 +109,9 @@ class TestNavigationObserver {
|
||||
// The number of navigations to wait for.
|
||||
int number_of_navigations_;
|
||||
|
||||
// The URL to wait for.
|
||||
const GURL target_url_;
|
||||
|
||||
// The url of the navigation that last committed.
|
||||
GURL last_navigation_url_;
|
||||
|
||||
|
Reference in New Issue
Block a user