Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(805)

Side by Side Diff: chrome/test/base/ui_test_utils.cc

Issue 10479018: Add base::RunLoop and update ui_test_utils to use it to reduce flakiness (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: win compile Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/test/base/ui_test_utils.h" 5 #include "chrome/test/base/ui_test_utils.h"
6 6
7 #if defined(OS_WIN) 7 #if defined(OS_WIN)
8 #include <windows.h> 8 #include <windows.h>
9 #endif 9 #endif
10 10
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 using content::NavigationController; 86 using content::NavigationController;
87 using content::NavigationEntry; 87 using content::NavigationEntry;
88 using content::OpenURLParams; 88 using content::OpenURLParams;
89 using content::RenderViewHost; 89 using content::RenderViewHost;
90 using content::RenderWidgetHost; 90 using content::RenderWidgetHost;
91 using content::Referrer; 91 using content::Referrer;
92 using content::WebContents; 92 using content::WebContents;
93 93
94 static const int kDefaultWsPort = 8880; 94 static const int kDefaultWsPort = 8880;
95 95
96 // Number of times to repost a Quit task so that the MessageLoop finishes up
97 // pending tasks and tasks posted by those pending tasks without risking the
98 // potential hang behavior of MessageLoop::QuitWhenIdle.
99 // The criteria for choosing this number: it should be high enough to make the
100 // quit act like QuitWhenIdle, while taking into account that any page which is
101 // animating may be rendering another frame for each quit deferral. For an
102 // animating page, the potential delay to quitting the RunLoop would be
103 // kNumQuitDeferrals * frame_render_time. Some perf tests run slow, such as
104 // 200ms/frame.
105 static const int kNumQuitDeferrals = 10;
106
96 namespace ui_test_utils { 107 namespace ui_test_utils {
97 108
98 namespace { 109 namespace {
99 110
100 class DOMOperationObserver : public content::NotificationObserver, 111 class DOMOperationObserver : public content::NotificationObserver,
101 public content::WebContentsObserver { 112 public content::WebContentsObserver {
102 public: 113 public:
103 explicit DOMOperationObserver(RenderViewHost* render_view_host) 114 explicit DOMOperationObserver(RenderViewHost* render_view_host)
104 : content::WebContentsObserver( 115 : content::WebContentsObserver(
105 WebContents::FromRenderViewHost(render_view_host)), 116 WebContents::FromRenderViewHost(render_view_host)),
106 did_respond_(false) { 117 did_respond_(false) {
107 registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE, 118 registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE,
108 content::Source<RenderViewHost>(render_view_host)); 119 content::Source<RenderViewHost>(render_view_host));
109 ui_test_utils::RunMessageLoop(); 120 message_loop_runner_ = new MessageLoopRunner;
121 message_loop_runner_->Run();
110 } 122 }
111 123
112 virtual void Observe(int type, 124 virtual void Observe(int type,
113 const content::NotificationSource& source, 125 const content::NotificationSource& source,
114 const content::NotificationDetails& details) OVERRIDE { 126 const content::NotificationDetails& details) OVERRIDE {
115 DCHECK(type == content::NOTIFICATION_DOM_OPERATION_RESPONSE); 127 DCHECK(type == content::NOTIFICATION_DOM_OPERATION_RESPONSE);
116 content::Details<DomOperationNotificationDetails> dom_op_details(details); 128 content::Details<DomOperationNotificationDetails> dom_op_details(details);
117 response_ = dom_op_details->json; 129 response_ = dom_op_details->json;
118 did_respond_ = true; 130 did_respond_ = true;
119 MessageLoopForUI::current()->Quit(); 131 message_loop_runner_->Quit();
120 } 132 }
121 133
122 // Overridden from content::WebContentsObserver: 134 // Overridden from content::WebContentsObserver:
123 virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE { 135 virtual void RenderViewGone(base::TerminationStatus status) OVERRIDE {
124 MessageLoopForUI::current()->Quit(); 136 message_loop_runner_->Quit();
125 } 137 }
126 138
127 bool GetResponse(std::string* response) WARN_UNUSED_RESULT { 139 bool GetResponse(std::string* response) WARN_UNUSED_RESULT {
128 *response = response_; 140 *response = response_;
129 return did_respond_; 141 return did_respond_;
130 } 142 }
131 143
132 private: 144 private:
133 content::NotificationRegistrar registrar_; 145 content::NotificationRegistrar registrar_;
134 std::string response_; 146 std::string response_;
135 bool did_respond_; 147 bool did_respond_;
148 scoped_refptr<MessageLoopRunner> message_loop_runner_;
136 149
137 DISALLOW_COPY_AND_ASSIGN(DOMOperationObserver); 150 DISALLOW_COPY_AND_ASSIGN(DOMOperationObserver);
138 }; 151 };
139 152
140 class FindInPageNotificationObserver : public content::NotificationObserver { 153 class FindInPageNotificationObserver : public content::NotificationObserver {
141 public: 154 public:
142 explicit FindInPageNotificationObserver(TabContents* parent_tab) 155 explicit FindInPageNotificationObserver(TabContents* parent_tab)
143 : parent_tab_(parent_tab), 156 : parent_tab_(parent_tab),
144 active_match_ordinal_(-1), 157 active_match_ordinal_(-1),
145 number_of_matches_(0) { 158 number_of_matches_(0) {
146 current_find_request_id_ = 159 current_find_request_id_ =
147 parent_tab->find_tab_helper()->current_find_request_id(); 160 parent_tab->find_tab_helper()->current_find_request_id();
148 registrar_.Add(this, chrome::NOTIFICATION_FIND_RESULT_AVAILABLE, 161 registrar_.Add(this, chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
149 content::Source<WebContents>(parent_tab_->web_contents())); 162 content::Source<WebContents>(parent_tab_->web_contents()));
150 ui_test_utils::RunMessageLoop(); 163 message_loop_runner_ = new MessageLoopRunner;
164 message_loop_runner_->Run();
151 } 165 }
152 166
153 int active_match_ordinal() const { return active_match_ordinal_; } 167 int active_match_ordinal() const { return active_match_ordinal_; }
154 168
155 int number_of_matches() const { return number_of_matches_; } 169 int number_of_matches() const { return number_of_matches_; }
156 170
157 virtual void Observe(int type, const content::NotificationSource& source, 171 virtual void Observe(int type, const content::NotificationSource& source,
158 const content::NotificationDetails& details) { 172 const content::NotificationDetails& details) {
159 if (type == chrome::NOTIFICATION_FIND_RESULT_AVAILABLE) { 173 if (type == chrome::NOTIFICATION_FIND_RESULT_AVAILABLE) {
160 content::Details<FindNotificationDetails> find_details(details); 174 content::Details<FindNotificationDetails> find_details(details);
161 if (find_details->request_id() == current_find_request_id_) { 175 if (find_details->request_id() == current_find_request_id_) {
162 // We get multiple responses and one of those will contain the ordinal. 176 // We get multiple responses and one of those will contain the ordinal.
163 // This message comes to us before the final update is sent. 177 // This message comes to us before the final update is sent.
164 if (find_details->active_match_ordinal() > -1) 178 if (find_details->active_match_ordinal() > -1)
165 active_match_ordinal_ = find_details->active_match_ordinal(); 179 active_match_ordinal_ = find_details->active_match_ordinal();
166 if (find_details->final_update()) { 180 if (find_details->final_update()) {
167 number_of_matches_ = find_details->number_of_matches(); 181 number_of_matches_ = find_details->number_of_matches();
168 MessageLoopForUI::current()->Quit(); 182 message_loop_runner_->Quit();
169 } else { 183 } else {
170 DVLOG(1) << "Ignoring, since we only care about the final message"; 184 DVLOG(1) << "Ignoring, since we only care about the final message";
171 } 185 }
172 } 186 }
173 } else { 187 } else {
174 NOTREACHED(); 188 NOTREACHED();
175 } 189 }
176 } 190 }
177 191
178 private: 192 private:
179 content::NotificationRegistrar registrar_; 193 content::NotificationRegistrar registrar_;
180 TabContents* parent_tab_; 194 TabContents* parent_tab_;
181 // We will at some point (before final update) be notified of the ordinal and 195 // We will at some point (before final update) be notified of the ordinal and
182 // we need to preserve it so we can send it later. 196 // we need to preserve it so we can send it later.
183 int active_match_ordinal_; 197 int active_match_ordinal_;
184 int number_of_matches_; 198 int number_of_matches_;
185 // The id of the current find request, obtained from WebContents. Allows us 199 // The id of the current find request, obtained from WebContents. Allows us
186 // to monitor when the search completes. 200 // to monitor when the search completes.
187 int current_find_request_id_; 201 int current_find_request_id_;
202 scoped_refptr<MessageLoopRunner> message_loop_runner_;
188 203
189 DISALLOW_COPY_AND_ASSIGN(FindInPageNotificationObserver); 204 DISALLOW_COPY_AND_ASSIGN(FindInPageNotificationObserver);
190 }; 205 };
191 206
192 class InProcessJavaScriptExecutionController 207 class InProcessJavaScriptExecutionController
193 : public base::RefCounted<InProcessJavaScriptExecutionController>, 208 : public base::RefCounted<InProcessJavaScriptExecutionController>,
194 public JavaScriptExecutionController { 209 public JavaScriptExecutionController {
195 public: 210 public:
196 explicit InProcessJavaScriptExecutionController( 211 explicit InProcessJavaScriptExecutionController(
197 RenderViewHost* render_view_host) 212 RenderViewHost* render_view_host)
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 base::JSONReader reader(base::JSON_ALLOW_TRAILING_COMMAS); 271 base::JSONReader reader(base::JSON_ALLOW_TRAILING_COMMAS);
257 result->reset(reader.ReadToValue(json)); 272 result->reset(reader.ReadToValue(json));
258 if (!result->get()) { 273 if (!result->get()) {
259 DLOG(ERROR) << reader.GetErrorMessage(); 274 DLOG(ERROR) << reader.GetErrorMessage();
260 return false; 275 return false;
261 } 276 }
262 277
263 return true; 278 return true;
264 } 279 }
265 280
266 void RunAllPendingMessageAndSendQuit(content::BrowserThread::ID thread_id) { 281 void RunAllPendingMessageAndSendQuit(content::BrowserThread::ID thread_id,
267 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); 282 const base::Closure& quit_task) {
283 MessageLoop::current()->PostTask(FROM_HERE,
284 MessageLoop::QuitWhenIdleClosure());
268 RunMessageLoop(); 285 RunMessageLoop();
269 content::BrowserThread::PostTask(thread_id, FROM_HERE, 286 content::BrowserThread::PostTask(thread_id, FROM_HERE, quit_task);
270 MessageLoop::QuitClosure());
271 } 287 }
272 288
273 } // namespace 289 } // namespace
274 290
275 void RunMessageLoop() { 291 void RunMessageLoop() {
276 MessageLoop* loop = MessageLoop::current(); 292 base::RunLoop run_loop;
277 MessageLoopForUI* ui_loop = 293 RunThisRunLoop(&run_loop);
278 content::BrowserThread::CurrentlyOn(content::BrowserThread::UI) ? 294 }
279 MessageLoopForUI::current() : NULL; 295
280 MessageLoop::ScopedNestableTaskAllower allow(loop); 296 void RunThisRunLoop(base::RunLoop* run_loop) {
281 if (ui_loop) { 297 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
282 #if defined(USE_AURA) 298 #if !defined(USE_AURA) && defined(TOOLKIT_VIEWS)
283 ui_loop->Run(); 299 scoped_ptr<views::AcceleratorHandler> handler;
284 #elif defined(TOOLKIT_VIEWS) 300 if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
285 views::AcceleratorHandler handler; 301 handler.reset(new views::AcceleratorHandler);
286 ui_loop->RunWithDispatcher(&handler); 302 run_loop->set_dispatcher(handler.get());
287 #elif defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) 303 }
288 ui_loop->RunWithDispatcher(NULL);
289 #else
290 ui_loop->Run();
291 #endif 304 #endif
305 run_loop->Run();
306 }
307
308 static void DeferredQuitRunLoop(const base::Closure& quit_task,
309 int num_quit_deferrals) {
310 if (num_quit_deferrals <= 0) {
311 quit_task.Run();
292 } else { 312 } else {
293 loop->Run(); 313 MessageLoop::current()->PostTask(FROM_HERE,
314 base::Bind(&DeferredQuitRunLoop, quit_task, num_quit_deferrals - 1));
294 } 315 }
295 } 316 }
296 317
318 base::Closure GetQuitTaskForRunLoop(base::RunLoop* run_loop) {
319 return base::Bind(&DeferredQuitRunLoop, run_loop->QuitClosure(),
320 kNumQuitDeferrals);
321 }
322
297 void RunAllPendingInMessageLoop() { 323 void RunAllPendingInMessageLoop() {
298 MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); 324 MessageLoop::current()->PostTask(FROM_HERE,
325 MessageLoop::QuitWhenIdleClosure());
299 ui_test_utils::RunMessageLoop(); 326 ui_test_utils::RunMessageLoop();
300 } 327 }
301 328
302 void RunAllPendingInMessageLoop(content::BrowserThread::ID thread_id) { 329 void RunAllPendingInMessageLoop(content::BrowserThread::ID thread_id) {
303 if (content::BrowserThread::CurrentlyOn(thread_id)) { 330 if (content::BrowserThread::CurrentlyOn(thread_id)) {
304 RunAllPendingInMessageLoop(); 331 RunAllPendingInMessageLoop();
305 return; 332 return;
306 } 333 }
307 content::BrowserThread::ID current_thread_id; 334 content::BrowserThread::ID current_thread_id;
308 if (!content::BrowserThread::GetCurrentThreadIdentifier(&current_thread_id)) { 335 if (!content::BrowserThread::GetCurrentThreadIdentifier(&current_thread_id)) {
309 NOTREACHED(); 336 NOTREACHED();
310 return; 337 return;
311 } 338 }
339
340 base::RunLoop run_loop;
312 content::BrowserThread::PostTask(thread_id, FROM_HERE, 341 content::BrowserThread::PostTask(thread_id, FROM_HERE,
313 base::Bind(&RunAllPendingMessageAndSendQuit, current_thread_id)); 342 base::Bind(&RunAllPendingMessageAndSendQuit, current_thread_id,
314 343 run_loop.QuitClosure()));
315 ui_test_utils::RunMessageLoop(); 344 ui_test_utils::RunThisRunLoop(&run_loop);
316 } 345 }
317 346
318 bool GetCurrentTabTitle(const Browser* browser, string16* title) { 347 bool GetCurrentTabTitle(const Browser* browser, string16* title) {
319 WebContents* web_contents = browser->GetActiveWebContents(); 348 WebContents* web_contents = browser->GetActiveWebContents();
320 if (!web_contents) 349 if (!web_contents)
321 return false; 350 return false;
322 NavigationEntry* last_entry = web_contents->GetController().GetActiveEntry(); 351 NavigationEntry* last_entry = web_contents->GetController().GetActiveEntry();
323 if (!last_entry) 352 if (!last_entry)
324 return false; 353 return false;
325 title->assign(last_entry->GetTitleForDisplay("")); 354 title->assign(last_entry->GetTitleForDisplay(""));
326 return true; 355 return true;
327 } 356 }
328 357
329 void WaitForNavigations(NavigationController* controller, 358 void WaitForNavigations(NavigationController* controller,
330 int number_of_navigations) { 359 int number_of_navigations) {
331 content::TestNavigationObserver observer( 360 content::TestNavigationObserver observer(
332 content::Source<NavigationController>(controller), NULL, 361 content::Source<NavigationController>(controller), NULL,
333 number_of_navigations); 362 number_of_navigations);
363 base::RunLoop run_loop;
334 observer.WaitForObservation( 364 observer.WaitForObservation(
335 base::Bind(&ui_test_utils::RunMessageLoop), 365 base::Bind(&ui_test_utils::RunThisRunLoop, base::Unretained(&run_loop)),
336 base::Bind(&MessageLoop::Quit, 366 ui_test_utils::GetQuitTaskForRunLoop(&run_loop));
337 base::Unretained(MessageLoopForUI::current())));
338 } 367 }
339 368
340 void WaitForNewTab(Browser* browser) { 369 void WaitForNewTab(Browser* browser) {
341 WindowedNotificationObserver observer( 370 WindowedNotificationObserver observer(
342 chrome::NOTIFICATION_TAB_ADDED, 371 chrome::NOTIFICATION_TAB_ADDED,
343 content::Source<content::WebContentsDelegate>(browser)); 372 content::Source<content::WebContentsDelegate>(browser));
344 observer.Wait(); 373 observer.Wait();
345 } 374 }
346 375
347 void WaitForLoadStop(WebContents* tab) { 376 void WaitForLoadStop(WebContents* tab) {
(...skipping 29 matching lines...) Expand all
377 chrome::OpenURLOffTheRecord(profile, url); 406 chrome::OpenURLOffTheRecord(profile, url);
378 Browser* browser = browser::FindTabbedBrowser( 407 Browser* browser = browser::FindTabbedBrowser(
379 profile->GetOffTheRecordProfile(), false); 408 profile->GetOffTheRecordProfile(), false);
380 WaitForNavigations(&browser->GetActiveWebContents()->GetController(), 1); 409 WaitForNavigations(&browser->GetActiveWebContents()->GetController(), 1);
381 } 410 }
382 411
383 void NavigateToURL(browser::NavigateParams* params) { 412 void NavigateToURL(browser::NavigateParams* params) {
384 content::TestNavigationObserver observer( 413 content::TestNavigationObserver observer(
385 content::NotificationService::AllSources(), NULL, 1); 414 content::NotificationService::AllSources(), NULL, 1);
386 browser::Navigate(params); 415 browser::Navigate(params);
416 base::RunLoop run_loop;
387 observer.WaitForObservation( 417 observer.WaitForObservation(
388 base::Bind(&ui_test_utils::RunMessageLoop), 418 base::Bind(&ui_test_utils::RunThisRunLoop, base::Unretained(&run_loop)),
389 base::Bind(&MessageLoop::Quit, 419 ui_test_utils::GetQuitTaskForRunLoop(&run_loop));
390 base::Unretained(MessageLoopForUI::current())));
391
392 } 420 }
393 421
394 void NavigateToURL(Browser* browser, const GURL& url) { 422 void NavigateToURL(Browser* browser, const GURL& url) {
395 NavigateToURLWithDisposition(browser, url, CURRENT_TAB, 423 NavigateToURLWithDisposition(browser, url, CURRENT_TAB,
396 BROWSER_TEST_WAIT_FOR_NAVIGATION); 424 BROWSER_TEST_WAIT_FOR_NAVIGATION);
397 } 425 }
398 426
399 // Navigates the specified tab (via |disposition|) of |browser| to |url|, 427 // Navigates the specified tab (via |disposition|) of |browser| to |url|,
400 // blocking until the |number_of_navigations| specified complete. 428 // blocking until the |number_of_navigations| specified complete.
401 // |disposition| indicates what tab the download occurs in, and 429 // |disposition| indicates what tab the download occurs in, and
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 << " Unable to wait for navigation to \"" << url.spec() 479 << " Unable to wait for navigation to \"" << url.spec()
452 << "\" because the new tab is not available yet"; 480 << "\" because the new tab is not available yet";
453 return; 481 return;
454 } else if ((disposition == CURRENT_TAB) || 482 } else if ((disposition == CURRENT_TAB) ||
455 (disposition == NEW_FOREGROUND_TAB) || 483 (disposition == NEW_FOREGROUND_TAB) ||
456 (disposition == SINGLETON_TAB)) { 484 (disposition == SINGLETON_TAB)) {
457 // The currently selected tab is the right one. 485 // The currently selected tab is the right one.
458 web_contents = browser->GetActiveWebContents(); 486 web_contents = browser->GetActiveWebContents();
459 } 487 }
460 if (disposition == CURRENT_TAB) { 488 if (disposition == CURRENT_TAB) {
489 base::RunLoop run_loop;
461 same_tab_observer.WaitForObservation( 490 same_tab_observer.WaitForObservation(
462 base::Bind(&ui_test_utils::RunMessageLoop), 491 base::Bind(&ui_test_utils::RunThisRunLoop, base::Unretained(&run_loop)),
463 base::Bind(&MessageLoop::Quit, 492 ui_test_utils::GetQuitTaskForRunLoop(&run_loop));
464 base::Unretained(MessageLoopForUI::current())));
465 return; 493 return;
466 } else if (web_contents) { 494 } else if (web_contents) {
467 NavigationController* controller = &web_contents->GetController(); 495 NavigationController* controller = &web_contents->GetController();
468 WaitForNavigations(controller, number_of_navigations); 496 WaitForNavigations(controller, number_of_navigations);
469 return; 497 return;
470 } 498 }
471 EXPECT_TRUE(NULL != web_contents) << " Unable to wait for navigation to \"" 499 EXPECT_TRUE(NULL != web_contents) << " Unable to wait for navigation to \""
472 << url.spec() << "\"" 500 << url.spec() << "\""
473 << " because we can't get the tab contents"; 501 << " because we can't get the tab contents";
474 } 502 }
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
704 int type, 732 int type,
705 const content::NotificationSource& source) { 733 const content::NotificationSource& source) {
706 content::NotificationRegistrar registrar; 734 content::NotificationRegistrar registrar;
707 registrar.Add(observer, type, source); 735 registrar.Add(observer, type, source);
708 RunMessageLoop(); 736 RunMessageLoop();
709 } 737 }
710 738
711 void WaitForBookmarkModelToLoad(BookmarkModel* model) { 739 void WaitForBookmarkModelToLoad(BookmarkModel* model) {
712 if (model->IsLoaded()) 740 if (model->IsLoaded())
713 return; 741 return;
714 BookmarkLoadObserver observer; 742 base::RunLoop run_loop;
743 BookmarkLoadObserver observer(GetQuitTaskForRunLoop(&run_loop));
715 model->AddObserver(&observer); 744 model->AddObserver(&observer);
716 RunMessageLoop(); 745 RunThisRunLoop(&run_loop);
717 model->RemoveObserver(&observer); 746 model->RemoveObserver(&observer);
718 ASSERT_TRUE(model->IsLoaded()); 747 ASSERT_TRUE(model->IsLoaded());
719 } 748 }
720 749
721 void WaitForTemplateURLServiceToLoad(TemplateURLService* service) { 750 void WaitForTemplateURLServiceToLoad(TemplateURLService* service) {
722 if (service->loaded()) 751 if (service->loaded())
723 return; 752 return;
724 service->Load(); 753 service->Load();
725 TemplateURLServiceTestUtil::BlockTillServiceProcessesRequests(); 754 TemplateURLServiceTestUtil::BlockTillServiceProcessesRequests();
726 ASSERT_TRUE(service->loaded()); 755 ASSERT_TRUE(service->loaded());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 793
765 bool SendKeyPressSync(const Browser* browser, 794 bool SendKeyPressSync(const Browser* browser,
766 ui::KeyboardCode key, 795 ui::KeyboardCode key,
767 bool control, 796 bool control,
768 bool shift, 797 bool shift,
769 bool alt, 798 bool alt,
770 bool command) { 799 bool command) {
771 gfx::NativeWindow window = NULL; 800 gfx::NativeWindow window = NULL;
772 if (!GetNativeWindow(browser, &window)) 801 if (!GetNativeWindow(browser, &window))
773 return false; 802 return false;
774 803 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
775 bool result; 804 bool result;
776 result = ui_controls::SendKeyPressNotifyWhenDone( 805 result = ui_controls::SendKeyPressNotifyWhenDone(
777 window, key, control, shift, alt, command, MessageLoop::QuitClosure()); 806 window, key, control, shift, alt, command, runner->QuitClosure());
778 #if defined(OS_WIN) 807 #if defined(OS_WIN)
779 if (!result && BringBrowserWindowToFront(browser)) { 808 if (!result && BringBrowserWindowToFront(browser)) {
780 result = ui_controls::SendKeyPressNotifyWhenDone( 809 result = ui_controls::SendKeyPressNotifyWhenDone(
781 window, key, control, shift, alt, command, MessageLoop::QuitClosure()); 810 window, key, control, shift, alt, command, runner->QuitClosure());
782 } 811 }
783 #endif 812 #endif
784 if (!result) { 813 if (!result) {
785 LOG(ERROR) << "ui_controls::SendKeyPressNotifyWhenDone failed"; 814 LOG(ERROR) << "ui_controls::SendKeyPressNotifyWhenDone failed";
786 return false; 815 return false;
787 } 816 }
788 817
789 // Run the message loop. It'll stop running when either the key was received 818 // Run the message loop. It'll stop running when either the key was received
790 // or the test timed out (in which case testing::Test::HasFatalFailure should 819 // or the test timed out (in which case testing::Test::HasFatalFailure should
791 // be set). 820 // be set).
792 RunMessageLoop(); 821 runner->Run();
793 return !testing::Test::HasFatalFailure(); 822 return !testing::Test::HasFatalFailure();
794 } 823 }
795 824
796 bool SendKeyPressAndWait(const Browser* browser, 825 bool SendKeyPressAndWait(const Browser* browser,
797 ui::KeyboardCode key, 826 ui::KeyboardCode key,
798 bool control, 827 bool control,
799 bool shift, 828 bool shift,
800 bool alt, 829 bool alt,
801 bool command, 830 bool command,
802 int type, 831 int type,
803 const content::NotificationSource& source) { 832 const content::NotificationSource& source) {
804 WindowedNotificationObserver observer(type, source); 833 WindowedNotificationObserver observer(type, source);
805 834
806 if (!SendKeyPressSync(browser, key, control, shift, alt, command)) 835 if (!SendKeyPressSync(browser, key, control, shift, alt, command))
807 return false; 836 return false;
808 837
809 observer.Wait(); 838 observer.Wait();
810 return !testing::Test::HasFatalFailure(); 839 return !testing::Test::HasFatalFailure();
811 } 840 }
812 841
813 bool SendMouseMoveSync(const gfx::Point& location) { 842 bool SendMouseMoveSync(const gfx::Point& location) {
814 if (!ui_controls::SendMouseMoveNotifyWhenDone(location.x(), location.y(), 843 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
815 MessageLoop::QuitClosure())) { 844 if (!ui_controls::SendMouseMoveNotifyWhenDone(
845 location.x(), location.y(), runner->QuitClosure())) {
816 return false; 846 return false;
817 } 847 }
818 RunMessageLoop(); 848 runner->Run();
819 return !testing::Test::HasFatalFailure(); 849 return !testing::Test::HasFatalFailure();
820 } 850 }
821 851
822 bool SendMouseEventsSync(ui_controls::MouseButton type, int state) { 852 bool SendMouseEventsSync(ui_controls::MouseButton type, int state) {
853 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
823 if (!ui_controls::SendMouseEventsNotifyWhenDone( 854 if (!ui_controls::SendMouseEventsNotifyWhenDone(
824 type, state, MessageLoop::QuitClosure())) { 855 type, state, runner->QuitClosure())) {
825 return false; 856 return false;
826 } 857 }
827 RunMessageLoop(); 858 runner->Run();
828 return !testing::Test::HasFatalFailure(); 859 return !testing::Test::HasFatalFailure();
829 } 860 }
830 861
831 TimedMessageLoopRunner::TimedMessageLoopRunner() 862 MessageLoopRunner::MessageLoopRunner() {
832 : loop_(new MessageLoopForUI()),
833 owned_(true),
834 quit_loop_invoked_(false) {
835 } 863 }
836 864
837 TimedMessageLoopRunner::~TimedMessageLoopRunner() { 865 MessageLoopRunner::~MessageLoopRunner() {
838 if (owned_)
839 delete loop_;
840 } 866 }
841 867
842 void TimedMessageLoopRunner::RunFor(int ms) { 868 void MessageLoopRunner::Run() {
843 QuitAfter(ms); 869 ui_test_utils::RunThisRunLoop(&run_loop_);
844 quit_loop_invoked_ = false;
845 loop_->Run();
846 } 870 }
847 871
848 void TimedMessageLoopRunner::Quit() { 872 base::Closure MessageLoopRunner::QuitClosure() {
849 quit_loop_invoked_ = true; 873 return base::Bind(&MessageLoopRunner::Quit, this);
850 loop_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
851 } 874 }
852 875
853 void TimedMessageLoopRunner::QuitAfter(int ms) { 876 void MessageLoopRunner::Quit() {
854 quit_loop_invoked_ = true; 877 ui_test_utils::GetQuitTaskForRunLoop(&run_loop_).Run();
855 loop_->PostDelayedTask(
856 FROM_HERE,
857 MessageLoop::QuitClosure(),
858 base::TimeDelta::FromMilliseconds(ms));
859 } 878 }
860 879
861 TestWebSocketServer::TestWebSocketServer() 880 TestWebSocketServer::TestWebSocketServer()
862 : started_(false), 881 : started_(false),
863 port_(kDefaultWsPort), 882 port_(kDefaultWsPort),
864 secure_(false) { 883 secure_(false) {
865 #if defined(OS_POSIX) 884 #if defined(OS_POSIX)
866 process_group_id_ = base::kNullProcessHandle; 885 process_group_id_ = base::kNullProcessHandle;
867 #endif 886 #endif
868 } 887 }
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 registrar_.Add(this, notification_type, source); 1032 registrar_.Add(this, notification_type, source);
1014 } 1033 }
1015 1034
1016 WindowedNotificationObserver::~WindowedNotificationObserver() {} 1035 WindowedNotificationObserver::~WindowedNotificationObserver() {}
1017 1036
1018 void WindowedNotificationObserver::Wait() { 1037 void WindowedNotificationObserver::Wait() {
1019 if (seen_) 1038 if (seen_)
1020 return; 1039 return;
1021 1040
1022 running_ = true; 1041 running_ = true;
1023 ui_test_utils::RunMessageLoop(); 1042 message_loop_runner_ = new MessageLoopRunner;
1043 message_loop_runner_->Run();
1024 EXPECT_TRUE(seen_); 1044 EXPECT_TRUE(seen_);
1025 } 1045 }
1026 1046
1027 void WindowedNotificationObserver::Observe( 1047 void WindowedNotificationObserver::Observe(
1028 int type, 1048 int type,
1029 const content::NotificationSource& source, 1049 const content::NotificationSource& source,
1030 const content::NotificationDetails& details) { 1050 const content::NotificationDetails& details) {
1031 source_ = source; 1051 source_ = source;
1032 details_ = details; 1052 details_ = details;
1033 seen_ = true; 1053 seen_ = true;
1034 if (!running_) 1054 if (!running_)
1035 return; 1055 return;
1036 1056
1037 MessageLoopForUI::current()->Quit(); 1057 message_loop_runner_->Quit();
1038 running_ = false; 1058 running_ = false;
1039 } 1059 }
1040 1060
1041 WindowedTabAddedNotificationObserver::WindowedTabAddedNotificationObserver( 1061 WindowedTabAddedNotificationObserver::WindowedTabAddedNotificationObserver(
1042 const content::NotificationSource& source) 1062 const content::NotificationSource& source)
1043 : WindowedNotificationObserver(chrome::NOTIFICATION_TAB_ADDED, source), 1063 : WindowedNotificationObserver(chrome::NOTIFICATION_TAB_ADDED, source),
1044 added_tab_(NULL) { 1064 added_tab_(NULL) {
1045 } 1065 }
1046 1066
1047 void WindowedTabAddedNotificationObserver::Observe( 1067 void WindowedTabAddedNotificationObserver::Observe(
(...skipping 30 matching lines...) Expand all
1078 expected_titles_.push_back(expected_title); 1098 expected_titles_.push_back(expected_title);
1079 } 1099 }
1080 1100
1081 TitleWatcher::~TitleWatcher() { 1101 TitleWatcher::~TitleWatcher() {
1082 } 1102 }
1083 1103
1084 const string16& TitleWatcher::WaitAndGetTitle() { 1104 const string16& TitleWatcher::WaitAndGetTitle() {
1085 if (expected_title_observed_) 1105 if (expected_title_observed_)
1086 return observed_title_; 1106 return observed_title_;
1087 quit_loop_on_observation_ = true; 1107 quit_loop_on_observation_ = true;
1088 ui_test_utils::RunMessageLoop(); 1108 message_loop_runner_ = new MessageLoopRunner;
1109 message_loop_runner_->Run();
1089 return observed_title_; 1110 return observed_title_;
1090 } 1111 }
1091 1112
1092 void TitleWatcher::Observe(int type, 1113 void TitleWatcher::Observe(int type,
1093 const content::NotificationSource& source, 1114 const content::NotificationSource& source,
1094 const content::NotificationDetails& details) { 1115 const content::NotificationDetails& details) {
1095 if (type == content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED) { 1116 if (type == content::NOTIFICATION_WEB_CONTENTS_TITLE_UPDATED) {
1096 WebContents* source_contents = content::Source<WebContents>(source).ptr(); 1117 WebContents* source_contents = content::Source<WebContents>(source).ptr();
1097 ASSERT_EQ(web_contents_, source_contents); 1118 ASSERT_EQ(web_contents_, source_contents);
1098 } else if (type == content::NOTIFICATION_LOAD_STOP) { 1119 } else if (type == content::NOTIFICATION_LOAD_STOP) {
1099 NavigationController* controller = 1120 NavigationController* controller =
1100 content::Source<NavigationController>(source).ptr(); 1121 content::Source<NavigationController>(source).ptr();
1101 ASSERT_EQ(&web_contents_->GetController(), controller); 1122 ASSERT_EQ(&web_contents_->GetController(), controller);
1102 } else { 1123 } else {
1103 FAIL() << "Unexpected notification received."; 1124 FAIL() << "Unexpected notification received.";
1104 } 1125 }
1105 1126
1106 std::vector<string16>::const_iterator it = 1127 std::vector<string16>::const_iterator it =
1107 std::find(expected_titles_.begin(), 1128 std::find(expected_titles_.begin(),
1108 expected_titles_.end(), 1129 expected_titles_.end(),
1109 web_contents_->GetTitle()); 1130 web_contents_->GetTitle());
1110 if (it == expected_titles_.end()) 1131 if (it == expected_titles_.end())
1111 return; 1132 return;
1112 observed_title_ = *it; 1133 observed_title_ = *it;
1113 expected_title_observed_ = true; 1134 expected_title_observed_ = true;
1114 if (quit_loop_on_observation_) 1135 if (quit_loop_on_observation_) {
1115 MessageLoopForUI::current()->Quit(); 1136 // Only call Quit once, on first Observe:
1137 quit_loop_on_observation_ = false;
1138 message_loop_runner_->Quit();
1139 }
1116 } 1140 }
1117 1141
1118 BrowserAddedObserver::BrowserAddedObserver() 1142 BrowserAddedObserver::BrowserAddedObserver()
1119 : notification_observer_( 1143 : notification_observer_(
1120 chrome::NOTIFICATION_BROWSER_OPENED, 1144 chrome::NOTIFICATION_BROWSER_OPENED,
1121 content::NotificationService::AllSources()) { 1145 content::NotificationService::AllSources()) {
1122 original_browsers_.insert(BrowserList::begin(), BrowserList::end()); 1146 original_browsers_.insert(BrowserList::begin(), BrowserList::end());
1123 } 1147 }
1124 1148
1125 BrowserAddedObserver::~BrowserAddedObserver() { 1149 BrowserAddedObserver::~BrowserAddedObserver() {
(...skipping 14 matching lines...) Expand all
1140 DOMMessageQueue::~DOMMessageQueue() {} 1164 DOMMessageQueue::~DOMMessageQueue() {}
1141 1165
1142 void DOMMessageQueue::Observe(int type, 1166 void DOMMessageQueue::Observe(int type,
1143 const content::NotificationSource& source, 1167 const content::NotificationSource& source,
1144 const content::NotificationDetails& details) { 1168 const content::NotificationDetails& details) {
1145 content::Details<DomOperationNotificationDetails> dom_op_details(details); 1169 content::Details<DomOperationNotificationDetails> dom_op_details(details);
1146 content::Source<RenderViewHost> sender(source); 1170 content::Source<RenderViewHost> sender(source);
1147 message_queue_.push(dom_op_details->json); 1171 message_queue_.push(dom_op_details->json);
1148 if (waiting_for_message_) { 1172 if (waiting_for_message_) {
1149 waiting_for_message_ = false; 1173 waiting_for_message_ = false;
1150 MessageLoopForUI::current()->Quit(); 1174 message_loop_runner_->Quit();
1151 } 1175 }
1152 } 1176 }
1153 1177
1154 void DOMMessageQueue::ClearQueue() { 1178 void DOMMessageQueue::ClearQueue() {
1155 message_queue_ = std::queue<std::string>(); 1179 message_queue_ = std::queue<std::string>();
1156 } 1180 }
1157 1181
1158 bool DOMMessageQueue::WaitForMessage(std::string* message) { 1182 bool DOMMessageQueue::WaitForMessage(std::string* message) {
1159 if (message_queue_.empty()) { 1183 if (message_queue_.empty()) {
1160 waiting_for_message_ = true; 1184 waiting_for_message_ = true;
1161 // This will be quit when a new message comes in. 1185 // This will be quit when a new message comes in.
1162 RunMessageLoop(); 1186 message_loop_runner_ = new MessageLoopRunner;
1187 message_loop_runner_->Run();
1163 } 1188 }
1164 // The queue should not be empty, unless we were quit because of a timeout. 1189 // The queue should not be empty, unless we were quit because of a timeout.
1165 if (message_queue_.empty()) 1190 if (message_queue_.empty())
1166 return false; 1191 return false;
1167 if (message) 1192 if (message)
1168 *message = message_queue_.front(); 1193 *message = message_queue_.front();
1169 return true; 1194 return true;
1170 } 1195 }
1171 1196
1172 // Coordinates taking snapshots of a |RenderWidget|. 1197 // Coordinates taking snapshots of a |RenderWidget|.
1173 class SnapshotTaker { 1198 class SnapshotTaker {
1174 public: 1199 public:
1175 SnapshotTaker() : bitmap_(NULL) {} 1200 SnapshotTaker() : bitmap_(NULL) {}
1176 1201
1177 bool TakeRenderWidgetSnapshot(RenderWidgetHost* rwh, 1202 bool TakeRenderWidgetSnapshot(RenderWidgetHost* rwh,
1178 const gfx::Size& page_size, 1203 const gfx::Size& page_size,
1179 const gfx::Size& desired_size, 1204 const gfx::Size& desired_size,
1180 SkBitmap* bitmap) WARN_UNUSED_RESULT { 1205 SkBitmap* bitmap) WARN_UNUSED_RESULT {
1181 bitmap_ = bitmap; 1206 bitmap_ = bitmap;
1182 ThumbnailGenerator* generator = g_browser_process->GetThumbnailGenerator(); 1207 ThumbnailGenerator* generator = g_browser_process->GetThumbnailGenerator();
1183 generator->MonitorRenderer(rwh, true); 1208 generator->MonitorRenderer(rwh, true);
1184 snapshot_taken_ = false; 1209 snapshot_taken_ = false;
1185 generator->AskForSnapshot( 1210 generator->AskForSnapshot(
1186 rwh, 1211 rwh,
1187 base::Bind(&SnapshotTaker::OnSnapshotTaken, base::Unretained(this)), 1212 base::Bind(&SnapshotTaker::OnSnapshotTaken, base::Unretained(this)),
1188 page_size, 1213 page_size,
1189 desired_size); 1214 desired_size);
1190 ui_test_utils::RunMessageLoop(); 1215 message_loop_runner_ = new MessageLoopRunner;
1216 message_loop_runner_->Run();
1191 return snapshot_taken_; 1217 return snapshot_taken_;
1192 } 1218 }
1193 1219
1194 bool TakeEntirePageSnapshot(RenderViewHost* rvh, 1220 bool TakeEntirePageSnapshot(RenderViewHost* rvh,
1195 SkBitmap* bitmap) WARN_UNUSED_RESULT { 1221 SkBitmap* bitmap) WARN_UNUSED_RESULT {
1196 const wchar_t* script = 1222 const wchar_t* script =
1197 L"window.domAutomationController.send(" 1223 L"window.domAutomationController.send("
1198 L" JSON.stringify([document.width, document.height]))"; 1224 L" JSON.stringify([document.width, document.height]))";
1199 std::string json; 1225 std::string json;
1200 if (!ui_test_utils::ExecuteJavaScriptAndExtractString( 1226 if (!ui_test_utils::ExecuteJavaScriptAndExtractString(
(...skipping 14 matching lines...) Expand all
1215 // Take the snapshot. 1241 // Take the snapshot.
1216 gfx::Size page_size(width, height); 1242 gfx::Size page_size(width, height);
1217 return TakeRenderWidgetSnapshot(rvh, page_size, page_size, bitmap); 1243 return TakeRenderWidgetSnapshot(rvh, page_size, page_size, bitmap);
1218 } 1244 }
1219 1245
1220 private: 1246 private:
1221 // Called when the ThumbnailGenerator has taken the snapshot. 1247 // Called when the ThumbnailGenerator has taken the snapshot.
1222 void OnSnapshotTaken(const SkBitmap& bitmap) { 1248 void OnSnapshotTaken(const SkBitmap& bitmap) {
1223 *bitmap_ = bitmap; 1249 *bitmap_ = bitmap;
1224 snapshot_taken_ = true; 1250 snapshot_taken_ = true;
1225 MessageLoop::current()->Quit(); 1251 message_loop_runner_->Quit();
1226 } 1252 }
1227 1253
1228 SkBitmap* bitmap_; 1254 SkBitmap* bitmap_;
1229 // Whether the snapshot was actually taken and received by this SnapshotTaker. 1255 // Whether the snapshot was actually taken and received by this SnapshotTaker.
1230 // This will be false if the test times out. 1256 // This will be false if the test times out.
1231 bool snapshot_taken_; 1257 bool snapshot_taken_;
1258 scoped_refptr<MessageLoopRunner> message_loop_runner_;
1232 1259
1233 DISALLOW_COPY_AND_ASSIGN(SnapshotTaker); 1260 DISALLOW_COPY_AND_ASSIGN(SnapshotTaker);
1234 }; 1261 };
1235 1262
1236 bool TakeRenderWidgetSnapshot(RenderWidgetHost* rwh, 1263 bool TakeRenderWidgetSnapshot(RenderWidgetHost* rwh,
1237 const gfx::Size& page_size, 1264 const gfx::Size& page_size,
1238 SkBitmap* bitmap) { 1265 SkBitmap* bitmap) {
1239 DCHECK(bitmap); 1266 DCHECK(bitmap);
1240 SnapshotTaker taker; 1267 SnapshotTaker taker;
1241 return taker.TakeRenderWidgetSnapshot(rwh, page_size, page_size, bitmap); 1268 return taker.TakeRenderWidgetSnapshot(rwh, page_size, page_size, bitmap);
1242 } 1269 }
1243 1270
1244 bool TakeEntirePageSnapshot(RenderViewHost* rvh, SkBitmap* bitmap) { 1271 bool TakeEntirePageSnapshot(RenderViewHost* rvh, SkBitmap* bitmap) {
1245 DCHECK(bitmap); 1272 DCHECK(bitmap);
1246 SnapshotTaker taker; 1273 SnapshotTaker taker;
1247 return taker.TakeEntirePageSnapshot(rvh, bitmap); 1274 return taker.TakeEntirePageSnapshot(rvh, bitmap);
1248 } 1275 }
1249 1276
1250 void OverrideGeolocation(double latitude, double longitude) { 1277 void OverrideGeolocation(double latitude, double longitude) {
1251 content::Geoposition position; 1278 content::Geoposition position;
1252 position.latitude = latitude; 1279 position.latitude = latitude;
1253 position.longitude = longitude; 1280 position.longitude = longitude;
1254 position.altitude = 0.; 1281 position.altitude = 0.;
1255 position.accuracy = 0.; 1282 position.accuracy = 0.;
1256 position.timestamp = base::Time::Now(); 1283 position.timestamp = base::Time::Now();
1257 content::OverrideLocationForTesting(position, 1284 scoped_refptr<MessageLoopRunner> runner = new MessageLoopRunner;
1258 base::Bind(MessageLoop::QuitClosure())); 1285 content::OverrideLocationForTesting(position, runner->QuitClosure());
1259 RunMessageLoop(); 1286 runner->Run();
1260 } 1287 }
1261 1288
1262 namespace internal { 1289 namespace internal {
1263 1290
1264 void ClickTask(ui_controls::MouseButton button, 1291 void ClickTask(ui_controls::MouseButton button,
1265 int state, 1292 int state,
1266 const base::Closure& followup) { 1293 const base::Closure& followup) {
1267 if (!followup.is_null()) 1294 if (!followup.is_null())
1268 ui_controls::SendMouseEventsNotifyWhenDone(button, state, followup); 1295 ui_controls::SendMouseEventsNotifyWhenDone(button, state, followup);
1269 else 1296 else
1270 ui_controls::SendMouseEvents(button, state); 1297 ui_controls::SendMouseEvents(button, state);
1271 } 1298 }
1272 1299
1273 } // namespace internal 1300 } // namespace internal
1274 } // namespace ui_test_utils 1301 } // namespace ui_test_utils
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698