15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/view_event_test_base.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "chrome/test/base/chrome_unit_test_suite.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/interactive_test_utils.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/test/base/testing_browser_process.h" 126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/test/base/view_event_test_platform_part.h" 137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/base/ime/input_method_initializer.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/base/test/ui_controls.h" 151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/compositor/test/context_factories_for_test.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/view.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// View subclass that allows you to specify the preferred size. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestView : public views::View { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestView() {} 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetPreferredSize(const gfx::Size& size) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preferred_size_ = size; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PreferredSizeChanged(); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual gfx::Size GetPreferredSize() const OVERRIDE { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!preferred_size_.IsEmpty()) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return preferred_size_; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return View::GetPreferredSize(); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Layout() OVERRIDE { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) View* child_view = child_at(0); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child_view->SetBounds(0, 0, width(), height()); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size preferred_size_; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestView); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delay in background thread before posting mouse move. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMouseMoveDelayMS = 200; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ViewEventTestBase::ViewEventTestBase() 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : window_(NULL), 55a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch content_view_(NULL) { 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // The TestingBrowserProcess must be created in the constructor because there 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // are tests that require it before SetUp() is called. 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TestingBrowserProcess::CreateInstance(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewEventTestBase::Done() { 62a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::MessageLoop::current()->Quit(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're in a nested message loop, as is the case with menus, we 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // need to quit twice. The second quit does that for us. Finish all 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pending UI events before posting closure because events it may be 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // executed before UI events are executed. 68a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ui_controls::RunClosureAfterAllPendingUIEvents( 69a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::MessageLoop::QuitClosure()); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void ViewEventTestBase::SetUpTestCase() { 7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ChromeUnitTestSuite::InitializeProviders(); 7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ChromeUnitTestSuite::InitializeResourceBundle(); 7523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewEventTestBase::SetUp() { 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) views::ViewsDelegate::views_delegate = &views_delegate_; 797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ui::InitializeInputMethodForTesting(); 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The ContextFactory must exist before any Compositors are created. 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool enable_pixel_output = false; 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::ContextFactory* context_factory = 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::InitializeContextFactoryForTests(enable_pixel_output); 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) platform_part_.reset(ViewEventTestPlatformPart::Create(context_factory)); 876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) gfx::NativeWindow context = platform_part_->GetContext(); 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_ = views::Widget::CreateWindowWithContext(this, context); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewEventTestBase::TearDown() { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_->Close(); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RunAllPendingInMessageLoop(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_ = NULL; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::Clipboard::DestroyClipboardForCurrentThread(); 996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) platform_part_.reset(); 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::TerminateContextFactoryForTests(); 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ui::ShutdownInputMethodForTesting(); 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) views::ViewsDelegate::views_delegate = NULL; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ViewEventTestBase::CanResize() const { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* ViewEventTestBase::GetContentsView() { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!content_view_) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wrap the real view (as returned by CreateContentsView) in a View so 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that we can customize the preferred size. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestView* test_view = new TestView(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_view->SetPreferredSize(GetPreferredSize()); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_view->AddChildView(CreateContentsView()); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content_view_ = test_view; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return content_view_; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const views::Widget* ViewEventTestBase::GetWidget() const { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return content_view_->GetWidget(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::Widget* ViewEventTestBase::GetWidget() { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return content_view_->GetWidget(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ViewEventTestBase::~ViewEventTestBase() { 132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) TestingBrowserProcess::DeleteInstance(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewEventTestBase::StartMessageLoopAndRunTest() { 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE( 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui_test_utils::ShowAndFocusNativeWindow(window_->GetNativeWindow())); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flush any pending events to make sure we start with a clean slate. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RunAllPendingInMessageLoop(); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedule a task that starts the test. Need to do this as we're going to 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // run the message loop. 144a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::MessageLoop::current()->PostTask( 145a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) FROM_HERE, base::Bind(&ViewEventTestBase::DoTestOnMessageLoop, this)); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RunMessageLoop(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)gfx::Size ViewEventTestBase::GetPreferredSize() const { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Size(); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewEventTestBase::ScheduleMouseMoveInBackground(int x, int y) { 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dnd_thread_.get()) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dnd_thread_.reset(new base::Thread("mouse-move-thread")); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dnd_thread_->Start(); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dnd_thread_->message_loop()->PostDelayedTask( 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(base::IgnoreResult(&ui_controls::SendMouseMove), x, y), 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kMouseMoveDelayMS)); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewEventTestBase::StopBackgroundThread() { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dnd_thread_.reset(NULL); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ViewEventTestBase::RunTestMethod(const base::Closure& task) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopBackgroundThread(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) task.Run(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (HasFatalFailure()) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 176