1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/compiler_specific.h"
6 #include "base/string_number_conversions.h"
7 #include "base/string_util.h"
8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/dom_operation_notification_details.h"
10 #include "chrome/browser/geolocation/geolocation_content_settings_map.h"
11 #include "chrome/browser/geolocation/geolocation_settings_state.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_list.h"
16 #include "chrome/common/chrome_paths.h"
17 #include "chrome/test/in_process_browser_test.h"
18 #include "chrome/test/ui_test_utils.h"
19 #include "content/browser/geolocation/arbitrator_dependency_factories_for_test.h"
20 #include "content/browser/geolocation/location_arbitrator.h"
21 #include "content/browser/geolocation/mock_location_provider.h"
22 #include "content/browser/renderer_host/render_view_host.h"
23 #include "content/browser/tab_contents/tab_contents.h"
24 #include "content/common/geoposition.h"
25 #include "content/common/notification_details.h"
26 #include "content/common/notification_service.h"
27 #include "content/common/notification_type.h"
28 #include "net/base/net_util.h"
29 #include "net/test/test_server.h"
30
31 namespace {
32
33 // Used to block until an iframe is loaded via a javascript call.
34 // Note: NavigateToURLBlockUntilNavigationsComplete doesn't seem to work for
35 // multiple embedded iframes, as notifications seem to be 'batched'. Instead, we
36 // load and wait one single frame here by calling a javascript function.
37 class IFrameLoader : public NotificationObserver {
38 public:
IFrameLoader(Browser * browser,int iframe_id,const GURL & url)39 IFrameLoader(Browser* browser, int iframe_id, const GURL& url)
40 : navigation_completed_(false),
41 javascript_completed_(false) {
42 NavigationController* controller =
43 &browser->GetSelectedTabContents()->controller();
44 registrar_.Add(this, NotificationType::LOAD_STOP,
45 Source<NavigationController>(controller));
46 registrar_.Add(this, NotificationType::DOM_OPERATION_RESPONSE,
47 NotificationService::AllSources());
48 std::string script = StringPrintf(
49 "window.domAutomationController.setAutomationId(0);"
50 "window.domAutomationController.send(addIFrame(%d, \"%s\"));",
51 iframe_id,
52 url.spec().c_str());
53 browser->GetSelectedTabContents()->render_view_host()->
54 ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(script));
55 ui_test_utils::RunMessageLoop();
56
57 EXPECT_EQ(StringPrintf("\"%d\"", iframe_id), javascript_response_);
58 registrar_.RemoveAll();
59 // Now that we loaded the iframe, let's fetch its src.
60 script = StringPrintf(
61 "window.domAutomationController.send(getIFrameSrc(%d))", iframe_id);
62 std::string iframe_src;
63 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
64 browser->GetSelectedTabContents()->render_view_host(),
65 L"", UTF8ToWide(script), &iframe_src));
66 iframe_url_ = GURL(iframe_src);
67 }
68
iframe_url() const69 GURL iframe_url() const { return iframe_url_; }
70
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)71 virtual void Observe(NotificationType type,
72 const NotificationSource& source,
73 const NotificationDetails& details) {
74 if (type == NotificationType::LOAD_STOP) {
75 navigation_completed_ = true;
76 } else if (type == NotificationType::DOM_OPERATION_RESPONSE) {
77 Details<DomOperationNotificationDetails> dom_op_details(details);
78 javascript_response_ = dom_op_details->json();
79 javascript_completed_ = true;
80 }
81 if (javascript_completed_ && navigation_completed_)
82 MessageLoopForUI::current()->Quit();
83 }
84
85 private:
86 NotificationRegistrar registrar_;
87
88 // If true the navigation has completed.
89 bool navigation_completed_;
90
91 // If true the javascript call has completed.
92 bool javascript_completed_;
93
94 std::string javascript_response_;
95
96 // The URL for the iframe we just loaded.
97 GURL iframe_url_;
98
99 DISALLOW_COPY_AND_ASSIGN(IFrameLoader);
100 };
101
102 class GeolocationNotificationObserver : public NotificationObserver {
103 public:
104 // If |wait_for_infobar| is true, AddWatchAndWaitForNotification will block
105 // until the infobar has been displayed; otherwise it will block until the
106 // navigation is completed.
GeolocationNotificationObserver(bool wait_for_infobar)107 explicit GeolocationNotificationObserver(bool wait_for_infobar)
108 : wait_for_infobar_(wait_for_infobar),
109 infobar_(NULL),
110 navigation_started_(false),
111 navigation_completed_(false) {
112 registrar_.Add(this, NotificationType::DOM_OPERATION_RESPONSE,
113 NotificationService::AllSources());
114 if (wait_for_infobar) {
115 registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_ADDED,
116 NotificationService::AllSources());
117 } else {
118 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
119 NotificationService::AllSources());
120 registrar_.Add(this, NotificationType::LOAD_START,
121 NotificationService::AllSources());
122 registrar_.Add(this, NotificationType::LOAD_STOP,
123 NotificationService::AllSources());
124 }
125 }
126
AddWatchAndWaitForNotification(RenderViewHost * render_view_host,const std::wstring & iframe_xpath)127 void AddWatchAndWaitForNotification(RenderViewHost* render_view_host,
128 const std::wstring& iframe_xpath) {
129 LOG(WARNING) << "will add geolocation watch";
130 std::string script =
131 "window.domAutomationController.setAutomationId(0);"
132 "window.domAutomationController.send(geoStart());";
133 render_view_host->ExecuteJavascriptInWebFrame(WideToUTF16Hack(iframe_xpath),
134 UTF8ToUTF16(script));
135 ui_test_utils::RunMessageLoop();
136 registrar_.RemoveAll();
137 LOG(WARNING) << "got geolocation watch" << javascript_response_;
138 EXPECT_NE("\"0\"", javascript_response_);
139 if (wait_for_infobar_) {
140 EXPECT_TRUE(infobar_);
141 } else {
142 EXPECT_TRUE(navigation_completed_);
143 }
144 }
145
146 // NotificationObserver
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)147 virtual void Observe(NotificationType type,
148 const NotificationSource& source,
149 const NotificationDetails& details) {
150 if (type.value == NotificationType::TAB_CONTENTS_INFOBAR_ADDED) {
151 infobar_ = Details<InfoBarDelegate>(details).ptr();
152 ASSERT_TRUE(infobar_->GetIcon());
153 ASSERT_TRUE(infobar_->AsConfirmInfoBarDelegate());
154 } else if (type == NotificationType::DOM_OPERATION_RESPONSE) {
155 Details<DomOperationNotificationDetails> dom_op_details(details);
156 javascript_response_ = dom_op_details->json();
157 LOG(WARNING) << "javascript_response " << javascript_response_;
158 } else if (type == NotificationType::NAV_ENTRY_COMMITTED ||
159 type == NotificationType::LOAD_START) {
160 navigation_started_ = true;
161 } else if (type == NotificationType::LOAD_STOP) {
162 if (navigation_started_) {
163 navigation_started_ = false;
164 navigation_completed_ = true;
165 }
166 }
167
168 // We're either waiting for just the inforbar, or for both a javascript
169 // prompt and response.
170 if (wait_for_infobar_ && infobar_)
171 MessageLoopForUI::current()->Quit();
172 else if (navigation_completed_ && !javascript_response_.empty())
173 MessageLoopForUI::current()->Quit();
174 }
175
176 NotificationRegistrar registrar_;
177 bool wait_for_infobar_;
178 InfoBarDelegate* infobar_;
179 bool navigation_started_;
180 bool navigation_completed_;
181 std::string javascript_response_;
182 };
183
NotifyGeoposition(const Geoposition & geoposition)184 void NotifyGeoposition(const Geoposition& geoposition) {
185 DCHECK(MockLocationProvider::instance_);
186 MockLocationProvider::instance_->HandlePositionChanged(geoposition);
187 LOG(WARNING) << "MockLocationProvider listeners updated";
188 }
189
190 // This is a browser test for Geolocation.
191 // It exercises various integration points from javascript <-> browser:
192 // 1. Infobar is displayed when a geolocation is requested from an unauthorized
193 // origin.
194 // 2. Denying the infobar triggers the correct error callback.
195 // 3. Allowing the infobar does not trigger an error, and allow a geoposition to
196 // be passed to javascript.
197 // 4. Permissions persisted in disk are respected.
198 // 5. Incognito profiles don't use saved permissions.
199 class GeolocationBrowserTest : public InProcessBrowserTest {
200 public:
GeolocationBrowserTest()201 GeolocationBrowserTest()
202 : infobar_(NULL),
203 current_browser_(NULL),
204 html_for_tests_("files/geolocation/simple.html"),
205 started_test_server_(false),
206 dependency_factory_(
207 new GeolocationArbitratorDependencyFactoryWithLocationProvider(
208 &NewAutoSuccessMockNetworkLocationProvider)) {
209 EnableDOMAutomation();
210 }
211
212 // InProcessBrowserTest
SetUpInProcessBrowserTestFixture()213 virtual void SetUpInProcessBrowserTestFixture() {
214 GeolocationArbitrator::SetDependencyFactoryForTest(
215 dependency_factory_.get());
216 }
217
218 // InProcessBrowserTest
TearDownInProcessBrowserTestFixture()219 virtual void TearDownInProcessBrowserTestFixture() {
220 LOG(WARNING) << "TearDownInProcessBrowserTestFixture. Test Finished.";
221 GeolocationArbitrator::SetDependencyFactoryForTest(NULL);
222 }
223
224 enum InitializationOptions {
225 INITIALIZATION_NONE,
226 INITIALIZATION_OFFTHERECORD,
227 INITIALIZATION_NEWTAB,
228 INITIALIZATION_IFRAMES,
229 };
230
Initialize(InitializationOptions options)231 bool Initialize(InitializationOptions options) WARN_UNUSED_RESULT {
232 if (!started_test_server_)
233 started_test_server_ = test_server()->Start();
234 EXPECT_TRUE(started_test_server_);
235 if (!started_test_server_)
236 return false;
237
238 current_url_ = test_server()->GetURL(html_for_tests_);
239 LOG(WARNING) << "before navigate";
240 if (options == INITIALIZATION_OFFTHERECORD) {
241 ui_test_utils::OpenURLOffTheRecord(browser()->profile(), current_url_);
242 current_browser_ = BrowserList::FindBrowserWithType(
243 browser()->profile()->GetOffTheRecordProfile(), Browser::TYPE_NORMAL,
244 false);
245 } else if (options == INITIALIZATION_NEWTAB) {
246 current_browser_ = browser();
247 current_browser_->NewTab();
248 ui_test_utils::NavigateToURL(current_browser_, current_url_);
249 } else if (options == INITIALIZATION_IFRAMES) {
250 current_browser_ = browser();
251 ui_test_utils::NavigateToURL(current_browser_, current_url_);
252 } else {
253 current_browser_ = browser();
254 ui_test_utils::NavigateToURL(current_browser_, current_url_);
255 }
256 LOG(WARNING) << "after navigate";
257
258 EXPECT_TRUE(current_browser_);
259 if (!current_browser_)
260 return false;
261
262 return true;
263 }
264
LoadIFrames(int number_iframes)265 void LoadIFrames(int number_iframes) {
266 // Limit to 3 iframes.
267 DCHECK(0 < number_iframes && number_iframes <= 3);
268 iframe_urls_.resize(number_iframes);
269 for (int i = 0; i < number_iframes; ++i) {
270 IFrameLoader loader(current_browser_, i, GURL());
271 iframe_urls_[i] = loader.iframe_url();
272 }
273 }
274
AddGeolocationWatch(bool wait_for_infobar)275 void AddGeolocationWatch(bool wait_for_infobar) {
276 GeolocationNotificationObserver notification_observer(wait_for_infobar);
277 notification_observer.AddWatchAndWaitForNotification(
278 current_browser_->GetSelectedTabContents()->render_view_host(),
279 iframe_xpath_);
280 if (wait_for_infobar) {
281 EXPECT_TRUE(notification_observer.infobar_);
282 infobar_ = notification_observer.infobar_;
283 }
284 }
285
GeopositionFromLatLong(double latitude,double longitude)286 Geoposition GeopositionFromLatLong(double latitude, double longitude) {
287 Geoposition geoposition;
288 geoposition.latitude = latitude;
289 geoposition.longitude = longitude;
290 geoposition.accuracy = 0;
291 geoposition.error_code = Geoposition::ERROR_CODE_NONE;
292 // Webkit compares the timestamp to wall clock time, so we need
293 // it to be contemporary.
294 geoposition.timestamp = base::Time::Now();
295 EXPECT_TRUE(geoposition.IsValidFix());
296 return geoposition;
297 }
298
CheckGeoposition(const Geoposition & geoposition)299 void CheckGeoposition(const Geoposition& geoposition) {
300 // Checks we have no error.
301 CheckStringValueFromJavascript("0", "geoGetLastError()");
302 CheckStringValueFromJavascript(base::DoubleToString(geoposition.latitude),
303 "geoGetLastPositionLatitude()");
304 CheckStringValueFromJavascript(base::DoubleToString(geoposition.longitude),
305 "geoGetLastPositionLongitude()");
306 }
307
SetInfobarResponse(const GURL & requesting_url,bool allowed)308 void SetInfobarResponse(const GURL& requesting_url, bool allowed) {
309 TabContents* tab_contents = current_browser_->GetSelectedTabContents();
310 TabSpecificContentSettings* content_settings =
311 tab_contents->GetTabSpecificContentSettings();
312 const GeolocationSettingsState& settings_state =
313 content_settings->geolocation_settings_state();
314 size_t state_map_size = settings_state.state_map().size();
315 ASSERT_TRUE(infobar_);
316 LOG(WARNING) << "will set infobar response";
317 if (allowed)
318 infobar_->AsConfirmInfoBarDelegate()->Accept();
319 else
320 infobar_->AsConfirmInfoBarDelegate()->Cancel();
321 WaitForNavigation();
322 tab_contents->RemoveInfoBar(infobar_);
323 LOG(WARNING) << "infobar response set";
324 infobar_ = NULL;
325 EXPECT_GT(settings_state.state_map().size(), state_map_size);
326 GURL requesting_origin = requesting_url.GetOrigin();
327 EXPECT_EQ(1U, settings_state.state_map().count(requesting_origin));
328 ContentSetting expected_setting =
329 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
330 EXPECT_EQ(expected_setting,
331 settings_state.state_map().find(requesting_origin)->second);
332 }
333
WaitForNavigation()334 void WaitForNavigation() {
335 LOG(WARNING) << "will block for navigation";
336 NavigationController* controller =
337 ¤t_browser_->GetSelectedTabContents()->controller();
338 ui_test_utils::WaitForNavigation(controller);
339 LOG(WARNING) << "navigated";
340 }
341
CheckStringValueFromJavascriptForTab(const std::string & expected,const std::string & function,TabContents * tab_contents)342 void CheckStringValueFromJavascriptForTab(
343 const std::string& expected, const std::string& function,
344 TabContents* tab_contents) {
345 std::string script = StringPrintf(
346 "window.domAutomationController.send(%s)", function.c_str());
347 std::string result;
348 ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
349 tab_contents->render_view_host(),
350 iframe_xpath_, UTF8ToWide(script), &result));
351 EXPECT_EQ(expected, result);
352 }
353
CheckStringValueFromJavascript(const std::string & expected,const std::string & function)354 void CheckStringValueFromJavascript(
355 const std::string& expected, const std::string& function) {
356 CheckStringValueFromJavascriptForTab(
357 expected, function, current_browser_->GetSelectedTabContents());
358 }
359
360 InfoBarDelegate* infobar_;
361 Browser* current_browser_;
362 // path element of a URL referencing the html content for this test.
363 std::string html_for_tests_;
364 // This member defines the iframe (or top-level page, if empty) where the
365 // javascript calls will run.
366 std::wstring iframe_xpath_;
367 // The current url for the top level page.
368 GURL current_url_;
369 // If not empty, the GURLs for the iframes loaded by LoadIFrames().
370 std::vector<GURL> iframe_urls_;
371
372 // TODO(phajdan.jr): Remove after we can ask TestServer whether it is started.
373 bool started_test_server_;
374
375 scoped_refptr<GeolocationArbitratorDependencyFactory> dependency_factory_;
376 };
377
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,DisplaysPermissionBar)378 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, DisplaysPermissionBar) {
379 ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
380 AddGeolocationWatch(true);
381 }
382
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,Geoposition)383 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, Geoposition) {
384 ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
385 AddGeolocationWatch(true);
386 SetInfobarResponse(current_url_, true);
387 CheckGeoposition(MockLocationProvider::instance_->position_);
388 }
389
390 // Crashy, http://crbug.com/70585.
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,DISABLED_ErrorOnPermissionDenied)391 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,
392 DISABLED_ErrorOnPermissionDenied) {
393 ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
394 AddGeolocationWatch(true);
395 // Infobar was displayed, deny access and check for error code.
396 SetInfobarResponse(current_url_, false);
397 CheckStringValueFromJavascript("1", "geoGetLastError()");
398 }
399
400 // http://crbug.com/44589. Hangs on Mac, crashes on Windows
401 #if defined(OS_MACOSX) || defined(OS_WINDOWS)
402 #define MAYBE_NoInfobarForSecondTab DISABLED_NoInfobarForSecondTab
403 #else
404 #define MAYBE_NoInfobarForSecondTab NoInfobarForSecondTab
405 #endif
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,MAYBE_NoInfobarForSecondTab)406 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_NoInfobarForSecondTab) {
407 ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
408 AddGeolocationWatch(true);
409 SetInfobarResponse(current_url_, true);
410 // Disables further prompts from this tab.
411 CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
412
413 // Checks infobar will not be created a second tab.
414 ASSERT_TRUE(Initialize(INITIALIZATION_NEWTAB));
415 AddGeolocationWatch(false);
416 CheckGeoposition(MockLocationProvider::instance_->position_);
417 }
418
419 // http://crbug.com/44589. Hangs on Mac, crashes on Windows
420 #if defined(OS_MACOSX) || defined(OS_WINDOWS)
421 #define MAYBE_NoInfobarForDeniedOrigin DISABLED_NoInfobarForDeniedOrigin
422 #else
423 #define MAYBE_NoInfobarForDeniedOrigin NoInfobarForDeniedOrigin
424 #endif
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,MAYBE_NoInfobarForDeniedOrigin)425 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_NoInfobarForDeniedOrigin) {
426 ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
427 current_browser_->profile()->GetGeolocationContentSettingsMap()->
428 SetContentSetting(current_url_, current_url_, CONTENT_SETTING_BLOCK);
429 AddGeolocationWatch(false);
430 // Checks we have an error for this denied origin.
431 CheckStringValueFromJavascript("1", "geoGetLastError()");
432 // Checks infobar will not be created a second tab.
433 ASSERT_TRUE(Initialize(INITIALIZATION_NEWTAB));
434 AddGeolocationWatch(false);
435 CheckStringValueFromJavascript("1", "geoGetLastError()");
436 }
437
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,NoInfobarForAllowedOrigin)438 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoInfobarForAllowedOrigin) {
439 ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
440 current_browser_->profile()->GetGeolocationContentSettingsMap()->
441 SetContentSetting(current_url_, current_url_, CONTENT_SETTING_ALLOW);
442 // Checks no infobar will be created and there's no error callback.
443 AddGeolocationWatch(false);
444 CheckGeoposition(MockLocationProvider::instance_->position_);
445 }
446
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,NoInfobarForOffTheRecord)447 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoInfobarForOffTheRecord) {
448 // First, check infobar will be created for regular profile
449 ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
450 AddGeolocationWatch(true);
451 // Response will be persisted
452 SetInfobarResponse(current_url_, true);
453 CheckGeoposition(MockLocationProvider::instance_->position_);
454 // Disables further prompts from this tab.
455 CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
456 // Go incognito, and checks no infobar will be created.
457 ASSERT_TRUE(Initialize(INITIALIZATION_OFFTHERECORD));
458 AddGeolocationWatch(false);
459 CheckGeoposition(MockLocationProvider::instance_->position_);
460 }
461
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,IFramesWithFreshPosition)462 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, IFramesWithFreshPosition) {
463 html_for_tests_ = "files/geolocation/iframes_different_origin.html";
464 ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
465 LoadIFrames(2);
466 LOG(WARNING) << "frames loaded";
467
468 iframe_xpath_ = L"//iframe[@id='iframe_0']";
469 AddGeolocationWatch(true);
470 SetInfobarResponse(iframe_urls_[0], true);
471 CheckGeoposition(MockLocationProvider::instance_->position_);
472 // Disables further prompts from this iframe.
473 CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
474
475 // Test second iframe from a different origin with a cached geoposition will
476 // create the infobar.
477 iframe_xpath_ = L"//iframe[@id='iframe_1']";
478 AddGeolocationWatch(true);
479
480 // Back to the first frame, enable navigation and refresh geoposition.
481 iframe_xpath_ = L"//iframe[@id='iframe_0']";
482 CheckStringValueFromJavascript("1", "geoSetMaxNavigateCount(1)");
483 // MockLocationProvider must have been created.
484 ASSERT_TRUE(MockLocationProvider::instance_);
485 Geoposition fresh_position = GeopositionFromLatLong(3.17, 4.23);
486 NotifyGeoposition(fresh_position);
487 WaitForNavigation();
488 CheckGeoposition(fresh_position);
489
490 // Disable navigation for this frame.
491 CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
492
493 // Now go ahead an authorize the second frame.
494 iframe_xpath_ = L"//iframe[@id='iframe_1']";
495 // Infobar was displayed, allow access and check there's no error code.
496 SetInfobarResponse(iframe_urls_[1], true);
497 LOG(WARNING) << "Checking position...";
498 CheckGeoposition(fresh_position);
499 LOG(WARNING) << "...done.";
500 }
501
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,IFramesWithCachedPosition)502 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, IFramesWithCachedPosition) {
503 html_for_tests_ = "files/geolocation/iframes_different_origin.html";
504 ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
505 LoadIFrames(2);
506
507 iframe_xpath_ = L"//iframe[@id='iframe_0']";
508 AddGeolocationWatch(true);
509 SetInfobarResponse(iframe_urls_[0], true);
510 CheckGeoposition(MockLocationProvider::instance_->position_);
511
512 // Refresh geoposition, but let's not yet create the watch on the second frame
513 // so that it'll fetch from cache.
514 // MockLocationProvider must have been created.
515 ASSERT_TRUE(MockLocationProvider::instance_);
516 Geoposition cached_position = GeopositionFromLatLong(5.67, 8.09);
517 NotifyGeoposition(cached_position);
518 WaitForNavigation();
519 CheckGeoposition(cached_position);
520
521 // Disable navigation for this frame.
522 CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
523
524 // Now go ahead an authorize the second frame.
525 iframe_xpath_ = L"//iframe[@id='iframe_1']";
526 AddGeolocationWatch(true);
527 // WebKit will use its cache, but we also broadcast a position shortly
528 // afterwards. We're only interested in the first navigation for the success
529 // callback from the cached position.
530 CheckStringValueFromJavascript("1", "geoSetMaxNavigateCount(1)");
531 SetInfobarResponse(iframe_urls_[1], true);
532 CheckGeoposition(cached_position);
533 }
534
535 // See http://crbug.com/56033
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,DISABLED_CancelPermissionForFrame)536 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,
537 DISABLED_CancelPermissionForFrame) {
538 html_for_tests_ = "files/geolocation/iframes_different_origin.html";
539 ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
540 LoadIFrames(2);
541 LOG(WARNING) << "frames loaded";
542
543 iframe_xpath_ = L"//iframe[@id='iframe_0']";
544 AddGeolocationWatch(true);
545 SetInfobarResponse(iframe_urls_[0], true);
546 CheckGeoposition(MockLocationProvider::instance_->position_);
547 // Disables further prompts from this iframe.
548 CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
549
550 // Test second iframe from a different origin with a cached geoposition will
551 // create the infobar.
552 iframe_xpath_ = L"//iframe[@id='iframe_1']";
553 AddGeolocationWatch(true);
554
555 size_t num_infobars_before_cancel =
556 current_browser_->GetSelectedTabContents()->infobar_count();
557 // Change the iframe, and ensure the infobar is gone.
558 IFrameLoader change_iframe_1(current_browser_, 1, current_url_);
559 size_t num_infobars_after_cancel =
560 current_browser_->GetSelectedTabContents()->infobar_count();
561 EXPECT_EQ(num_infobars_before_cancel, num_infobars_after_cancel + 1);
562 }
563
564 // Disabled, http://crbug.com/66959.
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,DISABLED_InvalidUrlRequest)565 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, DISABLED_InvalidUrlRequest) {
566 // Tests that an invalid URL (e.g. from a popup window) is rejected
567 // correctly. Also acts as a regression test for http://crbug.com/40478
568 html_for_tests_ = "files/geolocation/invalid_request_url.html";
569 ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
570 TabContents* original_tab = current_browser_->GetSelectedTabContents();
571 CheckStringValueFromJavascript("1", "requestGeolocationFromInvalidUrl()");
572 CheckStringValueFromJavascriptForTab("1", "isAlive()", original_tab);
573 }
574
575 // Crashy, http://crbug.com/66400.
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,DISABLED_NoInfoBarBeforeStart)576 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, DISABLED_NoInfoBarBeforeStart) {
577 // See http://crbug.com/42789
578 html_for_tests_ = "files/geolocation/iframes_different_origin.html";
579 ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
580 LoadIFrames(2);
581 LOG(WARNING) << "frames loaded";
582
583 // Access navigator.geolocation, but ensure it won't request permission.
584 iframe_xpath_ = L"//iframe[@id='iframe_1']";
585 CheckStringValueFromJavascript("object", "geoAccessNavigatorGeolocation()");
586
587 iframe_xpath_ = L"//iframe[@id='iframe_0']";
588 AddGeolocationWatch(true);
589 SetInfobarResponse(iframe_urls_[0], true);
590 CheckGeoposition(MockLocationProvider::instance_->position_);
591 CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
592
593 // Permission should be requested after adding a watch.
594 iframe_xpath_ = L"//iframe[@id='iframe_1']";
595 AddGeolocationWatch(true);
596 SetInfobarResponse(iframe_urls_[1], true);
597 CheckGeoposition(MockLocationProvider::instance_->position_);
598 }
599
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,TwoWatchesInOneFrame)600 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, TwoWatchesInOneFrame) {
601 html_for_tests_ = "files/geolocation/two_watches.html";
602 ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
603 // First, set the JavaScript to navigate when it receives |final_position|.
604 const Geoposition final_position = GeopositionFromLatLong(3.17, 4.23);
605 std::string script = StringPrintf(
606 "window.domAutomationController.send(geoSetFinalPosition(%f, %f))",
607 final_position.latitude, final_position.longitude);
608 std::string js_result;
609 EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
610 current_browser_->GetSelectedTabContents()->render_view_host(),
611 L"", UTF8ToWide(script), &js_result));
612 EXPECT_EQ(js_result, "ok");
613
614 // Send a position which both geolocation watches will receive.
615 AddGeolocationWatch(true);
616 SetInfobarResponse(current_url_, true);
617 CheckGeoposition(MockLocationProvider::instance_->position_);
618
619 // The second watch will now have cancelled. Ensure an update still makes
620 // its way through to the first watcher.
621 NotifyGeoposition(final_position);
622 WaitForNavigation();
623 CheckGeoposition(final_position);
624 }
625
626 // Hangs flakily, http://crbug.com/70588.
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,DISABLED_TabDestroyed)627 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, DISABLED_TabDestroyed) {
628 html_for_tests_ = "files/geolocation/tab_destroyed.html";
629 ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
630 LoadIFrames(3);
631
632 iframe_xpath_ = L"//iframe[@id='iframe_0']";
633 AddGeolocationWatch(true);
634
635 iframe_xpath_ = L"//iframe[@id='iframe_1']";
636 AddGeolocationWatch(false);
637
638 iframe_xpath_ = L"//iframe[@id='iframe_2']";
639 AddGeolocationWatch(false);
640
641 std::string script =
642 "window.domAutomationController.setAutomationId(0);"
643 "window.domAutomationController.send(window.close());";
644 bool result =
645 ui_test_utils::ExecuteJavaScript(
646 current_browser_->GetSelectedTabContents()->render_view_host(),
647 L"", UTF8ToWide(script));
648 EXPECT_EQ(result, true);
649 }
650
651 } // namespace
652