diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-05 18:00:33 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-05 18:00:33 +0000 |
commit | 09c37bac05f382080e064d0bf96c7387f5f00c4b (patch) | |
tree | 57036c81129326d1d5ed94faa30f28643dea5f84 | |
parent | 37f978c043a87f37c8ba65fafdcbe081775ad57e (diff) | |
download | chromium_src-09c37bac05f382080e064d0bf96c7387f5f00c4b.zip chromium_src-09c37bac05f382080e064d0bf96c7387f5f00c4b.tar.gz chromium_src-09c37bac05f382080e064d0bf96c7387f5f00c4b.tar.bz2 |
Add tests for the page visibility, position, and clip in the new view API. This adds some additional capabilities to the UI test framework to support navigating background tabs.
Review URL: http://codereview.chromium.org/9034001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@116507 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.cc | 35 | ||||
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.h | 2 | ||||
-rw-r--r-- | chrome/common/automation_messages_internal.h | 26 | ||||
-rw-r--r-- | chrome/test/automation/browser_proxy.cc | 11 | ||||
-rw-r--r-- | chrome/test/automation/browser_proxy.h | 3 | ||||
-rw-r--r-- | chrome/test/ui/ppapi_uitest.cc | 93 | ||||
-rw-r--r-- | ppapi/ppapi_sources.gypi | 3 | ||||
-rw-r--r-- | ppapi/tests/test_case.cc | 2 | ||||
-rw-r--r-- | ppapi/tests/test_case.h | 3 | ||||
-rw-r--r-- | ppapi/tests/test_case.html | 8 | ||||
-rw-r--r-- | ppapi/tests/test_flash_fullscreen.cc | 5 | ||||
-rw-r--r-- | ppapi/tests/test_flash_fullscreen.h | 2 | ||||
-rw-r--r-- | ppapi/tests/test_fullscreen.cc | 6 | ||||
-rw-r--r-- | ppapi/tests/test_fullscreen.h | 2 | ||||
-rw-r--r-- | ppapi/tests/test_input_event.cc | 8 | ||||
-rw-r--r-- | ppapi/tests/test_input_event.h | 6 | ||||
-rw-r--r-- | ppapi/tests/test_view.cc | 197 | ||||
-rw-r--r-- | ppapi/tests/test_view.h | 51 | ||||
-rw-r--r-- | ppapi/tests/testing_instance.cc | 24 | ||||
-rw-r--r-- | ppapi/tests/testing_instance.h | 8 |
20 files changed, 443 insertions, 52 deletions
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index 39d9225..1acf44f 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -312,6 +312,8 @@ bool TestingAutomationProvider::OnMessageReceived( CloseBrowserAsync) IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab) IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab) + IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendBackgroundTab, + AppendBackgroundTab) IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex) IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab) IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies) @@ -559,6 +561,39 @@ void TestingAutomationProvider::AppendTab(int handle, } } +void TestingAutomationProvider::AppendBackgroundTab( + int handle, + const GURL& url, + IPC::Message* reply_message) { + int append_tab_response = -1; // -1 is the error code + content::NotificationObserver* observer = NULL; + + if (browser_tracker_->ContainsHandle(handle)) { + Browser* browser = browser_tracker_->GetResource(handle); + observer = new TabAppendedNotificationObserver(browser, this, + reply_message); + + browser::NavigateParams params(browser, url, content::PAGE_TRANSITION_LINK); + params.disposition = NEW_BACKGROUND_TAB; + browser::Navigate(¶ms); + TabContentsWrapper* contents = params.target_contents; + if (contents) { + append_tab_response = GetIndexForNavigationController( + &contents->web_contents()->GetController(), browser); + } + } + + if (append_tab_response < 0) { + // Appending tab failed. Clean up and send failure response. + if (observer) + delete observer; + + AutomationMsg_AppendBackgroundTab::WriteReplyParams(reply_message, + append_tab_response); + Send(reply_message); + } +} + void TestingAutomationProvider::GetActiveTabIndex(int handle, int* active_tab_index) { *active_tab_index = -1; // -1 is the error code diff --git a/chrome/browser/automation/testing_automation_provider.h b/chrome/browser/automation/testing_automation_provider.h index 5ae029f..3eee8ce 100644 --- a/chrome/browser/automation/testing_automation_provider.h +++ b/chrome/browser/automation/testing_automation_provider.h @@ -87,6 +87,8 @@ class TestingAutomationProvider : public AutomationProvider, void CloseBrowserAsync(int browser_handle); void ActivateTab(int handle, int at_index, int* status); void AppendTab(int handle, const GURL& url, IPC::Message* reply_message); + void AppendBackgroundTab(int handle, const GURL& url, + IPC::Message* reply_message); void GetActiveTabIndex(int handle, int* active_tab_index); void CloseTab(int tab_handle, bool wait_until_closed, IPC::Message* reply_message); diff --git a/chrome/common/automation_messages_internal.h b/chrome/common/automation_messages_internal.h index 35f75c0..08040b3 100644 --- a/chrome/common/automation_messages_internal.h +++ b/chrome/common/automation_messages_internal.h @@ -10,12 +10,12 @@ // any other purpose in these message types. // NOTE: All the new IPC messages should go at the end. -// The IPC message IDs need to match the reference builds. Since we now -// define the IDs based on __LINE__, to allow these IPC messages to be -// used to control an old version of Chrome we need the message IDs to -// remain the same. This means that you should not change the line number -// of any of the messages below. - +// The test <--> browser IPC message IDs need to match the reference +// builds. Since we now define the IDs based on __LINE__, to allow these +// IPC messages to be used to control an old version of Chrome we need +// the message IDs to remain the same. This means that you should not +// change the line number of these types of messages. You can, however, +// change the browser <--> renderer messages. @@ -1496,6 +1496,16 @@ IPC_SYNC_MESSAGE_CONTROL0_2(AutomationMsg_GetTracingOutput, std::string /* trace_chunk */, bool /* success */) +// This message notifies the AutomationProvider to append a new tab to the +// window with the given handle. The tab will be opened in the background +// like it was middle-clicked. The return value contains the index of +// the new tab, or -1 if the request failed. +// The second parameter is the url to be loaded in the new tab. +IPC_SYNC_MESSAGE_CONTROL2_1(AutomationMsg_AppendBackgroundTab, + int, + GURL, + int) + // Browser -> renderer messages. // Requests a snapshot. @@ -1520,7 +1530,7 @@ IPC_MESSAGE_ROUTED2(AutomationMsg_WillPerformClientRedirect, IPC_MESSAGE_ROUTED1(AutomationMsg_DidCompleteOrCancelClientRedirect, int64 /* frame_id */) - // YOUR NEW MESSAGE MIGHT NOT BELONG HERE. // This is the section for renderer -> browser automation messages. If it is -// an automation <-> browser message, put it above this section. +// an automation <-> browser message, put it above this section. The "no line +// number change" applies only to the automation <-> browser messages. diff --git a/chrome/test/automation/browser_proxy.cc b/chrome/test/automation/browser_proxy.cc index 68cabb8..66a4b0a 100644 --- a/chrome/test/automation/browser_proxy.cc +++ b/chrome/test/automation/browser_proxy.cc @@ -70,6 +70,17 @@ bool BrowserProxy::AppendTab(const GURL& tab_url) { return append_tab_response >= 0; } +bool BrowserProxy::AppendBackgroundTab(const GURL& tab_url) { + if (!is_valid()) + return false; + + int append_tab_response = -1; + + sender_->Send(new AutomationMsg_AppendBackgroundTab(handle_, tab_url, + &append_tab_response)); + return append_tab_response >= 0; +} + bool BrowserProxy::GetActiveTabIndex(int* active_tab_index) const { if (!is_valid()) return false; diff --git a/chrome/test/automation/browser_proxy.h b/chrome/test/automation/browser_proxy.h index 958f4ec..d564672 100644 --- a/chrome/test/automation/browser_proxy.h +++ b/chrome/test/automation/browser_proxy.h @@ -51,6 +51,9 @@ class BrowserProxy : public AutomationResourceProxy { // Returns true if successful. bool AppendTab(const GURL& tab_url) WARN_UNUSED_RESULT; + // Appends a new tab in the background (as if middle-clicking). + bool AppendBackgroundTab(const GURL& tab_url) WARN_UNUSED_RESULT; + // Gets the (zero-based) index of the currently active tab. Returns true if // successful. bool GetActiveTabIndex(int* active_tab_index) const WARN_UNUSED_RESULT; diff --git a/chrome/test/ui/ppapi_uitest.cc b/chrome/test/ui/ppapi_uitest.cc index 0bf637b..730c7d8 100644 --- a/chrome/test/ui/ppapi_uitest.cc +++ b/chrome/test/ui/ppapi_uitest.cc @@ -10,9 +10,11 @@ #include "content/common/pepper_plugin_registry.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" +#include "chrome/test/automation/browser_proxy.h" #include "chrome/test/automation/tab_proxy.h" #include "chrome/test/base/ui_test_utils.h" #include "chrome/test/ui/ui_test.h" +#include "content/public/common/url_constants.h" #include "net/base/net_util.h" #include "net/test/test_server.h" #include "webkit/plugins/plugin_switches.h" @@ -45,9 +47,10 @@ class PPAPITestBase : public UITest { } virtual std::string BuildQuery(const std::string& base, - const std::string& test_case)=0; + const std::string& test_case) = 0; - void RunTest(const std::string& test_case) { + // Returns the URL to load for file: tests. + GURL GetTestFileUrl(const std::string& test_case) { FilePath test_path; EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &test_path)); test_path = test_path.Append(FILE_PATH_LITERAL("ppapi")); @@ -57,11 +60,22 @@ class PPAPITestBase : public UITest { // Sanity check the file name. EXPECT_TRUE(file_util::PathExists(test_path)); + GURL test_url = net::FilePathToFileURL(test_path); + GURL::Replacements replacements; std::string query = BuildQuery("", test_case); replacements.SetQuery(query.c_str(), url_parse::Component(0, query.size())); - GURL test_url = net::FilePathToFileURL(test_path); - RunTestURL(test_url.ReplaceComponents(replacements)); + return test_url.ReplaceComponents(replacements); + } + + void RunTest(const std::string& test_case) { + scoped_refptr<TabProxy> tab = GetActiveTab(); + EXPECT_TRUE(tab.get()); + if (!tab.get()) + return; + GURL url = GetTestFileUrl(test_case); + EXPECT_TRUE(tab->NavigateToURLBlockUntilNavigationsComplete(url, 1)); + RunTestURL(tab, url); } void RunTestViaHTTP(const std::string& test_case) { @@ -102,7 +116,11 @@ class PPAPITestBase : public UITest { net::TestServer test_server(net::TestServer::TYPE_HTTP, web_dir); ASSERT_TRUE(test_server.Start()); std::string query = BuildQuery("files/test_case.html?", test_case); - RunTestURL(test_server.GetURL(query)); + + scoped_refptr<TabProxy> tab = GetActiveTab(); + GURL url = test_server.GetURL(query); + EXPECT_TRUE(tab->NavigateToURLBlockUntilNavigationsComplete(url, 1)); + RunTestURL(tab, url); } void RunTestWithWebSocketServer(const std::string& test_case) { @@ -123,11 +141,11 @@ class PPAPITestBase : public UITest { return test_name; } - private: - void RunTestURL(const GURL& test_url) { - scoped_refptr<TabProxy> tab(GetActiveTab()); + protected: + // Runs the test for a tab given the tab that's already navigated to the + // given URL. + void RunTestURL(scoped_refptr<TabProxy> tab, const GURL& test_url) { ASSERT_TRUE(tab.get()); - ASSERT_TRUE(tab->NavigateToURL(test_url)); // The large timeout was causing the cycle time for the whole test suite // to be too long when a tiny bug caused all tests to timeout. @@ -668,4 +686,61 @@ TEST_PPAPI_OUT_OF_PROCESS(Audio_Creation) TEST_PPAPI_OUT_OF_PROCESS(Audio_DestroyNoStop) TEST_PPAPI_OUT_OF_PROCESS(Audio_Failures) +TEST_PPAPI_IN_PROCESS(View_CreateVisible); +TEST_PPAPI_OUT_OF_PROCESS(View_CreateVisible); +TEST_PPAPI_NACL_VIA_HTTP(View_CreateVisible); +// This test ensures that plugins created in a background tab have their +// initial visibility set to false. We don't bother testing in-process for this +// custom test since the out of process code also exercises in-process. +TEST_F(OutOfProcessPPAPITest, View_CreateInvisible) { + // Make a second tab in the foreground. + scoped_refptr<TabProxy> tab(GetActiveTab()); + ASSERT_TRUE(tab.get()); + scoped_refptr<BrowserProxy> browser(tab->GetParentBrowser()); + ASSERT_TRUE(browser.get()); + GURL url = GetTestFileUrl("View_CreatedInvisible"); + ASSERT_TRUE(browser->AppendBackgroundTab(url)); + + // Tab 1 will be the one we appended after the default tab 0. + RunTestURL(tab, url); +} +// This test messes with tab visibility so is custom. +TEST_F(OutOfProcessPPAPITest, View_PageHideShow) { + GURL url = GetTestFileUrl("View_PageHideShow"); + scoped_refptr<TabProxy> tab = GetActiveTab(); + ASSERT_TRUE(tab.get()); + ASSERT_TRUE(tab->NavigateToURLBlockUntilNavigationsComplete(url, 1)); + + // The plugin will be loaded in the foreground tab and will set the + // "created" cookie. + std::string true_str("TRUE"); + std::string progress = WaitUntilCookieNonEmpty(tab.get(), url, + "TestPageHideShow:Created", + TestTimeouts::action_max_timeout_ms()); + ASSERT_EQ(true_str, progress); + + // Make a new tab to cause the original one to hide, this should trigger the + // next phase of the test. + scoped_refptr<BrowserProxy> browser(tab->GetParentBrowser()); + ASSERT_TRUE(browser.get()); + ASSERT_TRUE(browser->AppendTab(GURL(chrome::kAboutBlankURL))); + + // Wait until the test acks that it got hidden. + progress = WaitUntilCookieNonEmpty(tab.get(), url, "TestPageHideShow:Hidden", + TestTimeouts::action_max_timeout_ms()); + ASSERT_EQ(true_str, progress); + + // Switch back to the test tab. + ASSERT_TRUE(browser->ActivateTab(0)); + + // Wait for the test completion event. + RunTestURL(tab, url); +} +TEST_PPAPI_IN_PROCESS(View_SizeChange); +TEST_PPAPI_OUT_OF_PROCESS(View_SizeChange); +TEST_PPAPI_NACL_VIA_HTTP(View_SizeChange); +TEST_PPAPI_IN_PROCESS(View_ClipChange); +TEST_PPAPI_OUT_OF_PROCESS(View_ClipChange); +TEST_PPAPI_NACL_VIA_HTTP(View_ClipChange); + #endif // ADDRESS_SANITIZER diff --git a/ppapi/ppapi_sources.gypi b/ppapi/ppapi_sources.gypi index 84b354d..13b333f 100644 --- a/ppapi/ppapi_sources.gypi +++ b/ppapi/ppapi_sources.gypi @@ -301,6 +301,7 @@ 'tests/test_udp_socket_private_disallowed.cc', 'tests/test_url_loader.cc', 'tests/test_var.cc', + 'tests/test_view.cc', ], # # Sources used in trusted tests. @@ -372,6 +373,8 @@ 'tests/test_utils.h', 'tests/test_var.cc', 'tests/test_var.h', + 'tests/test_view.cc', + 'tests/test_view.h', 'tests/test_video_decoder.cc', 'tests/test_video_decoder.h', 'tests/test_websocket.cc', diff --git a/ppapi/tests/test_case.cc b/ppapi/tests/test_case.cc index e6164e0..6ffe53e 100644 --- a/ppapi/tests/test_case.cc +++ b/ppapi/tests/test_case.cc @@ -71,7 +71,7 @@ bool TestCase::CheckTestingInterface() { void TestCase::HandleMessage(const pp::Var& message_data) { } -void TestCase::DidChangeView(const pp::Rect& position, const pp::Rect& clip) { +void TestCase::DidChangeView(const pp::View& view) { } bool TestCase::HandleInputEvent(const pp::InputEvent& event) { diff --git a/ppapi/tests/test_case.h b/ppapi/tests/test_case.h index 05fbb05..c04ed83 100644 --- a/ppapi/tests/test_case.h +++ b/ppapi/tests/test_case.h @@ -12,6 +12,7 @@ #include "ppapi/c/pp_resource.h" #include "ppapi/c/dev/ppb_testing_dev.h" #include "ppapi/cpp/dev/scrollbar_dev.h" +#include "ppapi/cpp/view.h" #if (defined __native_client__) #include "ppapi/cpp/var.h" @@ -62,7 +63,7 @@ class TestCase { // A function that is invoked whenever DidChangeView is called on the // associated TestingInstance. Default implementation does nothing. TestCases // that want to handle view changes should override this method. - virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip); + virtual void DidChangeView(const pp::View& view); // A function that is invoked whenever HandleInputEvent is called on the // associated TestingInstance. Default implementation returns false. TestCases diff --git a/ppapi/tests/test_case.html b/ppapi/tests/test_case.html index 7e8630e..f5c046e 100644 --- a/ppapi/tests/test_case.html +++ b/ppapi/tests/test_case.html @@ -153,10 +153,6 @@ onload = function() { obj = document.createElement("EMBED"); obj.setAttribute("src", "http://a.b.c/test"); obj.setAttribute("type", mimeType); - obj.setAttribute("width", 80); - obj.setAttribute("height", 80); - obj.setAttribute("style", - "background-color:#AAAAAA;border:1px solid black;"); } else { document.getElementById("console").innerHTML = '<span class="fail">FAIL</span>: ' + @@ -164,6 +160,10 @@ onload = function() { } } if (obj) { + obj.setAttribute("width", 80); + obj.setAttribute("height", 80); + obj.setAttribute("style", + "background-color:#AAAAAA;border:1px solid black;"); obj.setAttribute("id", "plugin"); obj.setAttribute("testcase", testcase); obj.setAttribute("protocol", window.location.protocol); diff --git a/ppapi/tests/test_flash_fullscreen.cc b/ppapi/tests/test_flash_fullscreen.cc index 0d49605..0d7163b 100644 --- a/ppapi/tests/test_flash_fullscreen.cc +++ b/ppapi/tests/test_flash_fullscreen.cc @@ -131,8 +131,9 @@ std::string TestFlashFullscreen::TestNormalToFullscreenToNormal() { // Transition to fullscreen is asynchornous ending at DidChangeView. // Transition to normal is synchronous in-process and asynchronous // out-of-process ending at DidChangeView. -void TestFlashFullscreen::DidChangeView(const pp::Rect& position, - const pp::Rect& clip) { +void TestFlashFullscreen::DidChangeView(const pp::View& view) { + pp::Rect position = view.GetRect(); + pp::Rect clip = view.GetClipRect(); if (fullscreen_pending_ && IsFullscreenView(position, clip, screen_size_)) { fullscreen_pending_ = false; pp::Module::Get()->core()->CallOnMainThread(0, fullscreen_callback_); diff --git a/ppapi/tests/test_flash_fullscreen.h b/ppapi/tests/test_flash_fullscreen.h index b5d6daf..b02ff2a 100644 --- a/ppapi/tests/test_flash_fullscreen.h +++ b/ppapi/tests/test_flash_fullscreen.h @@ -23,7 +23,7 @@ class TestFlashFullscreen : public TestCase { // TestCase implementation. virtual bool Init(); virtual void RunTests(const std::string& filter); - virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip); + virtual void DidChangeView(const pp::View& view); private: std::string TestGetScreenSize(); diff --git a/ppapi/tests/test_fullscreen.cc b/ppapi/tests/test_fullscreen.cc index f2b204e..5b2aabe 100644 --- a/ppapi/tests/test_fullscreen.cc +++ b/ppapi/tests/test_fullscreen.cc @@ -297,8 +297,10 @@ bool TestFullscreen::PaintPlugin(pp::Size size, ColorPremul color) { // fullscreen. // // NOTE: The number of DidChangeView calls for <object> might be different. -void TestFullscreen::DidChangeView(const pp::Rect& position, - const pp::Rect& clip) { +void TestFullscreen::DidChangeView(const pp::View& view) { + pp::Rect position = view.GetRect(); + pp::Rect clip = view.GetClipRect(); + if (normal_position_.IsEmpty()) { normal_position_ = position; if (!PaintPlugin(position.size(), kSheerRed)) diff --git a/ppapi/tests/test_fullscreen.h b/ppapi/tests/test_fullscreen.h index 220b7e9..f3efbcc 100644 --- a/ppapi/tests/test_fullscreen.h +++ b/ppapi/tests/test_fullscreen.h @@ -28,7 +28,7 @@ class TestFullscreen : public TestCase { virtual bool Init(); virtual void RunTests(const std::string& filter); virtual bool HandleInputEvent(const pp::InputEvent& event); - virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip); + virtual void DidChangeView(const pp::View& view); private: std::string TestGetScreenSize(); diff --git a/ppapi/tests/test_input_event.cc b/ppapi/tests/test_input_event.cc index 8ac9a8fd..c9f1736 100644 --- a/ppapi/tests/test_input_event.cc +++ b/ppapi/tests/test_input_event.cc @@ -26,7 +26,8 @@ pp::Point GetCenter(const pp::Rect& rect) { rect.x() + rect.width() / 2, rect.y() + rect.height() / 2); } -} + +} // namespace void TestInputEvent::RunTests(const std::string& filter) { RUN_TEST(Events, filter); @@ -243,9 +244,8 @@ void TestInputEvent::HandleMessage(const pp::Var& message_data) { } } -void TestInputEvent::DidChangeView(const pp::Rect& position, - const pp::Rect& clip) { - view_rect_ = position; +void TestInputEvent::DidChangeView(const pp::View& view) { + view_rect_ = view.GetRect(); } std::string TestInputEvent::TestEvents() { diff --git a/ppapi/tests/test_input_event.h b/ppapi/tests/test_input_event.h index 0bf2673..406c182 100644 --- a/ppapi/tests/test_input_event.h +++ b/ppapi/tests/test_input_event.h @@ -20,9 +20,9 @@ class TestInputEvent : public TestCase { explicit TestInputEvent(TestingInstance* instance); ~TestInputEvent(); - bool HandleInputEvent(const pp::InputEvent& input_event); - void HandleMessage(const pp::Var& message_data); - void DidChangeView(const pp::Rect& position, const pp::Rect& clip); + virtual bool HandleInputEvent(const pp::InputEvent& input_event); + virtual void HandleMessage(const pp::Var& message_data); + virtual void DidChangeView(const pp::View& view); // TestCase implementation. virtual bool Init(); diff --git a/ppapi/tests/test_view.cc b/ppapi/tests/test_view.cc new file mode 100644 index 0000000..3889285 --- /dev/null +++ b/ppapi/tests/test_view.cc @@ -0,0 +1,197 @@ +// Copyright (c) 2011 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.
+
+#include "ppapi/tests/test_view.h"
+
+#include <sstream>
+
+#include "ppapi/c/pp_time.h"
+#include "ppapi/c/dev/ppb_testing_dev.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/tests/testing_instance.h"
+
+REGISTER_TEST_CASE(View);
+
+// When waiting for view changed events, wait no longer than this.
+static int kViewChangeTimeoutSec = 5;
+
+TestView::TestView(TestingInstance* instance)
+ : TestCase(instance),
+ post_quit_on_view_changed_(false) {
+}
+
+void TestView::DidChangeView(const pp::View& view) {
+ last_view_ = view;
+ page_visibility_log_.push_back(view.IsPageVisible());
+
+ if (post_quit_on_view_changed_) {
+ post_quit_on_view_changed_ = false;
+ testing_interface_->QuitMessageLoop(instance_->pp_instance());
+ }
+}
+
+bool TestView::Init() {
+ return CheckTestingInterface();
+}
+
+void TestView::RunTests(const std::string& filter) {
+ RUN_TEST(CreatedVisible, filter);
+ RUN_TEST(CreatedInvisible, filter);
+ RUN_TEST(PageHideShow, filter);
+ RUN_TEST(SizeChange, filter);
+ RUN_TEST(ClipChange, filter);
+}
+
+bool TestView::WaitUntilViewChanged() {
+ // Schedule a callback so this step times out if we don't get a ViewChanged
+ // in a reasonable amount of time.
+ pp::CompletionCallbackFactory<TestView> factory(this);
+ pp::CompletionCallback timeout =
+ factory.NewCallback(&TestView::QuitMessageLoop);
+ pp::Module::Get()->core()->CallOnMainThread(
+ kViewChangeTimeoutSec * 1000, timeout);
+
+ size_t old_page_visibility_change_count = page_visibility_log_.size();
+
+ // Run a nested message loop. It will exit either on ViewChanged or if the
+ // timeout happens.
+ post_quit_on_view_changed_ = true;
+ testing_interface_->RunMessageLoop(instance_->pp_instance());
+ post_quit_on_view_changed_ = false;
+
+ // We know we got a view changed event if something was appended to the log.
+ return page_visibility_log_.size() > old_page_visibility_change_count;
+}
+
+void TestView::QuitMessageLoop(int32_t result) {
+ testing_interface_->QuitMessageLoop(instance_->pp_instance());
+}
+
+std::string TestView::TestCreatedVisible() {
+ ASSERT_FALSE(page_visibility_log_.empty());
+ ASSERT_TRUE(page_visibility_log_[0]);
+ PASS();
+}
+
+std::string TestView::TestCreatedInvisible() {
+ ASSERT_FALSE(page_visibility_log_.empty());
+
+ if (page_visibility_log_[0]) {
+ // Add more error message since this test has some extra requirements.
+ instance_->AppendError("Initial page is set to visible. NOTE: "
+ "This test must be run in a background tab. "
+ "Either run in the UI test which does this, or you can middle-click "
+ "on the test link to run manually.");
+ }
+ ASSERT_FALSE(page_visibility_log_[0]);
+ PASS();
+}
+
+std::string TestView::TestPageHideShow() {
+ // Initial state should be visible.
+ ASSERT_FALSE(page_visibility_log_.empty());
+ ASSERT_TRUE(page_visibility_log_[0]);
+
+ // Now that we're alive, set a cookie so the UI test knows it can change our
+ // visibility.
+ instance_->SetCookie("TestPageHideShow:Created", "TRUE");
+
+ // Wait until we get a hide event, being careful to handle spurious
+ // notifications of ViewChanged.
+ PP_Time begin_time = pp::Module::Get()->core()->GetTime();
+ while (WaitUntilViewChanged() &&
+ page_visibility_log_[page_visibility_log_.size() - 1] &&
+ pp::Module::Get()->core()->GetTime() - begin_time <
+ kViewChangeTimeoutSec) {
+ }
+ if (page_visibility_log_[page_visibility_log_.size() - 1]) {
+ // Didn't get a view changed event that changed visibility (though there
+ // may have been some that didn't change visibility).
+ // Add more error message since this test has some extra requirements.
+ return "Didn't receive a hide event in timeout. NOTE: "
+ "This test requires tab visibility to change and won't pass if you "
+ "just run it in a browser. Normally the UI test should handle "
+ "this. You can also run manually by waiting 2 secs, creating a new "
+ "tab, waiting 2 more secs, and closing the new tab.";
+ }
+
+ // Set a cookie so the UI test knows it can show us again.
+ instance_->SetCookie("TestPageHideShow:Hidden", "TRUE");
+
+ // Wait until we get a show event.
+ begin_time = pp::Module::Get()->core()->GetTime();
+ while (WaitUntilViewChanged() &&
+ !page_visibility_log_[page_visibility_log_.size() - 1] &&
+ pp::Module::Get()->core()->GetTime() - begin_time <
+ kViewChangeTimeoutSec) {
+ }
+ ASSERT_TRUE(page_visibility_log_[page_visibility_log_.size() - 1]);
+
+ PASS();
+}
+
+std::string TestView::TestSizeChange() {
+ pp::Rect original_rect = last_view_.GetRect();
+
+ pp::Rect desired_rect = original_rect;
+ desired_rect.set_width(original_rect.width() + 10);
+ desired_rect.set_height(original_rect.height() + 12);
+
+ std::ostringstream script_stream;
+ script_stream << "var plugin = document.getElementById('plugin');";
+ script_stream << "plugin.setAttribute('width', "
+ << desired_rect.width() << ");";
+ script_stream << "plugin.setAttribute('height', "
+ << desired_rect.height() << ");";
+
+ instance_->EvalScript(script_stream.str());
+
+ PP_Time begin_time = pp::Module::Get()->core()->GetTime();
+ while (WaitUntilViewChanged() && last_view_.GetRect() != desired_rect &&
+ pp::Module::Get()->core()->GetTime() - begin_time <
+ kViewChangeTimeoutSec) {
+ }
+ ASSERT_TRUE(last_view_.GetRect() == desired_rect);
+
+ PASS();
+}
+
+std::string TestView::TestClipChange() {
+ pp::Rect original_rect = last_view_.GetRect();
+
+ // Original clip should be the full frame.
+ pp::Rect original_clip = last_view_.GetClipRect();
+ ASSERT_TRUE(original_clip.x() == 0);
+ ASSERT_TRUE(original_clip.y() == 0);
+ ASSERT_TRUE(original_clip.width() == original_rect.width());
+ ASSERT_TRUE(original_clip.height() == original_rect.height());
+
+ int clip_amount = original_rect.height() / 2;
+
+ // It might be nice to set the position to be absolute and set the location,
+ // but this will cause WebKit to actually tear down the plugin and recreate
+ // it. So instead we add a big div to cause the document to be scrollable,
+ // and scroll it down.
+ std::ostringstream script_stream;
+ script_stream
+ << "var big = document.createElement('div');"
+ << "big.setAttribute('style', 'position:absolute; left:100px; "
+ "top:0px; width:1px; height:5000px;');"
+ << "document.body.appendChild(big);"
+ << "window.scrollBy(0, " << original_rect.y() + clip_amount << ");";
+
+ instance_->EvalScript(script_stream.str());
+
+ pp::Rect desired_clip = original_clip;
+ desired_clip.set_y(clip_amount);
+ desired_clip.set_height(desired_clip.height() - desired_clip.y());
+
+ PP_Time begin_time = pp::Module::Get()->core()->GetTime();
+ while (WaitUntilViewChanged() && last_view_.GetClipRect() != desired_clip &&
+ pp::Module::Get()->core()->GetTime() - begin_time <
+ kViewChangeTimeoutSec) {
+ }
+ ASSERT_TRUE(last_view_.GetClipRect() == desired_clip);
+ PASS();
+}
diff --git a/ppapi/tests/test_view.h b/ppapi/tests/test_view.h new file mode 100644 index 0000000..ff8b70a --- /dev/null +++ b/ppapi/tests/test_view.h @@ -0,0 +1,51 @@ +// Copyright (c) 2011 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.
+
+#ifndef PPAPI_TEST_TEST_VIEW_H_
+#define PPAPI_TEST_TEST_VIEW_H_
+
+#include "ppapi/cpp/view.h"
+#include "ppapi/tests/test_case.h"
+
+class TestView : public TestCase {
+ public:
+ TestView(TestingInstance* instance);
+
+ virtual void DidChangeView(const pp::View& view);
+
+ // TestCase implementation.
+ virtual bool Init();
+ virtual void RunTests(const std::string& test_filter);
+
+ private:
+ // Waits until we get a view changed event. Note that the browser may give
+ // us any number of view changed events, so tests that use this should
+ // expect that there may be spurious events and handle them accordingly.
+ // Note also that view changed sequencing can change between different
+ // versions of WebKit.
+ //
+ // Returns true if we got a view changed, false if it timed out.
+ bool WaitUntilViewChanged();
+
+ void QuitMessageLoop(int32_t result);
+
+ std::string TestCreatedVisible();
+ std::string TestCreatedInvisible();
+ std::string TestPageHideShow();
+ std::string TestSizeChange();
+ std::string TestClipChange();
+
+ pp::View last_view_;
+
+ // DidChangeView stores the page visibility in this vector on each
+ // invocation so tests can check it.
+ std::vector<bool> page_visibility_log_;
+
+ // Set to true to request that the next invocation of DidChangeView should
+ // post a quit to the message loop. DidChangeView will also reset the flag so
+ // this will only happen once.
+ bool post_quit_on_view_changed_;
+};
+
+#endif // PPAPI_TEST_TEST_VIEW_H_
diff --git a/ppapi/tests/testing_instance.cc b/ppapi/tests/testing_instance.cc index 88ef424..58e0890 100644 --- a/ppapi/tests/testing_instance.cc +++ b/ppapi/tests/testing_instance.cc @@ -11,6 +11,7 @@ #include "ppapi/cpp/module.h" #include "ppapi/cpp/var.h" +#include "ppapi/cpp/view.h" #include "ppapi/tests/test_case.h" TestCaseFactory* TestCaseFactory::head_ = NULL; @@ -83,8 +84,7 @@ void TestingInstance::HandleMessage(const pp::Var& message_data) { current_case_->HandleMessage(message_data); } -void TestingInstance::DidChangeView(const pp::Rect& position, - const pp::Rect& clip) { +void TestingInstance::DidChangeView(const pp::View& view) { if (!executed_tests_) { executed_tests_ = true; pp::Module::Get()->core()->CallOnMainThread( @@ -92,7 +92,7 @@ void TestingInstance::DidChangeView(const pp::Rect& position, callback_factory_.NewCallback(&TestingInstance::ExecuteTests)); } if (current_case_) - current_case_->DidChangeView(position, clip); + current_case_->DidChangeView(view); } bool TestingInstance::HandleInputEvent(const pp::InputEvent& event) { @@ -107,6 +107,15 @@ void TestingInstance::EvalScript(const std::string& script) { PostMessage(pp::Var(message)); } +void TestingInstance::SetCookie(const std::string& name, + const std::string& value) { + std::string message("TESTING_MESSAGE:SetCookie:"); + message.append(name); + message.append("="); + message.append(value); + PostMessage(pp::Var(message)); +} + void TestingInstance::LogTest(const std::string& test_name, const std::string& error_message) { // Tell the browser we're still working. @@ -230,15 +239,6 @@ void TestingInstance::ReportProgress(const std::string& progress_value) { progress_cookie_number_++; } -void TestingInstance::SetCookie(const std::string& name, - const std::string& value) { - std::string message("TESTING_MESSAGE:SetCookie:"); - message.append(name); - message.append("="); - message.append(value); - PostMessage(pp::Var(message)); -} - class Module : public pp::Module { public: Module() : pp::Module() {} diff --git a/ppapi/tests/testing_instance.h b/ppapi/tests/testing_instance.h index 397c1c7..74934a7 100644 --- a/ppapi/tests/testing_instance.h +++ b/ppapi/tests/testing_instance.h @@ -48,7 +48,7 @@ pp::InstancePrivate { // pp::Instance override. virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]); - virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip); + virtual void DidChangeView(const pp::View& view); virtual bool HandleInputEvent(const pp::InputEvent& event); #if !(defined __native_client__) @@ -86,6 +86,9 @@ pp::InstancePrivate { // Posts a message to the test page to eval() the script. void EvalScript(const std::string& script); + // Sets the given cookie in the current document. + void SetCookie(const std::string& name, const std::string& value); + private: void ExecuteTests(int32_t unused); @@ -114,9 +117,6 @@ pp::InstancePrivate { void ReportProgress(const std::string& progress_value); - // Sets the given cookie in the current document. - void SetCookie(const std::string& name, const std::string& value); - pp::CompletionCallbackFactory<TestingInstance> callback_factory_; // Owning pointer to the current test case. Valid after Init has been called. |