diff options
author | mitchellwrosen@chromium.org <mitchellwrosen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-15 23:26:06 +0000 |
---|---|---|
committer | mitchellwrosen@chromium.org <mitchellwrosen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-15 23:26:06 +0000 |
commit | fad7367a498d80a4c3e9e91342ffdfbaa7a4c3c6 (patch) | |
tree | e0c8def7c3c797cb8962fc47b46ce56d92a742bf /chrome/browser/extensions | |
parent | c572a3ef5d0af696b3a852f6ceb427e7e3a7e597 (diff) | |
download | chromium_src-fad7367a498d80a4c3e9e91342ffdfbaa7a4c3c6.zip chromium_src-fad7367a498d80a4c3e9e91342ffdfbaa7a4c3c6.tar.gz chromium_src-fad7367a498d80a4c3e9e91342ffdfbaa7a4c3c6.tar.bz2 |
BUG=110235
TEST=Manual
Refactored chrome/browser/extensions/extension_browsertests_misc.cc into several
files, as per Aaron's recommendations.
Review URL: https://chromiumcodereview.appspot.com/9568043
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142518 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r-- | chrome/browser/extensions/browser_action_apitest.cc | 24 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_bindings_apitest.cc | 24 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_browsertest.cc | 21 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_browsertest.h | 8 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_browsertests_misc.cc | 863 | ||||
-rw-r--r-- | chrome/browser/extensions/gpu_browsertest.cc | 32 | ||||
-rw-r--r-- | chrome/browser/extensions/options_page_apitest.cc | 52 | ||||
-rw-r--r-- | chrome/browser/extensions/page_action_browsertest.cc | 192 | ||||
-rw-r--r-- | chrome/browser/extensions/plugin_apitest.cc | 130 | ||||
-rw-r--r-- | chrome/browser/extensions/subscribe_page_action_browsertest.cc | 347 | ||||
-rw-r--r-- | chrome/browser/extensions/web_contents_browsertest.cc | 38 | ||||
-rw-r--r-- | chrome/browser/extensions/window_open_apitest.cc | 58 |
12 files changed, 925 insertions, 864 deletions
diff --git a/chrome/browser/extensions/browser_action_apitest.cc b/chrome/browser/extensions/browser_action_apitest.cc new file mode 100644 index 0000000..fed11d3 --- /dev/null +++ b/chrome/browser/extensions/browser_action_apitest.cc @@ -0,0 +1,24 @@ +// Copyright (c) 2012 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. + +// Tests that tooltips of a browser action icon can be specified using UTF8. +// See http://crbug.com/25349. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TitleLocalizationBrowserAction) { + ExtensionService* service = browser()->profile()->GetExtensionService(); + const size_t size_before = service->extensions()->size(); + FilePath extension_path(test_data_dir_.AppendASCII("browsertest") + .AppendASCII("title_localized")); + const Extension* extension = LoadExtension(extension_path); + ASSERT_TRUE(extension); + + ASSERT_EQ(size_before + 1, service->extensions()->size()); + + EXPECT_STREQ(WideToUTF8(L"Hreggvi\u00F0ur: l10n browser action").c_str(), + extension->description().c_str()); + EXPECT_STREQ(WideToUTF8(L"Hreggvi\u00F0ur is my name").c_str(), + extension->name().c_str()); + int tab_id = ExtensionTabUtil::GetTabId(browser()->GetActiveWebContents()); + EXPECT_STREQ(WideToUTF8(L"Hreggvi\u00F0ur").c_str(), + extension->browser_action()->GetTitle(tab_id).c_str()); +} diff --git a/chrome/browser/extensions/extension_bindings_apitest.cc b/chrome/browser/extensions/extension_bindings_apitest.cc index 8d5bf0a..91a9843 100644 --- a/chrome/browser/extensions/extension_bindings_apitest.cc +++ b/chrome/browser/extensions/extension_bindings_apitest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -6,8 +6,30 @@ #include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/browser/extensions/extension_host.h" +#include "chrome/browser/extensions/extension_process_manager.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/ui_test_utils.h" + IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ExceptionInHandlerShouldNotCrash) { ASSERT_TRUE(RunExtensionSubtest( "bindings/exception_in_handler_should_not_crash", "page.html")) << message_; } + +// Tests that an error raised during an async function still fires +// the callback, but sets chrome.extension.lastError. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, LastError) { + ASSERT_TRUE(LoadExtension( + test_data_dir_.AppendASCII("browsertest").AppendASCII("last_error"))); + + // Get the ExtensionHost that is hosting our background page. + ExtensionProcessManager* manager = + browser()->profile()->GetExtensionProcessManager(); + ExtensionHost* host = FindHostWithPath(manager, "/bg.html", 1); + + bool result = false; + ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( + host->render_view_host(), L"", L"testLastError()", &result)); + EXPECT_TRUE(result); +} diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc index 50365fe..a2992fc 100644 --- a/chrome/browser/extensions/extension_browsertest.cc +++ b/chrome/browser/extensions/extension_browsertest.cc @@ -18,6 +18,7 @@ #include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/extension_creator.h" #include "chrome/browser/extensions/extension_error_reporter.h" +#include "chrome/browser/extensions/extension_host.h" #include "chrome/browser/extensions/extension_install_prompt.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/unpacked_installer.h" @@ -521,6 +522,26 @@ void ExtensionBrowserTest::NavigateInRenderer(content::WebContents* contents, EXPECT_EQ(url, contents->GetController().GetLastCommittedEntry()->GetURL()); } +ExtensionHost* ExtensionBrowserTest::FindHostWithPath( + ExtensionProcessManager* manager, + const std::string& path, + int expected_hosts) { + ExtensionHost* host = NULL; + int num_hosts = 0; + ExtensionProcessManager::ExtensionHostSet background_hosts = + manager->background_hosts(); + for (ExtensionProcessManager::const_iterator iter = background_hosts.begin(); + iter != background_hosts.end(); ++iter) { + if ((*iter)->GetURL().path() == path) { + EXPECT_FALSE(host); + host = *iter; + } + num_hosts++; + } + EXPECT_EQ(expected_hosts, num_hosts); + return host; +} + void ExtensionBrowserTest::Observe( int type, const content::NotificationSource& source, diff --git a/chrome/browser/extensions/extension_browsertest.h b/chrome/browser/extensions/extension_browsertest.h index 30d345d..88d22fa 100644 --- a/chrome/browser/extensions/extension_browsertest.h +++ b/chrome/browser/extensions/extension_browsertest.h @@ -12,6 +12,7 @@ #include "base/compiler_specific.h" #include "base/file_path.h" #include "base/scoped_temp_dir.h" +#include "chrome/browser/extensions/extension_host.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_observer.h" @@ -151,6 +152,13 @@ class ExtensionBrowserTest // navigation. void NavigateInRenderer(content::WebContents* contents, const GURL& url); + // Looks for an ExtensionHost whose URL has the given path component + // (including leading slash). Also verifies that the expected number of hosts + // are loaded. + ExtensionHost* FindHostWithPath(ExtensionProcessManager* manager, + const std::string& path, + int expected_hosts); + // content::NotificationObserver virtual void Observe(int type, const content::NotificationSource& source, diff --git a/chrome/browser/extensions/extension_browsertests_misc.cc b/chrome/browser/extensions/extension_browsertests_misc.cc deleted file mode 100644 index cafeef2..0000000 --- a/chrome/browser/extensions/extension_browsertests_misc.cc +++ /dev/null @@ -1,863 +0,0 @@ -// Copyright (c) 2012 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 "base/file_util.h" -#include "base/memory/ref_counted.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/extensions/autoupdate_interceptor.h" -#include "chrome/browser/extensions/extension_apitest.h" -#include "chrome/browser/extensions/extension_browsertest.h" -#include "chrome/browser/extensions/extension_error_reporter.h" -#include "chrome/browser/extensions/extension_host.h" -#include "chrome/browser/extensions/extension_process_manager.h" -#include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/extensions/extension_tab_util.h" -#include "chrome/browser/prefs/pref_service.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_list.h" -#include "chrome/browser/ui/tab_contents/tab_contents.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/common/extensions/extension_action.h" -#include "chrome/common/pref_names.h" -#include "chrome/common/url_constants.h" -#include "chrome/test/base/ui_test_utils.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/web_contents.h" -#include "net/base/net_util.h" -#include "net/test/test_server.h" -#include "webkit/glue/webpreferences.h" - -using content::NavigationController; -using content::WebContents; -using extensions::Extension; - -const std::string kSubscribePage = "/subscribe.html"; -const std::string kFeedPage = "files/feeds/feed.html"; -const std::string kFeedPageMultiRel = "files/feeds/feed_multi_rel.html"; -const std::string kNoFeedPage = "files/feeds/no_feed.html"; -const std::string kValidFeed0 = "files/feeds/feed_script.xml"; -const std::string kValidFeed1 = "files/feeds/feed1.xml"; -const std::string kValidFeed2 = "files/feeds/feed2.xml"; -const std::string kValidFeed3 = "files/feeds/feed3.xml"; -const std::string kValidFeed4 = "files/feeds/feed4.xml"; -const std::string kValidFeed5 = "files/feeds/feed5.xml"; -const std::string kValidFeed6 = "files/feeds/feed6.xml"; -const std::string kValidFeedNoLinks = "files/feeds/feed_nolinks.xml"; -const std::string kInvalidFeed1 = "files/feeds/feed_invalid1.xml"; -const std::string kInvalidFeed2 = "files/feeds/feed_invalid2.xml"; -const std::string kLocalization = - "files/extensions/browsertest/title_localized_pa/simple.html"; -// We need a triple encoded string to prove that we are not decoding twice in -// subscribe.js because one layer is also stripped off when subscribe.js passes -// it to the XMLHttpRequest object. -const std::string kFeedTripleEncoded = "files/feeds/url%25255Fdecoding.html"; -const std::string kHashPageA = - "files/extensions/api_test/page_action/hash_change/test_page_A.html"; -const std::string kHashPageAHash = kHashPageA + "#asdf"; -const std::string kHashPageB = - "files/extensions/api_test/page_action/hash_change/test_page_B.html"; - -// Looks for an ExtensionHost whose URL has the given path component (including -// leading slash). Also verifies that the expected number of hosts are loaded. -static ExtensionHost* FindHostWithPath(ExtensionProcessManager* manager, - const std::string& path, - int expected_hosts) { - ExtensionHost* host = NULL; - int num_hosts = 0; - ExtensionProcessManager::ExtensionHostSet background_hosts = - manager->background_hosts(); - for (ExtensionProcessManager::const_iterator iter = background_hosts.begin(); - iter != background_hosts.end(); ++iter) { - if ((*iter)->GetURL().path() == path) { - EXPECT_FALSE(host); - host = *iter; - } - num_hosts++; - } - EXPECT_EQ(expected_hosts, num_hosts); - return host; -} - -// Tests that we can load extension pages into the tab area and they can call -// extension APIs. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WebContents) { - ASSERT_TRUE(LoadExtension( - test_data_dir_.AppendASCII("good").AppendASCII("Extensions") - .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") - .AppendASCII("1.0.0.0"))); - - ui_test_utils::NavigateToURL( - browser(), - GURL("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/page.html")); - - bool result = false; - ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( - browser()->GetActiveWebContents()->GetRenderViewHost(), L"", - L"testTabsAPI()", &result)); - EXPECT_TRUE(result); - - // There was a bug where we would crash if we navigated to a page in the same - // extension because no new render view was getting created, so we would not - // do some setup. - ui_test_utils::NavigateToURL( - browser(), - GURL("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/page.html")); - result = false; - ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( - browser()->GetActiveWebContents()->GetRenderViewHost(), L"", - L"testTabsAPI()", &result)); - EXPECT_TRUE(result); -} - -// Tests that GPU-related WebKit preferences are set for extension background -// pages. See http://crbug.com/64512. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WebKitPrefsBackgroundPage) { - ASSERT_TRUE(LoadExtension( - test_data_dir_.AppendASCII("good").AppendASCII("Extensions") - .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") - .AppendASCII("1.0.0.0"))); - - ExtensionProcessManager* manager = - browser()->profile()->GetExtensionProcessManager(); - ExtensionHost* host = FindHostWithPath(manager, "/backgroundpage.html", 1); - webkit_glue::WebPreferences prefs = - host->render_view_host()->GetWebkitPreferences(); - ASSERT_TRUE(prefs.experimental_webgl_enabled); - ASSERT_TRUE(prefs.accelerated_compositing_enabled); - ASSERT_TRUE(prefs.accelerated_2d_canvas_enabled); -} - -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PageActionCrash25562) { - ASSERT_TRUE(test_server()->Start()); - - CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kAllowLegacyExtensionManifests); - - // This page action will not show an icon, since it doesn't specify one but - // is included here to test for a crash (http://crbug.com/25562). - ASSERT_TRUE(LoadExtension( - test_data_dir_.AppendASCII("browsertest") - .AppendASCII("crash_25562"))); - - // Navigate to the feed page. - GURL feed_url = test_server()->GetURL(kFeedPage); - ui_test_utils::NavigateToURL(browser(), feed_url); - // We should now have one page action ready to go in the LocationBar. - ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); -} - -// Tests that we can load page actions in the Omnibox. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PageAction) { - ASSERT_TRUE(test_server()->Start()); - - ASSERT_TRUE(LoadExtension( - test_data_dir_.AppendASCII("subscribe_page_action"))); - - ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0)); - - // Navigate to the feed page. - GURL feed_url = test_server()->GetURL(kFeedPage); - ui_test_utils::NavigateToURL(browser(), feed_url); - // We should now have one page action ready to go in the LocationBar. - ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); - - // Navigate to a page with no feed. - GURL no_feed = test_server()->GetURL(kNoFeedPage); - ui_test_utils::NavigateToURL(browser(), no_feed); - // Make sure the page action goes away. - ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0)); -} - -// Tests that we don't lose the page action icon on in-page navigations. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PageActionInPageNavigation) { - ASSERT_TRUE(test_server()->Start()); - - FilePath extension_path(test_data_dir_.AppendASCII("api_test") - .AppendASCII("page_action") - .AppendASCII("hash_change")); - ASSERT_TRUE(LoadExtension(extension_path)); - - // Page action should become visible when we navigate here. - GURL feed_url = test_server()->GetURL(kHashPageA); - ui_test_utils::NavigateToURL(browser(), feed_url); - ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); - - // In-page navigation, page action should remain. - feed_url = test_server()->GetURL(kHashPageAHash); - ui_test_utils::NavigateToURL(browser(), feed_url); - ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); - - // Not an in-page navigation, page action should go away. - feed_url = test_server()->GetURL(kHashPageB); - ui_test_utils::NavigateToURL(browser(), feed_url); - ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0)); -} - -// Tests that the location bar forgets about unloaded page actions. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, UnloadPageAction) { - ASSERT_TRUE(test_server()->Start()); - - FilePath extension_path(test_data_dir_.AppendASCII("subscribe_page_action")); - ASSERT_TRUE(LoadExtension(extension_path)); - - // Navigation prompts the location bar to load page actions. - GURL feed_url = test_server()->GetURL(kFeedPage); - ui_test_utils::NavigateToURL(browser(), feed_url); - ASSERT_TRUE(WaitForPageActionCountChangeTo(1)); - - UnloadExtension(last_loaded_extension_id_); - - // Make sure the page action goes away when it's unloaded. - ASSERT_TRUE(WaitForPageActionCountChangeTo(0)); -} - -// Tests that we can load page actions in the Omnibox. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PageActionRefreshCrash) { - base::TimeTicks start_time = base::TimeTicks::Now(); - - ExtensionService* service = browser()->profile()->GetExtensionService(); - - size_t size_before = service->extensions()->size(); - - FilePath base_path = test_data_dir_.AppendASCII("browsertest") - .AppendASCII("crash_44415"); - // Load extension A. - const Extension* extensionA = LoadExtension(base_path.AppendASCII("ExtA")); - ASSERT_TRUE(extensionA); - ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); - ASSERT_EQ(size_before + 1, service->extensions()->size()); - - LOG(INFO) << "Load extension A done : " - << (base::TimeTicks::Now() - start_time).InMilliseconds() - << " ms" << std::flush; - - // Load extension B. - const Extension* extensionB = LoadExtension(base_path.AppendASCII("ExtB")); - ASSERT_TRUE(extensionB); - ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(2)); - ASSERT_EQ(size_before + 2, service->extensions()->size()); - - LOG(INFO) << "Load extension B done : " - << (base::TimeTicks::Now() - start_time).InMilliseconds() - << " ms" << std::flush; - - std::string idA = extensionA->id(); - ReloadExtension(extensionA->id()); - // ExtensionA has changed, so refetch it. - ASSERT_EQ(size_before + 2, service->extensions()->size()); - extensionA = service->extensions()->GetByID(idA); - - LOG(INFO) << "Reload extension A done: " - << (base::TimeTicks::Now() - start_time).InMilliseconds() - << " ms" << std::flush; - - ReloadExtension(extensionB->id()); - - LOG(INFO) << "Reload extension B done: " - << (base::TimeTicks::Now() - start_time).InMilliseconds() - << " ms" << std::flush; - - // This is where it would crash, before http://crbug.com/44415 was fixed. - ReloadExtension(extensionA->id()); - - LOG(INFO) << "Test completed : " - << (base::TimeTicks::Now() - start_time).InMilliseconds() - << " ms" << std::flush; -} - -// Makes sure that the RSS detects RSS feed links, even when rel tag contains -// more than just "alternate". -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSMultiRelLink) { - ASSERT_TRUE(test_server()->Start()); - - ASSERT_TRUE(LoadExtension( - test_data_dir_.AppendASCII("subscribe_page_action"))); - - ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0)); - - // Navigate to the feed page. - GURL feed_url = test_server()->GetURL(kFeedPageMultiRel); - ui_test_utils::NavigateToURL(browser(), feed_url); - // We should now have one page action ready to go in the LocationBar. - ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); -} - -// Tests that tooltips of a browser action icon can be specified using UTF8. -// See http://crbug.com/25349. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TitleLocalizationBrowserAction) { - ExtensionService* service = browser()->profile()->GetExtensionService(); - const size_t size_before = service->extensions()->size(); - FilePath extension_path(test_data_dir_.AppendASCII("browsertest") - .AppendASCII("title_localized")); - const Extension* extension = LoadExtension(extension_path); - ASSERT_TRUE(extension); - - ASSERT_EQ(size_before + 1, service->extensions()->size()); - - EXPECT_STREQ(WideToUTF8(L"Hreggvi\u00F0ur: l10n browser action").c_str(), - extension->description().c_str()); - EXPECT_STREQ(WideToUTF8(L"Hreggvi\u00F0ur is my name").c_str(), - extension->name().c_str()); - int tab_id = ExtensionTabUtil::GetTabId(browser()->GetActiveWebContents()); - EXPECT_STREQ(WideToUTF8(L"Hreggvi\u00F0ur").c_str(), - extension->browser_action()->GetTitle(tab_id).c_str()); -} - -// Tests that tooltips of a page action icon can be specified using UTF8. -// See http://crbug.com/25349. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TitleLocalizationPageAction) { - ASSERT_TRUE(test_server()->Start()); - - ExtensionService* service = browser()->profile()->GetExtensionService(); - const size_t size_before = service->extensions()->size(); - - FilePath extension_path(test_data_dir_.AppendASCII("browsertest") - .AppendASCII("title_localized_pa")); - const Extension* extension = LoadExtension(extension_path); - ASSERT_TRUE(extension); - - // Any navigation prompts the location bar to load the page action. - GURL url = test_server()->GetURL(kLocalization); - ui_test_utils::NavigateToURL(browser(), url); - ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); - - ASSERT_EQ(size_before + 1, service->extensions()->size()); - - EXPECT_STREQ(WideToUTF8(L"Hreggvi\u00F0ur: l10n page action").c_str(), - extension->description().c_str()); - EXPECT_STREQ(WideToUTF8(L"Hreggvi\u00F0ur is my name").c_str(), - extension->name().c_str()); - int tab_id = ExtensionTabUtil::GetTabId(browser()->GetActiveWebContents()); - EXPECT_STREQ(WideToUTF8(L"Hreggvi\u00F0ur").c_str(), - extension->page_action()->GetTitle(tab_id).c_str()); -} - -GURL GetFeedUrl(net::TestServer* server, const std::string& feed_page, - bool direct_url, std::string extension_id) { - GURL feed_url = server->GetURL(feed_page); - if (direct_url) { - // We navigate directly to the subscribe page for feeds where the feed - // sniffing won't work, in other words, as is the case for malformed feeds. - return GURL(std::string(chrome::kExtensionScheme) + - content::kStandardSchemeSeparator + - extension_id + std::string(kSubscribePage) + std::string("?") + - feed_url.spec() + std::string("&synchronous")); - } else { - // Navigate to the feed content (which will cause the extension to try to - // sniff the type and display the subscribe page in another tab. - return GURL(feed_url.spec()); - } -} - -static const wchar_t* jscript_feed_title = - L"window.domAutomationController.send(" - L" document.getElementById('title') ? " - L" document.getElementById('title').textContent : " - L" \"element 'title' not found\"" - L");"; -static const wchar_t* jscript_anchor = - L"window.domAutomationController.send(" - L" document.getElementById('anchor_0') ? " - L" document.getElementById('anchor_0').textContent : " - L" \"element 'anchor_0' not found\"" - L");"; -static const wchar_t* jscript_desc = - L"window.domAutomationController.send(" - L" document.getElementById('desc_0') ? " - L" document.getElementById('desc_0').textContent : " - L" \"element 'desc_0' not found\"" - L");"; -static const wchar_t* jscript_error = - L"window.domAutomationController.send(" - L" document.getElementById('error') ? " - L" document.getElementById('error').textContent : " - L" \"No error\"" - L");"; - -bool ValidatePageElement(WebContents* tab, - const std::wstring& frame, - const std::wstring& javascript, - const std::string& expected_value) { - std::string returned_value; - std::string error; - - if (!ui_test_utils::ExecuteJavaScriptAndExtractString( - tab->GetRenderViewHost(), - frame, - javascript, &returned_value)) - return false; - - EXPECT_STREQ(expected_value.c_str(), returned_value.c_str()); - return expected_value == returned_value; -} - -// Navigates to a feed page and, if |sniff_xml_type| is set, wait for the -// extension to kick in, detect the feed and redirect to a feed preview page. -// |sniff_xml_type| is generally set to true if the feed is sniffable and false -// for invalid feeds. -void NavigateToFeedAndValidate(net::TestServer* server, - const std::string& url, - Browser* browser, - std::string extension_id, - bool sniff_xml_type, - const std::string& expected_feed_title, - const std::string& expected_item_title, - const std::string& expected_item_desc, - const std::string& expected_error) { - if (sniff_xml_type) { - // TODO(finnur): Implement this is a non-flaky way. - } - - // Navigate to the subscribe page directly. - ui_test_utils::NavigateToURL(browser, - GetFeedUrl(server, url, true, extension_id)); - - WebContents* tab = browser->GetActiveWebContents(); - ASSERT_TRUE(ValidatePageElement(tab, - L"", - jscript_feed_title, - expected_feed_title)); - ASSERT_TRUE(ValidatePageElement(tab, - L"//html/body/div/iframe[1]", - jscript_anchor, - expected_item_title)); - ASSERT_TRUE(ValidatePageElement(tab, - L"//html/body/div/iframe[1]", - jscript_desc, - expected_item_desc)); - ASSERT_TRUE(ValidatePageElement(tab, - L"//html/body/div/iframe[1]", - jscript_error, - expected_error)); -} - -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed1) { - ASSERT_TRUE(test_server()->Start()); - - const Extension* extension = LoadExtension( - test_data_dir_.AppendASCII("subscribe_page_action")); - ASSERT_TRUE(extension); - std::string id = extension->id(); - - NavigateToFeedAndValidate(test_server(), kValidFeed1, browser(), id, true, - "Feed for MyFeedTitle", - "Title 1", - "Desc", - "No error"); -} - -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed2) { - ASSERT_TRUE(test_server()->Start()); - - const Extension* extension = LoadExtension( - test_data_dir_.AppendASCII("subscribe_page_action")); - ASSERT_TRUE(extension); - std::string id = extension->id(); - - NavigateToFeedAndValidate(test_server(), kValidFeed2, browser(), id, true, - "Feed for MyFeed2", - "My item title1", - "This is a summary.", - "No error"); -} - -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed3) { - ASSERT_TRUE(test_server()->Start()); - - const Extension* extension = LoadExtension( - test_data_dir_.AppendASCII("subscribe_page_action")); - ASSERT_TRUE(extension); - std::string id = extension->id(); - - NavigateToFeedAndValidate(test_server(), kValidFeed3, browser(), id, true, - "Feed for Google Code buglist rss feed", - "My dear title", - "My dear content", - "No error"); -} - -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed4) { - ASSERT_TRUE(test_server()->Start()); - - const Extension* extension = LoadExtension( - test_data_dir_.AppendASCII("subscribe_page_action")); - ASSERT_TRUE(extension); - std::string id = extension->id(); - - NavigateToFeedAndValidate(test_server(), kValidFeed4, browser(), id, true, - "Feed for Title chars <script> %23 stop", - "Title chars %23 stop", - "My dear content %23 stop", - "No error"); -} - -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed0) { - ASSERT_TRUE(test_server()->Start()); - - const Extension* extension = LoadExtension( - test_data_dir_.AppendASCII("subscribe_page_action")); - ASSERT_TRUE(extension); - std::string id = extension->id(); - - // Try a feed with a link with an onclick handler (before r27440 this would - // trigger a NOTREACHED). - NavigateToFeedAndValidate(test_server(), kValidFeed0, browser(), id, true, - "Feed for MyFeedTitle", - "Title 1", - "Desc VIDEO", - "No error"); -} - -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed5) { - ASSERT_TRUE(test_server()->Start()); - - const Extension* extension = LoadExtension( - test_data_dir_.AppendASCII("subscribe_page_action")); - ASSERT_TRUE(extension); - std::string id = extension->id(); - - // Feed with valid but mostly empty xml. - NavigateToFeedAndValidate(test_server(), kValidFeed5, browser(), id, true, - "Feed for Unknown feed name", - "element 'anchor_0' not found", - "element 'desc_0' not found", - "This feed contains no entries."); -} - -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed6) { - ASSERT_TRUE(test_server()->Start()); - - const Extension* extension = LoadExtension( - test_data_dir_.AppendASCII("subscribe_page_action")); - ASSERT_TRUE(extension); - std::string id = extension->id(); - - // Feed that is technically invalid but still parseable. - NavigateToFeedAndValidate(test_server(), kValidFeed6, browser(), id, true, - "Feed for MyFeedTitle", - "Title 1", - "Desc", - "No error"); -} - -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedInvalidFeed1) { - ASSERT_TRUE(test_server()->Start()); - - const Extension* extension = LoadExtension( - test_data_dir_.AppendASCII("subscribe_page_action")); - ASSERT_TRUE(extension); - std::string id = extension->id(); - - // Try an empty feed. - NavigateToFeedAndValidate(test_server(), kInvalidFeed1, browser(), id, false, - "Feed for Unknown feed name", - "element 'anchor_0' not found", - "element 'desc_0' not found", - "This feed contains no entries."); -} - -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedInvalidFeed2) { - ASSERT_TRUE(test_server()->Start()); - - const Extension* extension = LoadExtension( - test_data_dir_.AppendASCII("subscribe_page_action")); - ASSERT_TRUE(extension); - std::string id = extension->id(); - - // Try a garbage feed. - NavigateToFeedAndValidate(test_server(), kInvalidFeed2, browser(), id, false, - "Feed for Unknown feed name", - "element 'anchor_0' not found", - "element 'desc_0' not found", - "This feed contains no entries."); -} - -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedInvalidFeed3) { - ASSERT_TRUE(test_server()->Start()); - - const Extension* extension = LoadExtension( - test_data_dir_.AppendASCII("subscribe_page_action")); - ASSERT_TRUE(extension); - std::string id = extension->id(); - - // Try a feed that doesn't exist. - NavigateToFeedAndValidate(test_server(), "foo.xml", browser(), id, false, - "Feed for Unknown feed name", - "element 'anchor_0' not found", - "element 'desc_0' not found", - "This feed contains no entries."); -} - -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedInvalidFeed4) { - ASSERT_TRUE(test_server()->Start()); - - const Extension* extension = LoadExtension( - test_data_dir_.AppendASCII("subscribe_page_action")); - ASSERT_TRUE(extension); - std::string id = extension->id(); - - // subscribe.js shouldn't double-decode the URL passed in. Otherwise feed - // links such as http://search.twitter.com/search.atom?lang=en&q=%23chrome - // will result in no feed being downloaded because %23 gets decoded to # and - // therefore #chrome is not treated as part of the Twitter query. This test - // uses an underscore instead of a hash, but the principle is the same. If - // we start erroneously double decoding again, the path (and the feed) will - // become valid resulting in a failure for this test. - NavigateToFeedAndValidate( - test_server(), kFeedTripleEncoded, browser(), id, true, - "Feed for Unknown feed name", - "element 'anchor_0' not found", - "element 'desc_0' not found", - "This feed contains no entries."); -} - -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeedNoLinks) { - ASSERT_TRUE(test_server()->Start()); - - const Extension* extension = LoadExtension( - test_data_dir_.AppendASCII("subscribe_page_action")); - ASSERT_TRUE(extension); - std::string id = extension->id(); - - // Valid feed but containing no links. - NavigateToFeedAndValidate( - test_server(), kValidFeedNoLinks, browser(), id, true, - "Feed for MyFeedTitle", - "Title with no link", - "Desc", - "No error"); -} - -// Tests that an error raised during an async function still fires -// the callback, but sets chrome.extension.lastError. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, LastError) { - ASSERT_TRUE(LoadExtension( - test_data_dir_.AppendASCII("browsertest").AppendASCII("last_error"))); - - // Get the ExtensionHost that is hosting our background page. - ExtensionProcessManager* manager = - browser()->profile()->GetExtensionProcessManager(); - ExtensionHost* host = FindHostWithPath(manager, "/bg.html", 1); - - bool result = false; - ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( - host->render_view_host(), L"", L"testLastError()", &result)); - EXPECT_TRUE(result); -} - -// Tests that an extension page can call window.open to an extension URL and -// the new window has extension privileges. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenExtension) { - ASSERT_TRUE(LoadExtension( - test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"))); - - GURL start_url(std::string("chrome-extension://") + - last_loaded_extension_id_ + "/test.html"); - ui_test_utils::NavigateToURL(browser(), start_url); - WebContents* newtab; - ASSERT_NO_FATAL_FAILURE(OpenWindow(browser()->GetActiveWebContents(), - start_url.Resolve("newtab.html"), true, &newtab)); - - bool result = false; - ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( - newtab->GetRenderViewHost(), L"", L"testExtensionApi()", &result)); - EXPECT_TRUE(result); -} - -// Tests that if an extension page calls window.open to an invalid extension -// URL, the browser doesn't crash. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenInvalidExtension) { - ASSERT_TRUE(LoadExtension( - test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"))); - - GURL start_url(std::string("chrome-extension://") + - last_loaded_extension_id_ + "/test.html"); - ui_test_utils::NavigateToURL(browser(), start_url); - ASSERT_NO_FATAL_FAILURE(OpenWindow(browser()->GetActiveWebContents(), - GURL("chrome-extension://thisissurelynotavalidextensionid/newtab.html"), - false, NULL)); - - // If we got to this point, we didn't crash, so we're good. -} - -// Tests that calling window.open from the newtab page to an extension URL -// gives the new window extension privileges - even though the opening page -// does not have extension privileges, we break the script connection, so -// there is no privilege leak. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenNoPrivileges) { - ASSERT_TRUE(LoadExtension( - test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"))); - - ui_test_utils::NavigateToURL(browser(), GURL("about:blank")); - WebContents* newtab; - ASSERT_NO_FATAL_FAILURE(OpenWindow(browser()->GetActiveWebContents(), - GURL(std::string("chrome-extension://") + last_loaded_extension_id_ + - "/newtab.html"), false, &newtab)); - - // Extension API should succeed. - bool result = false; - ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( - newtab->GetRenderViewHost(), L"", L"testExtensionApi()", &result)); - EXPECT_TRUE(result); -} - -#if defined(OS_WIN) && defined(NDEBUG) -#define MAYBE_PluginLoadUnload PluginLoadUnload -#elif defined(OS_WIN) && !defined(NDEBUG) -// http://crbug.com/123851 Debug builds are flaky. -#define MAYBE_PluginLoadUnload FLAKY_PluginLoadUnload -#elif defined(OS_LINUX) -// http://crbug.com/47598 -#define MAYBE_PluginLoadUnload DISABLED_PluginLoadUnload -#else -// TODO(mpcomplete): http://crbug.com/29900 need cross platform plugin support. -#define MAYBE_PluginLoadUnload DISABLED_PluginLoadUnload -#endif - -// Tests that a renderer's plugin list is properly updated when we load and -// unload an extension that contains a plugin. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MAYBE_PluginLoadUnload) { - browser()->profile()->GetPrefs()->SetBoolean(prefs::kPluginsAlwaysAuthorize, - true); - - FilePath extension_dir = - test_data_dir_.AppendASCII("uitest").AppendASCII("plugins"); - - ui_test_utils::NavigateToURL(browser(), - net::FilePathToFileURL(extension_dir.AppendASCII("test.html"))); - WebContents* tab = browser()->GetActiveWebContents(); - - // With no extensions, the plugin should not be loaded. - bool result = false; - ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( - tab->GetRenderViewHost(), L"", L"testPluginWorks()", &result)); - EXPECT_FALSE(result); - - ExtensionService* service = browser()->profile()->GetExtensionService(); - service->set_show_extensions_prompts(false); - const size_t size_before = service->extensions()->size(); - const Extension* extension = LoadExtension(extension_dir); - ASSERT_TRUE(extension); - EXPECT_EQ(size_before + 1, service->extensions()->size()); - // Now the plugin should be in the cache. - ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( - tab->GetRenderViewHost(), L"", L"testPluginWorks()", &result)); - EXPECT_TRUE(result); - - EXPECT_EQ(size_before + 1, service->extensions()->size()); - UnloadExtension(extension->id()); - EXPECT_EQ(size_before, service->extensions()->size()); - - // Now the plugin should be unloaded, and the page should be broken. - - ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( - tab->GetRenderViewHost(), L"", L"testPluginWorks()", &result)); - EXPECT_FALSE(result); - - // If we reload the extension and page, it should work again. - - ASSERT_TRUE(LoadExtension(extension_dir)); - EXPECT_EQ(size_before + 1, service->extensions()->size()); - { - ui_test_utils::WindowedNotificationObserver observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>( - &browser()->GetActiveWebContents()->GetController())); - browser()->Reload(CURRENT_TAB); - observer.Wait(); - } - ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( - tab->GetRenderViewHost(), L"", L"testPluginWorks()", &result)); - EXPECT_TRUE(result); -} - -#if defined(OS_WIN) || defined(OS_LINUX) -#define MAYBE_PluginPrivate PluginPrivate -#else -// TODO(mpcomplete): http://crbug.com/29900 need cross platform plugin support. -#define MAYBE_PluginPrivate DISABLED_PluginPrivate -#endif - -// Tests that private extension plugins are only visible to the extension. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MAYBE_PluginPrivate) { - FilePath extension_dir = - test_data_dir_.AppendASCII("uitest").AppendASCII("plugins_private"); - - ExtensionService* service = browser()->profile()->GetExtensionService(); - service->set_show_extensions_prompts(false); - const size_t size_before = service->extensions()->size(); - const Extension* extension = LoadExtension(extension_dir); - ASSERT_TRUE(extension); - EXPECT_EQ(size_before + 1, service->extensions()->size()); - - // Load the test page through the extension URL, and the plugin should work. - ui_test_utils::NavigateToURL(browser(), - extension->GetResourceURL("test.html")); - WebContents* tab = browser()->GetActiveWebContents(); - bool result = false; - ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( - tab->GetRenderViewHost(), L"", L"testPluginWorks()", &result)); - // We don't allow extension plugins to run on ChromeOS. -#if defined(OS_CHROMEOS) - EXPECT_FALSE(result); -#else - EXPECT_TRUE(result); -#endif - - // Now load it through a file URL. The plugin should not load. - ui_test_utils::NavigateToURL(browser(), - net::FilePathToFileURL(extension_dir.AppendASCII("test.html"))); - ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( - tab->GetRenderViewHost(), L"", L"testPluginWorks()", &result)); - EXPECT_FALSE(result); -} - -// Used to simulate a click on the first button named 'Options'. -static const wchar_t* jscript_click_option_button = - L"(function() { " - L" var button = document.evaluate(\"//button[text()='Options']\"," - L" document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE," - L" null).snapshotItem(0);" - L" button.click();" - L"})();"; - -// Test that an extension with an options page makes an 'Options' button appear -// on chrome://extensions, and that clicking the button opens a new tab with the -// extension's options page. -// Disabled. See http://crbug.com/26948 for details. -IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, DISABLED_OptionsPage) { - // Install an extension with an options page. - const Extension* extension = - InstallExtension(test_data_dir_.AppendASCII("options.crx"), 1); - ASSERT_TRUE(extension); - ExtensionService* service = browser()->profile()->GetExtensionService(); - ASSERT_EQ(1u, service->extensions()->size()); - - // Go to the Extension Settings page and click the Options button. - ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIExtensionsURL)); - TabStripModel* tab_strip = browser()->tab_strip_model(); - ASSERT_TRUE(ui_test_utils::ExecuteJavaScript( - browser()->GetActiveWebContents()->GetRenderViewHost(), L"", - jscript_click_option_button)); - - // If the options page hasn't already come up, wait for it. - if (tab_strip->count() == 1) { - ui_test_utils::WaitForNewTab(browser()); - } - ASSERT_EQ(2, tab_strip->count()); - - EXPECT_EQ(extension->GetResourceURL("options.html"), - tab_strip->GetTabContentsAt(1)->web_contents()->GetURL()); -} - -//============================================================================== -// STOP! Please do not add any more random-ass tests here. Create new files for -// your tests grouped by functionality. Also, you should strongly consider using -// ExtensionAPITest if possible. -//============================================================================== diff --git a/chrome/browser/extensions/gpu_browsertest.cc b/chrome/browser/extensions/gpu_browsertest.cc new file mode 100644 index 0000000..24b3759 --- /dev/null +++ b/chrome/browser/extensions/gpu_browsertest.cc @@ -0,0 +1,32 @@ +// Copyright (c) 2012 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. + +// Copyright (c) 2012 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 "chrome/browser/extensions/extension_browsertest.h" +#include "chrome/browser/extensions/extension_host.h" +#include "chrome/browser/extensions/extension_process_manager.h" +#include "chrome/browser/ui/browser.h" +#include "content/public/browser/render_view_host.h" +#include "webkit/glue/webpreferences.h" + +// Tests that GPU-related WebKit preferences are set for extension background +// pages. See http://crbug.com/64512. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WebKitPrefsBackgroundPage) { + ASSERT_TRUE(LoadExtension( + test_data_dir_.AppendASCII("good").AppendASCII("Extensions") + .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") + .AppendASCII("1.0.0.0"))); + + ExtensionProcessManager* manager = + browser()->profile()->GetExtensionProcessManager(); + ExtensionHost* host = FindHostWithPath(manager, "/backgroundpage.html", 1); + webkit_glue::WebPreferences prefs = + host->render_view_host()->GetWebkitPreferences(); + ASSERT_TRUE(prefs.experimental_webgl_enabled); + ASSERT_TRUE(prefs.accelerated_compositing_enabled); + ASSERT_TRUE(prefs.accelerated_2d_canvas_enabled); +} diff --git a/chrome/browser/extensions/options_page_apitest.cc b/chrome/browser/extensions/options_page_apitest.cc new file mode 100644 index 0000000..c281ac2 --- /dev/null +++ b/chrome/browser/extensions/options_page_apitest.cc @@ -0,0 +1,52 @@ +// Copyright (c) 2012 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 "chrome/browser/extensions/extension_browsertest.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tab_contents/tab_contents.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/url_constants.h" +#include "chrome/test/base/ui_test_utils.h" + +using extensions::Extension; + +// Used to simulate a click on the first button named 'Options'. +static const wchar_t* jscript_click_option_button = + L"(function() { " + L" var button = document.evaluate(\"//button[text()='Options']\"," + L" document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE," + L" null).snapshotItem(0);" + L" button.click();" + L"})();"; + +// Test that an extension with an options page makes an 'Options' button appear +// on chrome://extensions, and that clicking the button opens a new tab with the +// extension's options page. +// Disabled. See http://crbug.com/26948 for details. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, DISABLED_OptionsPage) { + // Install an extension with an options page. + const Extension* extension = + InstallExtension(test_data_dir_.AppendASCII("options.crx"), 1); + ASSERT_TRUE(extension); + ExtensionService* service = browser()->profile()->GetExtensionService(); + ASSERT_EQ(1u, service->extensions()->size()); + + // Go to the Extension Settings page and click the Options button. + ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIExtensionsURL)); + TabStripModel* tab_strip = browser()->tab_strip_model(); + ASSERT_TRUE(ui_test_utils::ExecuteJavaScript( + browser()->GetActiveWebContents()->GetRenderViewHost(), L"", + jscript_click_option_button)); + + // If the options page hasn't already come up, wait for it. + if (tab_strip->count() == 1) { + ui_test_utils::WaitForNewTab(browser()); + } + ASSERT_EQ(2, tab_strip->count()); + + EXPECT_EQ(extension->GetResourceURL("options.html"), + tab_strip->GetTabContentsAt(1)->web_contents()->GetURL()); +} diff --git a/chrome/browser/extensions/page_action_browsertest.cc b/chrome/browser/extensions/page_action_browsertest.cc new file mode 100644 index 0000000..90e7e9c --- /dev/null +++ b/chrome/browser/extensions/page_action_browsertest.cc @@ -0,0 +1,192 @@ +// Copyright (c) 2012 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 "base/utf_string_conversions.h" +#include "chrome/browser/extensions/extension_browsertest.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_tab_util.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/test/base/ui_test_utils.h" + +using extensions::Extension; + +const std::string kFeedPage = "files/feeds/feed.html"; +const std::string kNoFeedPage = "files/feeds/no_feed.html"; +const std::string kLocalization = + "files/extensions/browsertest/title_localized_pa/simple.html"; + +const std::string kHashPageA = + "files/extensions/api_test/page_action/hash_change/test_page_A.html"; +const std::string kHashPageAHash = kHashPageA + "#asdf"; +const std::string kHashPageB = + "files/extensions/api_test/page_action/hash_change/test_page_B.html"; + +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PageActionCrash25562) { + ASSERT_TRUE(test_server()->Start()); + + CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kAllowLegacyExtensionManifests); + + // This page action will not show an icon, since it doesn't specify one but + // is included here to test for a crash (http://crbug.com/25562). + ASSERT_TRUE(LoadExtension( + test_data_dir_.AppendASCII("browsertest") + .AppendASCII("crash_25562"))); + + // Navigate to the feed page. + GURL feed_url = test_server()->GetURL(kFeedPage); + ui_test_utils::NavigateToURL(browser(), feed_url); + // We should now have one page action ready to go in the LocationBar. + ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); +} + +// Tests that we can load page actions in the Omnibox. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PageAction) { + ASSERT_TRUE(test_server()->Start()); + + ASSERT_TRUE(LoadExtension( + test_data_dir_.AppendASCII("subscribe_page_action"))); + + ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0)); + + // Navigate to the feed page. + GURL feed_url = test_server()->GetURL(kFeedPage); + ui_test_utils::NavigateToURL(browser(), feed_url); + // We should now have one page action ready to go in the LocationBar. + ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); + + // Navigate to a page with no feed. + GURL no_feed = test_server()->GetURL(kNoFeedPage); + ui_test_utils::NavigateToURL(browser(), no_feed); + // Make sure the page action goes away. + ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0)); +} + +// Tests that we don't lose the page action icon on in-page navigations. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PageActionInPageNavigation) { + ASSERT_TRUE(test_server()->Start()); + + FilePath extension_path(test_data_dir_.AppendASCII("api_test") + .AppendASCII("page_action") + .AppendASCII("hash_change")); + ASSERT_TRUE(LoadExtension(extension_path)); + + // Page action should become visible when we navigate here. + GURL feed_url = test_server()->GetURL(kHashPageA); + ui_test_utils::NavigateToURL(browser(), feed_url); + ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); + + // In-page navigation, page action should remain. + feed_url = test_server()->GetURL(kHashPageAHash); + ui_test_utils::NavigateToURL(browser(), feed_url); + ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); + + // Not an in-page navigation, page action should go away. + feed_url = test_server()->GetURL(kHashPageB); + ui_test_utils::NavigateToURL(browser(), feed_url); + ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0)); +} + +// Tests that the location bar forgets about unloaded page actions. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, UnloadPageAction) { + ASSERT_TRUE(test_server()->Start()); + + FilePath extension_path(test_data_dir_.AppendASCII("subscribe_page_action")); + ASSERT_TRUE(LoadExtension(extension_path)); + + // Navigation prompts the location bar to load page actions. + GURL feed_url = test_server()->GetURL(kFeedPage); + ui_test_utils::NavigateToURL(browser(), feed_url); + ASSERT_TRUE(WaitForPageActionCountChangeTo(1)); + + UnloadExtension(last_loaded_extension_id_); + + // Make sure the page action goes away when it's unloaded. + ASSERT_TRUE(WaitForPageActionCountChangeTo(0)); +} + +// Tests that we can load page actions in the Omnibox. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, PageActionRefreshCrash) { + base::TimeTicks start_time = base::TimeTicks::Now(); + + ExtensionService* service = browser()->profile()->GetExtensionService(); + + size_t size_before = service->extensions()->size(); + + FilePath base_path = test_data_dir_.AppendASCII("browsertest") + .AppendASCII("crash_44415"); + // Load extension A. + const Extension* extensionA = LoadExtension(base_path.AppendASCII("ExtA")); + ASSERT_TRUE(extensionA); + ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); + ASSERT_EQ(size_before + 1, service->extensions()->size()); + + LOG(INFO) << "Load extension A done : " + << (base::TimeTicks::Now() - start_time).InMilliseconds() + << " ms" << std::flush; + + // Load extension B. + const Extension* extensionB = LoadExtension(base_path.AppendASCII("ExtB")); + ASSERT_TRUE(extensionB); + ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(2)); + ASSERT_EQ(size_before + 2, service->extensions()->size()); + + LOG(INFO) << "Load extension B done : " + << (base::TimeTicks::Now() - start_time).InMilliseconds() + << " ms" << std::flush; + + std::string idA = extensionA->id(); + ReloadExtension(extensionA->id()); + // ExtensionA has changed, so refetch it. + ASSERT_EQ(size_before + 2, service->extensions()->size()); + extensionA = service->extensions()->GetByID(idA); + + LOG(INFO) << "Reload extension A done: " + << (base::TimeTicks::Now() - start_time).InMilliseconds() + << " ms" << std::flush; + + ReloadExtension(extensionB->id()); + + LOG(INFO) << "Reload extension B done: " + << (base::TimeTicks::Now() - start_time).InMilliseconds() + << " ms" << std::flush; + + // This is where it would crash, before http://crbug.com/44415 was fixed. + ReloadExtension(extensionA->id()); + + LOG(INFO) << "Test completed : " + << (base::TimeTicks::Now() - start_time).InMilliseconds() + << " ms" << std::flush; +} + +// Tests that tooltips of a page action icon can be specified using UTF8. +// See http://crbug.com/25349. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TitleLocalizationPageAction) { + ASSERT_TRUE(test_server()->Start()); + + ExtensionService* service = browser()->profile()->GetExtensionService(); + const size_t size_before = service->extensions()->size(); + + FilePath extension_path(test_data_dir_.AppendASCII("browsertest") + .AppendASCII("title_localized_pa")); + const Extension* extension = LoadExtension(extension_path); + ASSERT_TRUE(extension); + + // Any navigation prompts the location bar to load the page action. + GURL url = test_server()->GetURL(kLocalization); + ui_test_utils::NavigateToURL(browser(), url); + ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); + + ASSERT_EQ(size_before + 1, service->extensions()->size()); + + EXPECT_STREQ(WideToUTF8(L"Hreggvi\u00F0ur: l10n page action").c_str(), + extension->description().c_str()); + EXPECT_STREQ(WideToUTF8(L"Hreggvi\u00F0ur is my name").c_str(), + extension->name().c_str()); + int tab_id = ExtensionTabUtil::GetTabId(browser()->GetActiveWebContents()); + EXPECT_STREQ(WideToUTF8(L"Hreggvi\u00F0ur").c_str(), + extension->page_action()->GetTitle(tab_id).c_str()); +} diff --git a/chrome/browser/extensions/plugin_apitest.cc b/chrome/browser/extensions/plugin_apitest.cc new file mode 100644 index 0000000..6269883 --- /dev/null +++ b/chrome/browser/extensions/plugin_apitest.cc @@ -0,0 +1,130 @@ +// Copyright (c) 2012 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 "chrome/browser/extensions/extension_browsertest.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/tab_contents/tab_contents.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/web_contents.h" +#include "net/base/net_util.h" + +#if defined(OS_WIN) && defined(NDEBUG) +#define MAYBE_PluginLoadUnload PluginLoadUnload +#elif defined(OS_WIN) && !defined(NDEBUG) +// http://crbug.com/123851 Debug builds are flaky. +#define MAYBE_PluginLoadUnload FLAKY_PluginLoadUnload +#elif defined(OS_LINUX) +// http://crbug.com/47598 +#define MAYBE_PluginLoadUnload DISABLED_PluginLoadUnload +#else +// TODO(mpcomplete): http://crbug.com/29900 need cross platform plugin support. +#define MAYBE_PluginLoadUnload DISABLED_PluginLoadUnload +#endif + +using content::NavigationController; +using content::WebContents; +using extensions::Extension; + +// Tests that a renderer's plugin list is properly updated when we load and +// unload an extension that contains a plugin. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MAYBE_PluginLoadUnload) { + browser()->profile()->GetPrefs()->SetBoolean(prefs::kPluginsAlwaysAuthorize, + true); + + FilePath extension_dir = + test_data_dir_.AppendASCII("uitest").AppendASCII("plugins"); + + ui_test_utils::NavigateToURL(browser(), + net::FilePathToFileURL(extension_dir.AppendASCII("test.html"))); + WebContents* tab = browser()->GetActiveWebContents(); + + // With no extensions, the plugin should not be loaded. + bool result = false; + ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( + tab->GetRenderViewHost(), L"", L"testPluginWorks()", &result)); + EXPECT_FALSE(result); + + ExtensionService* service = browser()->profile()->GetExtensionService(); + service->set_show_extensions_prompts(false); + const size_t size_before = service->extensions()->size(); + const Extension* extension = LoadExtension(extension_dir); + ASSERT_TRUE(extension); + EXPECT_EQ(size_before + 1, service->extensions()->size()); + // Now the plugin should be in the cache. + ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( + tab->GetRenderViewHost(), L"", L"testPluginWorks()", &result)); + EXPECT_TRUE(result); + + EXPECT_EQ(size_before + 1, service->extensions()->size()); + UnloadExtension(extension->id()); + EXPECT_EQ(size_before, service->extensions()->size()); + + // Now the plugin should be unloaded, and the page should be broken. + + ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( + tab->GetRenderViewHost(), L"", L"testPluginWorks()", &result)); + EXPECT_FALSE(result); + + // If we reload the extension and page, it should work again. + + ASSERT_TRUE(LoadExtension(extension_dir)); + EXPECT_EQ(size_before + 1, service->extensions()->size()); + { + ui_test_utils::WindowedNotificationObserver observer( + content::NOTIFICATION_LOAD_STOP, + content::Source<NavigationController>( + &browser()->GetActiveWebContents()->GetController())); + browser()->Reload(CURRENT_TAB); + observer.Wait(); + } + ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( + tab->GetRenderViewHost(), L"", L"testPluginWorks()", &result)); + EXPECT_TRUE(result); +} + +#if defined(OS_WIN) || defined(OS_LINUX) +#define MAYBE_PluginPrivate PluginPrivate +#else +// TODO(mpcomplete): http://crbug.com/29900 need cross platform plugin support. +#define MAYBE_PluginPrivate DISABLED_PluginPrivate +#endif + +// Tests that private extension plugins are only visible to the extension. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MAYBE_PluginPrivate) { + FilePath extension_dir = + test_data_dir_.AppendASCII("uitest").AppendASCII("plugins_private"); + + ExtensionService* service = browser()->profile()->GetExtensionService(); + service->set_show_extensions_prompts(false); + const size_t size_before = service->extensions()->size(); + const Extension* extension = LoadExtension(extension_dir); + ASSERT_TRUE(extension); + EXPECT_EQ(size_before + 1, service->extensions()->size()); + + // Load the test page through the extension URL, and the plugin should work. + ui_test_utils::NavigateToURL(browser(), + extension->GetResourceURL("test.html")); + WebContents* tab = browser()->GetActiveWebContents(); + bool result = false; + ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( + tab->GetRenderViewHost(), L"", L"testPluginWorks()", &result)); + // We don't allow extension plugins to run on ChromeOS. +#if defined(OS_CHROMEOS) + EXPECT_FALSE(result); +#else + EXPECT_TRUE(result); +#endif + + // Now load it through a file URL. The plugin should not load. + ui_test_utils::NavigateToURL(browser(), + net::FilePathToFileURL(extension_dir.AppendASCII("test.html"))); + ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( + tab->GetRenderViewHost(), L"", L"testPluginWorks()", &result)); + EXPECT_FALSE(result); +} diff --git a/chrome/browser/extensions/subscribe_page_action_browsertest.cc b/chrome/browser/extensions/subscribe_page_action_browsertest.cc new file mode 100644 index 0000000..454742d --- /dev/null +++ b/chrome/browser/extensions/subscribe_page_action_browsertest.cc @@ -0,0 +1,347 @@ +// Copyright (c) 2012 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 "chrome/browser/extensions/extension_browsertest.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/url_constants.h" +#include "chrome/test/base/ui_test_utils.h" +#include "content/public/browser/web_contents.h" + +using content::WebContents; +using extensions::Extension; + +namespace { + +const std::string kSubscribePage = "/subscribe.html"; +const std::string kFeedPageMultiRel = "files/feeds/feed_multi_rel.html"; +const std::string kValidFeedNoLinks = "files/feeds/feed_nolinks.xml"; +const std::string kValidFeed0 = "files/feeds/feed_script.xml"; +const std::string kValidFeed1 = "files/feeds/feed1.xml"; +const std::string kValidFeed2 = "files/feeds/feed2.xml"; +const std::string kValidFeed3 = "files/feeds/feed3.xml"; +const std::string kValidFeed4 = "files/feeds/feed4.xml"; +const std::string kValidFeed5 = "files/feeds/feed5.xml"; +const std::string kValidFeed6 = "files/feeds/feed6.xml"; +const std::string kInvalidFeed1 = "files/feeds/feed_invalid1.xml"; +const std::string kInvalidFeed2 = "files/feeds/feed_invalid2.xml"; +// We need a triple encoded string to prove that we are not decoding twice in +// subscribe.js because one layer is also stripped off when subscribe.js passes +// it to the XMLHttpRequest object. +const std::string kFeedTripleEncoded = "files/feeds/url%25255Fdecoding.html"; + +static const wchar_t* jscript_feed_title = + L"window.domAutomationController.send(" + L" document.getElementById('title') ? " + L" document.getElementById('title').textContent : " + L" \"element 'title' not found\"" + L");"; +static const wchar_t* jscript_anchor = + L"window.domAutomationController.send(" + L" document.getElementById('anchor_0') ? " + L" document.getElementById('anchor_0').textContent : " + L" \"element 'anchor_0' not found\"" + L");"; +static const wchar_t* jscript_desc = + L"window.domAutomationController.send(" + L" document.getElementById('desc_0') ? " + L" document.getElementById('desc_0').textContent : " + L" \"element 'desc_0' not found\"" + L");"; +static const wchar_t* jscript_error = + L"window.domAutomationController.send(" + L" document.getElementById('error') ? " + L" document.getElementById('error').textContent : " + L" \"No error\"" + L");"; + +GURL GetFeedUrl(net::TestServer* server, const std::string& feed_page, + bool direct_url, std::string extension_id) { + GURL feed_url = server->GetURL(feed_page); + if (direct_url) { + // We navigate directly to the subscribe page for feeds where the feed + // sniffing won't work, in other words, as is the case for malformed feeds. + return GURL(std::string(chrome::kExtensionScheme) + + content::kStandardSchemeSeparator + + extension_id + std::string(kSubscribePage) + std::string("?") + + feed_url.spec() + std::string("&synchronous")); + } else { + // Navigate to the feed content (which will cause the extension to try to + // sniff the type and display the subscribe page in another tab. + return GURL(feed_url.spec()); + } +} + +bool ValidatePageElement(WebContents* tab, + const std::wstring& frame, + const std::wstring& javascript, + const std::string& expected_value) { + std::string returned_value; + std::string error; + + if (!ui_test_utils::ExecuteJavaScriptAndExtractString( + tab->GetRenderViewHost(), + frame, + javascript, &returned_value)) + return false; + + EXPECT_STREQ(expected_value.c_str(), returned_value.c_str()); + return expected_value == returned_value; +} + +// Navigates to a feed page and, if |sniff_xml_type| is set, wait for the +// extension to kick in, detect the feed and redirect to a feed preview page. +// |sniff_xml_type| is generally set to true if the feed is sniffable and false +// for invalid feeds. +void NavigateToFeedAndValidate(net::TestServer* server, + const std::string& url, + Browser* browser, + std::string extension_id, + bool sniff_xml_type, + const std::string& expected_feed_title, + const std::string& expected_item_title, + const std::string& expected_item_desc, + const std::string& expected_error) { + if (sniff_xml_type) { + // TODO(finnur): Implement this is a non-flaky way. + } + + // Navigate to the subscribe page directly. + ui_test_utils::NavigateToURL(browser, + GetFeedUrl(server, url, true, extension_id)); + + WebContents* tab = browser->GetActiveWebContents(); + ASSERT_TRUE(ValidatePageElement(tab, + L"", + jscript_feed_title, + expected_feed_title)); + ASSERT_TRUE(ValidatePageElement(tab, + L"//html/body/div/iframe[1]", + jscript_anchor, + expected_item_title)); + ASSERT_TRUE(ValidatePageElement(tab, + L"//html/body/div/iframe[1]", + jscript_desc, + expected_item_desc)); + ASSERT_TRUE(ValidatePageElement(tab, + L"//html/body/div/iframe[1]", + jscript_error, + expected_error)); +} + +} // namespace + +// Makes sure that the RSS detects RSS feed links, even when rel tag contains +// more than just "alternate". +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSMultiRelLink) { + ASSERT_TRUE(test_server()->Start()); + + ASSERT_TRUE(LoadExtension( + test_data_dir_.AppendASCII("subscribe_page_action"))); + + ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0)); + + // Navigate to the feed page. + GURL feed_url = test_server()->GetURL(kFeedPageMultiRel); + ui_test_utils::NavigateToURL(browser(), feed_url); + // We should now have one page action ready to go in the LocationBar. + ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1)); +} + +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed1) { + ASSERT_TRUE(test_server()->Start()); + + const Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("subscribe_page_action")); + ASSERT_TRUE(extension); + std::string id = extension->id(); + + NavigateToFeedAndValidate(test_server(), kValidFeed1, browser(), id, true, + "Feed for MyFeedTitle", + "Title 1", + "Desc", + "No error"); +} + +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed2) { + ASSERT_TRUE(test_server()->Start()); + + const Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("subscribe_page_action")); + ASSERT_TRUE(extension); + std::string id = extension->id(); + + NavigateToFeedAndValidate(test_server(), kValidFeed2, browser(), id, true, + "Feed for MyFeed2", + "My item title1", + "This is a summary.", + "No error"); +} + +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed3) { + ASSERT_TRUE(test_server()->Start()); + + const Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("subscribe_page_action")); + ASSERT_TRUE(extension); + std::string id = extension->id(); + + NavigateToFeedAndValidate(test_server(), kValidFeed3, browser(), id, true, + "Feed for Google Code buglist rss feed", + "My dear title", + "My dear content", + "No error"); +} + +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed4) { + ASSERT_TRUE(test_server()->Start()); + + const Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("subscribe_page_action")); + ASSERT_TRUE(extension); + std::string id = extension->id(); + + NavigateToFeedAndValidate(test_server(), kValidFeed4, browser(), id, true, + "Feed for Title chars <script> %23 stop", + "Title chars %23 stop", + "My dear content %23 stop", + "No error"); +} + +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed0) { + ASSERT_TRUE(test_server()->Start()); + + const Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("subscribe_page_action")); + ASSERT_TRUE(extension); + std::string id = extension->id(); + + // Try a feed with a link with an onclick handler (before r27440 this would + // trigger a NOTREACHED). + NavigateToFeedAndValidate(test_server(), kValidFeed0, browser(), id, true, + "Feed for MyFeedTitle", + "Title 1", + "Desc VIDEO", + "No error"); +} + +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed5) { + ASSERT_TRUE(test_server()->Start()); + + const Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("subscribe_page_action")); + ASSERT_TRUE(extension); + std::string id = extension->id(); + + // Feed with valid but mostly empty xml. + NavigateToFeedAndValidate(test_server(), kValidFeed5, browser(), id, true, + "Feed for Unknown feed name", + "element 'anchor_0' not found", + "element 'desc_0' not found", + "This feed contains no entries."); +} + +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed6) { + ASSERT_TRUE(test_server()->Start()); + + const Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("subscribe_page_action")); + ASSERT_TRUE(extension); + std::string id = extension->id(); + + // Feed that is technically invalid but still parseable. + NavigateToFeedAndValidate(test_server(), kValidFeed6, browser(), id, true, + "Feed for MyFeedTitle", + "Title 1", + "Desc", + "No error"); +} + +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedInvalidFeed1) { + ASSERT_TRUE(test_server()->Start()); + + const Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("subscribe_page_action")); + ASSERT_TRUE(extension); + std::string id = extension->id(); + + // Try an empty feed. + NavigateToFeedAndValidate(test_server(), kInvalidFeed1, browser(), id, false, + "Feed for Unknown feed name", + "element 'anchor_0' not found", + "element 'desc_0' not found", + "This feed contains no entries."); +} + +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedInvalidFeed2) { + ASSERT_TRUE(test_server()->Start()); + + const Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("subscribe_page_action")); + ASSERT_TRUE(extension); + std::string id = extension->id(); + + // Try a garbage feed. + NavigateToFeedAndValidate(test_server(), kInvalidFeed2, browser(), id, false, + "Feed for Unknown feed name", + "element 'anchor_0' not found", + "element 'desc_0' not found", + "This feed contains no entries."); +} + +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedInvalidFeed3) { + ASSERT_TRUE(test_server()->Start()); + + const Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("subscribe_page_action")); + ASSERT_TRUE(extension); + std::string id = extension->id(); + + // Try a feed that doesn't exist. + NavigateToFeedAndValidate(test_server(), "foo.xml", browser(), id, false, + "Feed for Unknown feed name", + "element 'anchor_0' not found", + "element 'desc_0' not found", + "This feed contains no entries."); +} + +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedInvalidFeed4) { + ASSERT_TRUE(test_server()->Start()); + + const Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("subscribe_page_action")); + ASSERT_TRUE(extension); + std::string id = extension->id(); + + // subscribe.js shouldn't double-decode the URL passed in. Otherwise feed + // links such as http://search.twitter.com/search.atom?lang=en&q=%23chrome + // will result in no feed being downloaded because %23 gets decoded to # and + // therefore #chrome is not treated as part of the Twitter query. This test + // uses an underscore instead of a hash, but the principle is the same. If + // we start erroneously double decoding again, the path (and the feed) will + // become valid resulting in a failure for this test. + NavigateToFeedAndValidate( + test_server(), kFeedTripleEncoded, browser(), id, true, + "Feed for Unknown feed name", + "element 'anchor_0' not found", + "element 'desc_0' not found", + "This feed contains no entries."); +} + +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeedNoLinks) { + ASSERT_TRUE(test_server()->Start()); + + const Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("subscribe_page_action")); + ASSERT_TRUE(extension); + std::string id = extension->id(); + + // Valid feed but containing no links. + NavigateToFeedAndValidate( + test_server(), kValidFeedNoLinks, browser(), id, true, + "Feed for MyFeedTitle", + "Title with no link", + "Desc", + "No error"); +} diff --git a/chrome/browser/extensions/web_contents_browsertest.cc b/chrome/browser/extensions/web_contents_browsertest.cc new file mode 100644 index 0000000..031c1f7 --- /dev/null +++ b/chrome/browser/extensions/web_contents_browsertest.cc @@ -0,0 +1,38 @@ +// Copyright (c) 2012 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 "chrome/browser/extensions/extension_browsertest.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/ui_test_utils.h" + +// Tests that we can load extension pages into the tab area and they can call +// extension APIs. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WebContents) { + ASSERT_TRUE(LoadExtension( + test_data_dir_.AppendASCII("good").AppendASCII("Extensions") + .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") + .AppendASCII("1.0.0.0"))); + + ui_test_utils::NavigateToURL( + browser(), + GURL("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/page.html")); + + bool result = false; + ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( + browser()->GetActiveWebContents()->GetRenderViewHost(), L"", + L"testTabsAPI()", &result)); + EXPECT_TRUE(result); + + // There was a bug where we would crash if we navigated to a page in the same + // extension because no new render view was getting created, so we would not + // do some setup. + ui_test_utils::NavigateToURL( + browser(), + GURL("chrome-extension://behllobkkfkfnphdnhnkndlbkcpglgmj/page.html")); + result = false; + ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( + browser()->GetActiveWebContents()->GetRenderViewHost(), L"", + L"testTabsAPI()", &result)); + EXPECT_TRUE(result); +} diff --git a/chrome/browser/extensions/window_open_apitest.cc b/chrome/browser/extensions/window_open_apitest.cc index 1d2c3fd..749b853 100644 --- a/chrome/browser/extensions/window_open_apitest.cc +++ b/chrome/browser/extensions/window_open_apitest.cc @@ -13,11 +13,13 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/test/base/ui_test_utils.h" +#include "content/public/browser/web_contents.h" #include "testing/gtest/include/gtest/gtest.h" #include "net/base/mock_host_resolver.h" using content::OpenURLParams; using content::Referrer; +using content::WebContents; // Disabled, http://crbug.com/64899. IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_WindowOpen) { @@ -250,3 +252,59 @@ IN_PROC_BROWSER_TEST_F(WindowOpenPanelTest, IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_WindowOpener) { ASSERT_TRUE(RunExtensionTest("window_open/opener")) << message_; } + +// Tests that an extension page can call window.open to an extension URL and +// the new window has extension privileges. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenExtension) { + ASSERT_TRUE(LoadExtension( + test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"))); + + GURL start_url(std::string("chrome-extension://") + + last_loaded_extension_id_ + "/test.html"); + ui_test_utils::NavigateToURL(browser(), start_url); + WebContents* newtab; + ASSERT_NO_FATAL_FAILURE(OpenWindow(browser()->GetActiveWebContents(), + start_url.Resolve("newtab.html"), true, &newtab)); + + bool result = false; + ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( + newtab->GetRenderViewHost(), L"", L"testExtensionApi()", &result)); + EXPECT_TRUE(result); +} + +// Tests that if an extension page calls window.open to an invalid extension +// URL, the browser doesn't crash. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenInvalidExtension) { + ASSERT_TRUE(LoadExtension( + test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"))); + + GURL start_url(std::string("chrome-extension://") + + last_loaded_extension_id_ + "/test.html"); + ui_test_utils::NavigateToURL(browser(), start_url); + ASSERT_NO_FATAL_FAILURE(OpenWindow(browser()->GetActiveWebContents(), + GURL("chrome-extension://thisissurelynotavalidextensionid/newtab.html"), + false, NULL)); + + // If we got to this point, we didn't crash, so we're good. +} + +// Tests that calling window.open from the newtab page to an extension URL +// gives the new window extension privileges - even though the opening page +// does not have extension privileges, we break the script connection, so +// there is no privilege leak. +IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenNoPrivileges) { + ASSERT_TRUE(LoadExtension( + test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"))); + + ui_test_utils::NavigateToURL(browser(), GURL("about:blank")); + WebContents* newtab; + ASSERT_NO_FATAL_FAILURE(OpenWindow(browser()->GetActiveWebContents(), + GURL(std::string("chrome-extension://") + last_loaded_extension_id_ + + "/newtab.html"), false, &newtab)); + + // Extension API should succeed. + bool result = false; + ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool( + newtab->GetRenderViewHost(), L"", L"testExtensionApi()", &result)); + EXPECT_TRUE(result); +} |