summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-24 12:35:32 +0000
committerbulach@chromium.org <bulach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-24 12:35:32 +0000
commitda239eb0c5791d01f008be258d1e34fc42825b1e (patch)
tree672ace86008177b80a1cc8afa1b46ba5d10d9292
parent2c752481fa190588a852ff96a0ffe9428f0dc51d (diff)
downloadchromium_src-da239eb0c5791d01f008be258d1e34fc42825b1e.zip
chromium_src-da239eb0c5791d01f008be258d1e34fc42825b1e.tar.gz
chromium_src-da239eb0c5791d01f008be258d1e34fc42825b1e.tar.bz2
Adds Geolocation browser test.
Note: they're disabled on Mac pending my investigation (it seems to be a similar issue to http://code.google.com/p/chromium/issues/detail?id=29424). This will at least get some coverage for geolocation on win and linux for the time being. TEST=geolocation_browsertest.cc Review URL: http://codereview.chromium.org/650134 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39885 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/geolocation/geolocation_browsertest.cc325
-rw-r--r--chrome/browser/geolocation/geolocation_dispatcher_host.cc6
-rw-r--r--chrome/browser/geolocation/geolocation_dispatcher_host.h2
-rw-r--r--chrome/browser/geolocation/geolocation_permission_context.cc22
-rwxr-xr-xchrome/chrome_tests.gypi1
5 files changed, 338 insertions, 18 deletions
diff --git a/chrome/browser/geolocation/geolocation_browsertest.cc b/chrome/browser/geolocation/geolocation_browsertest.cc
new file mode 100644
index 0000000..03eccb2
--- /dev/null
+++ b/chrome/browser/geolocation/geolocation_browsertest.cc
@@ -0,0 +1,325 @@
+// Copyright (c) 2009 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/string_util.h"
+#include "chrome/browser/app_modal_dialog.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/geoposition.h"
+#include "chrome/common/notification_details.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/notification_type.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/test/in_process_browser_test.h"
+#include "chrome/test/ui_test_utils.h"
+#include "net/base/net_util.h"
+
+class InfobarNotificationObserver : public NotificationObserver {
+ public:
+ InfobarNotificationObserver() : infobar_(NULL) {
+ }
+
+ void Add(NotificationType notification_type) {
+ registrar_.Add(this, notification_type, NotificationService::AllSources());
+ }
+
+ // NotificationObserver
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type.value == NotificationType::TAB_CONTENTS_INFOBAR_ADDED) {
+ infobar_ = Details<InfoBarDelegate>(details).ptr();
+ ASSERT_TRUE(infobar_->GetIcon());
+ ASSERT_TRUE(infobar_->AsConfirmInfoBarDelegate());
+ MessageLoopForUI::current()->Quit();
+ } else if (type.value == NotificationType::TAB_CONTENTS_INFOBAR_REMOVED) {
+ infobar_ = NULL;
+ }
+ }
+
+ NotificationRegistrar registrar_;
+ InfoBarDelegate* infobar_;
+};
+
+// This is a browser test for Geolocation.
+// It exercises various integration points from javascript <-> browser:
+// 1. Infobar is displayed when a geolocation is requested from an unauthorized
+// origin.
+// 2. Denying the infobar triggers the correct error callback.
+// 3. Allowing the infobar does not trigger an error, and allow a geoposition to
+// be passed to javascript.
+// 4. Permissions persisted in disk are respected.
+// 5. Off the record profiles don't use saved permissions.
+class GeolocationBrowserTest : public InProcessBrowserTest {
+ public:
+ GeolocationBrowserTest() : infobar_(NULL), current_browser_(NULL) {
+ EnableDOMAutomation();
+ }
+
+ enum InitializationOptions {
+ INITIALIZATION_NONE,
+ INITIALIZATION_OFFTHERECORD,
+ INITIALIZATION_NEWTAB,
+ };
+
+ void Initialize(InitializationOptions options) {
+ if (!server_.get()) {
+ server_ = StartHTTPServer();
+ }
+ GURL url = server_->TestServerPage("files/geolocation/simple.html");
+ LOG(WARNING) << "before navigate";
+ if (options == INITIALIZATION_OFFTHERECORD) {
+ ui_test_utils::OpenURLOffTheRecord(browser()->profile(), url);
+ current_browser_ = BrowserList::FindBrowserWithType(
+ browser()->profile()->GetOffTheRecordProfile(), Browser::TYPE_NORMAL);
+ } else if (options == INITIALIZATION_NEWTAB) {
+ current_browser_ = browser();
+ current_browser_->NewTab();
+ ui_test_utils::NavigateToURL(current_browser_, url);
+ } else {
+ current_browser_ = browser();
+ ui_test_utils::NavigateToURL(current_browser_, url);
+ }
+ EXPECT_TRUE(current_browser_);
+ LOG(WARNING) << "after navigate";
+
+ int watch_id = 0;
+ EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractInt(
+ current_browser_->GetSelectedTabContents()->render_view_host(), L"",
+ UTF8ToWide("window.domAutomationController.send(geoStart());"),
+ &watch_id));
+ EXPECT_GT(watch_id, 0);
+ LOG(WARNING) << "got geolocation watch";
+ }
+
+ void SendGeoposition(bool wait_for_infobar, const Geoposition& geoposition) {
+ InfobarNotificationObserver infobar_notification_observer;
+ if (wait_for_infobar) {
+ // Observe infobar notification.
+ infobar_notification_observer.Add(
+ NotificationType::TAB_CONTENTS_INFOBAR_ADDED);
+ }
+
+ // Sending the Geoposition makes webkit trigger the permission request flow.
+ // If the origin is already allowed, no infobar will be displayed.
+ LOG(WARNING) << "will send geoposition";
+ RenderViewHost* render_view_host =
+ current_browser_->GetSelectedTabContents()->render_view_host();
+ render_view_host->Send(
+ new ViewMsg_Geolocation_PositionUpdated(
+ render_view_host->routing_id(), geoposition));
+ LOG(WARNING) << "geoposition sent";
+
+ if (wait_for_infobar) {
+ LOG(WARNING) << "will block for infobar";
+ ui_test_utils::RunMessageLoop();
+ LOG(WARNING) << "infobar created";
+ EXPECT_TRUE(infobar_notification_observer.infobar_);
+ infobar_ = infobar_notification_observer.infobar_;
+ } else {
+ WaitForJSPrompt();
+ }
+ }
+
+ void SetInfobarResponse(bool allowed) {
+ InfobarNotificationObserver infobar_notification_observer;
+ infobar_notification_observer.Add(
+ NotificationType::TAB_CONTENTS_INFOBAR_REMOVED);
+ ASSERT_TRUE(infobar_);
+ LOG(WARNING) << "will set infobar response";
+ if (allowed)
+ infobar_->AsConfirmInfoBarDelegate()->Accept();
+ else
+ infobar_->AsConfirmInfoBarDelegate()->Cancel();
+ LOG(WARNING) << "infobar response set";
+ EXPECT_FALSE(infobar_notification_observer.infobar_);
+ infobar_ = NULL;
+ WaitForJSPrompt();
+ }
+
+ void WaitForJSPrompt() {
+ LOG(WARNING) << "will block for JS prompt";
+ AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog();
+ LOG(WARNING) << "JS prompt received";
+ ASSERT_TRUE(alert);
+ LOG(WARNING) << "will close JS prompt";
+ alert->CloseModalDialog();
+ LOG(WARNING) << "closed JS prompt";
+ }
+
+ void CheckValueFromJavascript(
+ const std::string& expected, const std::string& function) {
+ std::string js_call = StringPrintf(
+ "window.domAutomationController.send(%s);", function.c_str());
+ std::string value;
+ LOG(WARNING) << "will check for JS value";
+ EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
+ current_browser_->GetSelectedTabContents()->render_view_host(), L"",
+ UTF8ToWide(js_call),
+ &value));
+ LOG(WARNING) << "JS value checked";
+ EXPECT_EQ(expected, value);
+ }
+
+ // InProcessBrowserTest
+ virtual void SetUpCommandLine(CommandLine* command_line) {
+ InProcessBrowserTest::SetUpCommandLine(command_line);
+ command_line->AppendSwitch(switches::kEnableGeolocation);
+ }
+
+ scoped_refptr<HTTPTestServer> server_;
+ InfoBarDelegate* infobar_;
+ Browser* current_browser_;
+};
+
+#if defined(OS_MACOSX)
+// TODO(bulach): investigate why this fails on mac. It may be related to:
+// http://crbug.com//29424
+#define MAYBE_DisplaysPermissionBar DISABLED_DisplaysPermissionBar
+#else
+#define MAYBE_DisplaysPermissionBar DisplaysPermissionBar
+#endif
+
+IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_DisplaysPermissionBar) {
+ Initialize(INITIALIZATION_NONE);
+ SendGeoposition(true, Geoposition());
+}
+
+#if defined(OS_MACOSX)
+// TODO(bulach): investigate why this fails on mac. It may be related to:
+// http://crbug.com//29424
+#define MAYBE_ErrorOnPermissionDenied DISABLED_ErrorOnPermissionDenied
+#else
+#define MAYBE_ErrorOnPermissionDenied ErrorOnPermissionDenied
+#endif
+
+IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_ErrorOnPermissionDenied) {
+ Initialize(INITIALIZATION_NONE);
+ SendGeoposition(true, Geoposition());
+ // Infobar was displayed, deny access and check for error code.
+ SetInfobarResponse(false);
+ CheckValueFromJavascript("1", "geoGetLastError()");
+}
+
+#if defined(OS_MACOSX)
+// TODO(bulach): investigate why this fails on mac. It may be related to:
+// http://crbug.com//29424
+#define MAYBE_NoInfobarForSecondTab DISABLED_NoInfobarForSecondTab
+#else
+#define MAYBE_NoInfobarForSecondTab NoInfobarForSecondTab
+#endif
+
+IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_NoInfobarForSecondTab) {
+#if 0
+ // TODO(bulach): enable this test once we use HostContentSettingsMap instead
+ // of files.
+ Initialize(INITIALIZATION_NONE);
+ SendGeoposition(true, Geoposition());
+ SetInfobarResponse(true);
+ // Checks infobar will not be created a second tab.
+ Initialize(INITIALIZATION_NEWTAB);
+ SendGeoposition(false, Geoposition());
+ CheckValueFromJavascript("0", "geoGetLastError()");
+#endif
+}
+
+#if defined(OS_MACOSX)
+// TODO(bulach): investigate why this fails on mac. It may be related to:
+// http://crbug.com//29424
+#define MAYBE_NoInfobarForDeniedOrigin DISABLED_NoInfobarForDeniedOrigin
+#else
+#define MAYBE_NoInfobarForDeniedOrigin NoInfobarForDeniedOrigin
+#endif
+
+IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_NoInfobarForDeniedOrigin) {
+#if 0
+ // TODO(bulach): enable this test once we use HostContentSettingsMap instead
+ // of files.
+ WritePermissionFile("{\"allowed\":false}");
+ // Checks no infobar will be created.
+ Initialize(INITIALIZATION_NONE);
+ SendGeoposition(false, Geoposition());
+ CheckValueFromJavascript("1", "geoGetLastError()");
+ // Checks infobar will not be created a second tab.
+ Initialize(INITIALIZATION_NEWTAB);
+ SendGeoposition(false, Geoposition());
+ CheckValueFromJavascript("1", "geoGetLastError()");
+#endif
+}
+
+#if defined(OS_MACOSX)
+// TODO(bulach): investigate why this fails on mac. It may be related to:
+// http://crbug.com//29424
+#define MAYBE_NoInfobarForAllowedOrigin DISABLED_NoInfobarForAllowedOrigin
+#else
+#define MAYBE_NoInfobarForAllowedOrigin NoInfobarForAllowedOrigin
+#endif
+
+IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,
+ MAYBE_NoInfobarForAllowedOrigin) {
+#if 0
+ // TODO(bulach): enable this test once we use HostContentSettingsMap instead
+ // of files.
+ WritePermissionFile("{\"allowed\":true}");
+ // Checks no infobar will be created and there's no error callback.
+ Initialize(INITIALIZATION_NONE);
+ SendGeoposition(false, Geoposition());
+ CheckValueFromJavascript("0", "geoGetLastError()");
+#endif
+}
+
+#if defined(OS_MACOSX)
+// TODO(bulach): investigate why this fails on mac. It may be related to:
+// http://crbug.com//29424
+#define MAYBE_InfobarForOffTheRecord DISABLED_InfobarForOffTheRecord
+#else
+#define MAYBE_InfobarForOffTheRecord InfobarForOffTheRecord
+#endif
+
+IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_InfobarForOffTheRecord) {
+ // Checks infobar will be created for regular profile.
+ Initialize(INITIALIZATION_NONE);
+ SendGeoposition(true, Geoposition());
+ SetInfobarResponse(true);
+ CheckValueFromJavascript("0", "geoGetLastError()");
+ // Go off the record, and checks infobar will be created and an error callback
+ // is triggered.
+ Initialize(INITIALIZATION_OFFTHERECORD);
+ SendGeoposition(true, Geoposition());
+ SetInfobarResponse(false);
+ CheckValueFromJavascript("1", "geoGetLastError()");
+}
+
+#if defined(OS_MACOSX)
+// TODO(bulach): investigate why this fails on mac. It may be related to:
+// http://crbug.com//29424
+#define MAYBE_Geoposition DISABLED_Geoposition
+#else
+#define MAYBE_Geoposition Geoposition
+#endif
+
+IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_Geoposition) {
+ // Checks infobar will be created.
+ Initialize(INITIALIZATION_NONE);
+ SendGeoposition(true, Geoposition());
+ // Infobar was displayed, allow access and check there's no error code.
+ SetInfobarResponse(true);
+ CheckValueFromJavascript("0", "geoGetLastError()");
+ // Sends a Geoposition over IPC, and check it arrives in the javascript side.
+ Geoposition geoposition;
+ geoposition.latitude = 3.17;
+ geoposition.longitude = 4.23;
+ SendGeoposition(false, geoposition);
+ // Checks we have no error.
+ CheckValueFromJavascript("0", "geoGetLastError()");
+ CheckValueFromJavascript(
+ DoubleToString(geoposition.latitude), "geoGetLastPositionLatitude()");
+ CheckValueFromJavascript(
+ DoubleToString(geoposition.longitude), "geoGetLastPositionLongitude()");
+}
diff --git a/chrome/browser/geolocation/geolocation_dispatcher_host.cc b/chrome/browser/geolocation/geolocation_dispatcher_host.cc
index 1217224..2ea0a48 100644
--- a/chrome/browser/geolocation/geolocation_dispatcher_host.cc
+++ b/chrome/browser/geolocation/geolocation_dispatcher_host.cc
@@ -51,7 +51,7 @@ bool GeolocationDispatcherHost::OnMessageReceived(
void GeolocationDispatcherHost::NotifyPositionUpdated(
const Geoposition& geoposition) {
- if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) {
+ if (!ChromeThread::CurrentlyOn(ChromeThread::IO)) {
ChromeThread::PostTask(
ChromeThread::UI, FROM_HERE,
NewRunnableMethod(
@@ -59,14 +59,14 @@ void GeolocationDispatcherHost::NotifyPositionUpdated(
geoposition));
return;
}
- DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
for (std::set<GeolocationServiceRenderId>::iterator geo =
geolocation_renderers_.begin();
geo != geolocation_renderers_.end();
++geo) {
IPC::Message* message;
- if (geoposition.error_code != Geoposition::ERROR_CODE_NONE) {
+ if (geoposition.error_code == Geoposition::ERROR_CODE_NONE) {
message = new ViewMsg_Geolocation_PositionUpdated(
geo->route_id, geoposition);
} else {
diff --git a/chrome/browser/geolocation/geolocation_dispatcher_host.h b/chrome/browser/geolocation/geolocation_dispatcher_host.h
index 8bd7eaf..c054bbb 100644
--- a/chrome/browser/geolocation/geolocation_dispatcher_host.h
+++ b/chrome/browser/geolocation/geolocation_dispatcher_host.h
@@ -68,7 +68,7 @@ class GeolocationDispatcherHost
route_id < rhs.route_id;
}
};
- // Only used on the UI thread.
+ // Only used on the IO thread.
std::set<GeolocationServiceRenderId> geolocation_renderers_;
DISALLOW_COPY_AND_ASSIGN(GeolocationDispatcherHost);
diff --git a/chrome/browser/geolocation/geolocation_permission_context.cc b/chrome/browser/geolocation/geolocation_permission_context.cc
index 853e0a7..79e1e30 100644
--- a/chrome/browser/geolocation/geolocation_permission_context.cc
+++ b/chrome/browser/geolocation/geolocation_permission_context.cc
@@ -18,6 +18,7 @@
#include "chrome/browser/renderer_host/render_view_host_notification_task.h"
#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome/common/render_messages.h"
#include "grit/generated_resources.h"
@@ -217,20 +218,13 @@ void GeolocationPermissionContext::RequestPermissionFromUI(
}
DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
- Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
- for (int i = 0; i < browser->tab_count(); ++i) {
- TabContents* tab_contents = browser->GetTabContentsAt(i);
- RenderViewHost* render_view_host = tab_contents->render_view_host();
- if (render_view_host->process()->id() == render_process_id &&
- render_view_host->routing_id() == render_view_id &&
- tab_contents->GetURL().GetOrigin() == origin) {
- tab_contents->AddInfoBar(
- new GeolocationConfirmInfoBarDelegate(
- tab_contents, this, render_process_id, render_view_id,
- bridge_id, origin));
- break;
- }
- }
+ TabContents* tab_contents =
+ tab_util::GetTabContentsByID(render_process_id, render_view_id);
+ DCHECK(tab_contents);
+ tab_contents->AddInfoBar(
+ new GeolocationConfirmInfoBarDelegate(
+ tab_contents, this, render_process_id, render_view_id,
+ bridge_id, origin));
}
void GeolocationPermissionContext::NotifyPermissionSet(
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 3ec7ce8..756bd9c 100755
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1171,6 +1171,7 @@
'browser/extensions/permissions_apitest.cc',
'browser/extensions/stubs_apitest.cc',
'browser/geolocation/access_token_store_browsertest.cc',
+ 'browser/geolocation/geolocation_browsertest.cc',
'browser/gtk/bookmark_manager_browsertest.cc',
'browser/net/cookie_policy_browsertest.cc',
'browser/net/ftp_browsertest.cc',