OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/public/test/browser_test_utils.h" | 5 #include "content/public/test/browser_test_utils.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <tuple> | 8 #include <tuple> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/auto_reset.h" | 11 #include "base/auto_reset.h" |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 15 #include "base/guid.h" |
15 #include "base/json/json_reader.h" | 16 #include "base/json/json_reader.h" |
16 #include "base/macros.h" | 17 #include "base/macros.h" |
17 #include "base/process/kill.h" | 18 #include "base/process/kill.h" |
18 #include "base/rand_util.h" | 19 #include "base/rand_util.h" |
19 #include "base/stl_util.h" | 20 #include "base/stl_util.h" |
20 #include "base/strings/pattern.h" | 21 #include "base/strings/pattern.h" |
21 #include "base/strings/string_number_conversions.h" | 22 #include "base/strings/string_number_conversions.h" |
22 #include "base/strings/string_piece.h" | 23 #include "base/strings/string_piece.h" |
| 24 #include "base/strings/stringprintf.h" |
23 #include "base/strings/utf_string_conversions.h" | 25 #include "base/strings/utf_string_conversions.h" |
24 #include "base/synchronization/waitable_event.h" | 26 #include "base/synchronization/waitable_event.h" |
25 #include "base/test/test_timeouts.h" | 27 #include "base/test/test_timeouts.h" |
26 #include "base/threading/thread_task_runner_handle.h" | 28 #include "base/threading/thread_task_runner_handle.h" |
27 #include "base/values.h" | 29 #include "base/values.h" |
28 #include "build/build_config.h" | 30 #include "build/build_config.h" |
29 #include "cc/surfaces/frame_sink_manager.h" | 31 #include "cc/surfaces/frame_sink_manager.h" |
30 #include "cc/surfaces/surface.h" | 32 #include "cc/surfaces/surface.h" |
31 #include "cc/surfaces/surface_manager.h" | 33 #include "cc/surfaces/surface_manager.h" |
32 #include "content/browser/accessibility/browser_accessibility.h" | 34 #include "content/browser/accessibility/browser_accessibility.h" |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 base::JSONReader reader(base::JSON_ALLOW_TRAILING_COMMAS); | 170 base::JSONReader reader(base::JSON_ALLOW_TRAILING_COMMAS); |
169 *result = reader.ReadToValue(json); | 171 *result = reader.ReadToValue(json); |
170 if (!*result) { | 172 if (!*result) { |
171 DLOG(ERROR) << reader.GetErrorMessage(); | 173 DLOG(ERROR) << reader.GetErrorMessage(); |
172 return false; | 174 return false; |
173 } | 175 } |
174 | 176 |
175 return true; | 177 return true; |
176 } | 178 } |
177 | 179 |
| 180 bool ExecuteScriptWithUserGestureControl(RenderFrameHost* frame, |
| 181 const std::string& script, |
| 182 bool user_gesture) { |
| 183 // TODO(lukasza): ExecuteScript should just call |
| 184 // ExecuteJavaScriptWithUserGestureForTests and avoid modifying the original |
| 185 // script (and at that point we should merge it with and remove |
| 186 // ExecuteScriptAsync). This is difficult to change, because many tests |
| 187 // depend on the message loop pumping done by ExecuteScriptHelper below (this |
| 188 // is fragile - these tests should wait on a more specific thing instead). |
| 189 |
| 190 std::string expected_response = "ExecuteScript-" + base::GenerateGUID(); |
| 191 std::string new_script = base::StringPrintf( |
| 192 R"( %s; // Original script. |
| 193 window.domAutomationController.send('%s'); )", |
| 194 script.c_str(), expected_response.c_str()); |
| 195 |
| 196 std::unique_ptr<base::Value> value; |
| 197 if (!ExecuteScriptHelper(frame, new_script, user_gesture, &value) || |
| 198 !value.get()) { |
| 199 return false; |
| 200 } |
| 201 |
| 202 DCHECK_EQ(base::Value::Type::STRING, value->GetType()); |
| 203 std::string actual_response; |
| 204 if (value->GetAsString(&actual_response)) |
| 205 DCHECK_EQ(expected_response, actual_response); |
| 206 |
| 207 return true; |
| 208 } |
| 209 |
178 // Specifying a prototype so that we can add the WARN_UNUSED_RESULT attribute. | 210 // Specifying a prototype so that we can add the WARN_UNUSED_RESULT attribute. |
179 bool ExecuteScriptInIsolatedWorldHelper(RenderFrameHost* render_frame_host, | 211 bool ExecuteScriptInIsolatedWorldHelper(RenderFrameHost* render_frame_host, |
180 const int world_id, | 212 const int world_id, |
181 const std::string& original_script, | 213 const std::string& original_script, |
182 std::unique_ptr<base::Value>* result) | 214 std::unique_ptr<base::Value>* result) |
183 WARN_UNUSED_RESULT; | 215 WARN_UNUSED_RESULT; |
184 | 216 |
185 bool ExecuteScriptInIsolatedWorldHelper(RenderFrameHost* render_frame_host, | 217 bool ExecuteScriptInIsolatedWorldHelper(RenderFrameHost* render_frame_host, |
186 const int world_id, | 218 const int world_id, |
187 const std::string& original_script, | 219 const std::string& original_script, |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 } | 439 } |
408 | 440 |
409 // Queries for video input devices on the current system using the getSources | 441 // Queries for video input devices on the current system using the getSources |
410 // API. | 442 // API. |
411 // | 443 // |
412 // This does not guarantee that a getUserMedia with video will succeed, as the | 444 // This does not guarantee that a getUserMedia with video will succeed, as the |
413 // camera could be busy for instance. | 445 // camera could be busy for instance. |
414 // | 446 // |
415 // Returns has-video-input-device to the test if there is a webcam available, | 447 // Returns has-video-input-device to the test if there is a webcam available, |
416 // no-video-input-devices otherwise. | 448 // no-video-input-devices otherwise. |
417 const char kHasVideoInputDeviceOnSystem[] = | 449 const char kHasVideoInputDeviceOnSystem[] = R"( |
418 "(function() {" | 450 (function() { |
419 "navigator.mediaDevices.enumerateDevices()" | 451 navigator.mediaDevices.enumerateDevices() |
420 ".then(function(devices) {" | 452 .then(function(devices) { |
421 "devices.forEach(function(device) {" | 453 if (devices.some((device) => device.kind == 'videoinput')) { |
422 "if (device.kind == 'videoinput') {" | 454 window.domAutomationController.send('has-video-input-device'); |
423 "window.domAutomationController.send('has-video-input-device');" | 455 } else { |
424 "return;" | 456 window.domAutomationController.send('no-video-input-devices'); |
425 "}" | 457 } |
426 "});" | 458 }); |
427 "window.domAutomationController.send('no-video-input-devices');" | 459 })() |
428 "});" | 460 )"; |
429 "})()"; | |
430 | 461 |
431 const char kHasVideoInputDevice[] = "has-video-input-device"; | 462 const char kHasVideoInputDevice[] = "has-video-input-device"; |
432 | 463 |
433 } // namespace | 464 } // namespace |
434 | 465 |
435 bool NavigateIframeToURL(WebContents* web_contents, | 466 bool NavigateIframeToURL(WebContents* web_contents, |
436 std::string iframe_id, | 467 std::string iframe_id, |
437 const GURL& url) { | 468 const GURL& url) { |
438 std::string script = base::StringPrintf( | 469 std::string script = base::StringPrintf( |
439 "setTimeout(\"" | 470 "setTimeout(\"" |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 RenderFrameHost* ConvertToRenderFrameHost(RenderViewHost* render_view_host) { | 841 RenderFrameHost* ConvertToRenderFrameHost(RenderViewHost* render_view_host) { |
811 return render_view_host->GetMainFrame(); | 842 return render_view_host->GetMainFrame(); |
812 } | 843 } |
813 | 844 |
814 RenderFrameHost* ConvertToRenderFrameHost(RenderFrameHost* render_frame_host) { | 845 RenderFrameHost* ConvertToRenderFrameHost(RenderFrameHost* render_frame_host) { |
815 return render_frame_host; | 846 return render_frame_host; |
816 } | 847 } |
817 | 848 |
818 bool ExecuteScript(const ToRenderFrameHost& adapter, | 849 bool ExecuteScript(const ToRenderFrameHost& adapter, |
819 const std::string& script) { | 850 const std::string& script) { |
820 std::string new_script = | 851 return ExecuteScriptWithUserGestureControl(adapter.render_frame_host(), |
821 script + ";window.domAutomationController.send(0);"; | 852 script, true); |
822 return ExecuteScriptHelper(adapter.render_frame_host(), new_script, true, | |
823 nullptr); | |
824 } | 853 } |
825 | 854 |
826 bool ExecuteScriptWithoutUserGesture(const ToRenderFrameHost& adapter, | 855 bool ExecuteScriptWithoutUserGesture(const ToRenderFrameHost& adapter, |
827 const std::string& script) { | 856 const std::string& script) { |
828 std::string new_script = script + ";window.domAutomationController.send(0);"; | 857 return ExecuteScriptWithUserGestureControl(adapter.render_frame_host(), |
829 return ExecuteScriptHelper(adapter.render_frame_host(), new_script, false, | 858 script, false); |
830 nullptr); | 859 } |
| 860 |
| 861 void ExecuteScriptAsync(const ToRenderFrameHost& adapter, |
| 862 const std::string& script) { |
| 863 adapter.render_frame_host()->ExecuteJavaScriptWithUserGestureForTests( |
| 864 base::UTF8ToUTF16(script)); |
831 } | 865 } |
832 | 866 |
833 bool ExecuteScriptAndExtractDouble(const ToRenderFrameHost& adapter, | 867 bool ExecuteScriptAndExtractDouble(const ToRenderFrameHost& adapter, |
834 const std::string& script, double* result) { | 868 const std::string& script, double* result) { |
835 DCHECK(result); | 869 DCHECK(result); |
836 std::unique_ptr<base::Value> value; | 870 std::unique_ptr<base::Value> value; |
837 if (!ExecuteScriptHelper(adapter.render_frame_host(), script, true, &value) || | 871 if (!ExecuteScriptHelper(adapter.render_frame_host(), script, true, &value) || |
838 !value.get()) { | 872 !value.get()) { |
839 return false; | 873 return false; |
840 } | 874 } |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 scoped_refptr<base::RefCountedMemory> bytes = | 1027 scoped_refptr<base::RefCountedMemory> bytes = |
994 ResourceBundle::GetSharedInstance().LoadDataResourceBytes(*iter); | 1028 ResourceBundle::GetSharedInstance().LoadDataResourceBytes(*iter); |
995 | 1029 |
996 if (HasGzipHeader(*bytes)) | 1030 if (HasGzipHeader(*bytes)) |
997 AppendGzippedResource(*bytes, &script); | 1031 AppendGzippedResource(*bytes, &script); |
998 else | 1032 else |
999 script.append(bytes->front_as<char>(), bytes->size()); | 1033 script.append(bytes->front_as<char>(), bytes->size()); |
1000 | 1034 |
1001 script.append("\n"); | 1035 script.append("\n"); |
1002 } | 1036 } |
1003 if (!ExecuteScript(web_contents, script)) | 1037 ExecuteScriptAsync(web_contents, script); |
1004 return false; | |
1005 | 1038 |
1006 DOMMessageQueue message_queue; | 1039 DOMMessageQueue message_queue; |
1007 if (!ExecuteScript(web_contents, "runTests()")) | 1040 ExecuteScriptAsync(web_contents, "runTests()"); |
1008 return false; | |
1009 | 1041 |
1010 std::string message; | 1042 std::string message; |
1011 do { | 1043 do { |
1012 if (!message_queue.WaitForMessage(&message)) | 1044 if (!message_queue.WaitForMessage(&message)) |
1013 return false; | 1045 return false; |
1014 } while (message.compare("\"PENDING\"") == 0); | 1046 } while (message.compare("\"PENDING\"") == 0); |
1015 | 1047 |
1016 return message.compare("\"SUCCESS\"") == 0; | 1048 return message.compare("\"SUCCESS\"") == 0; |
1017 } | 1049 } |
1018 | 1050 |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1486 Source<WebContents>(web_contents)); | 1518 Source<WebContents>(web_contents)); |
1487 } | 1519 } |
1488 | 1520 |
1489 DOMMessageQueue::~DOMMessageQueue() {} | 1521 DOMMessageQueue::~DOMMessageQueue() {} |
1490 | 1522 |
1491 void DOMMessageQueue::Observe(int type, | 1523 void DOMMessageQueue::Observe(int type, |
1492 const NotificationSource& source, | 1524 const NotificationSource& source, |
1493 const NotificationDetails& details) { | 1525 const NotificationDetails& details) { |
1494 Details<std::string> dom_op_result(details); | 1526 Details<std::string> dom_op_result(details); |
1495 message_queue_.push(*dom_op_result.ptr()); | 1527 message_queue_.push(*dom_op_result.ptr()); |
1496 if (message_loop_runner_.get()) | 1528 if (message_loop_runner_) |
1497 message_loop_runner_->Quit(); | 1529 message_loop_runner_->Quit(); |
1498 } | 1530 } |
1499 | 1531 |
1500 void DOMMessageQueue::RenderProcessGone(base::TerminationStatus status) { | 1532 void DOMMessageQueue::RenderProcessGone(base::TerminationStatus status) { |
1501 VLOG(0) << "DOMMessageQueue::RenderProcessGone " << status; | 1533 VLOG(0) << "DOMMessageQueue::RenderProcessGone " << status; |
1502 switch (status) { | 1534 switch (status) { |
1503 case base::TERMINATION_STATUS_NORMAL_TERMINATION: | 1535 case base::TERMINATION_STATUS_NORMAL_TERMINATION: |
1504 case base::TERMINATION_STATUS_STILL_RUNNING: | 1536 case base::TERMINATION_STATUS_STILL_RUNNING: |
1505 break; | 1537 break; |
1506 default: | 1538 default: |
| 1539 renderer_crashed_ = true; |
1507 if (message_loop_runner_.get()) | 1540 if (message_loop_runner_.get()) |
1508 message_loop_runner_->Quit(); | 1541 message_loop_runner_->Quit(); |
1509 break; | 1542 break; |
1510 } | 1543 } |
1511 } | 1544 } |
1512 | 1545 |
1513 void DOMMessageQueue::ClearQueue() { | 1546 void DOMMessageQueue::ClearQueue() { |
1514 message_queue_ = std::queue<std::string>(); | 1547 message_queue_ = std::queue<std::string>(); |
1515 } | 1548 } |
1516 | 1549 |
1517 bool DOMMessageQueue::WaitForMessage(std::string* message) { | 1550 bool DOMMessageQueue::WaitForMessage(std::string* message) { |
1518 DCHECK(message); | 1551 DCHECK(message); |
1519 if (message_queue_.empty()) { | 1552 if (!renderer_crashed_ && message_queue_.empty()) { |
1520 // This will be quit when a new message comes in. | 1553 // This will be quit when a new message comes in. |
1521 message_loop_runner_ = | 1554 message_loop_runner_ = |
1522 new MessageLoopRunner(MessageLoopRunner::QuitMode::IMMEDIATE); | 1555 new MessageLoopRunner(MessageLoopRunner::QuitMode::IMMEDIATE); |
1523 message_loop_runner_->Run(); | 1556 message_loop_runner_->Run(); |
1524 } | 1557 } |
1525 return PopMessage(message); | 1558 return PopMessage(message); |
1526 } | 1559 } |
1527 | 1560 |
1528 bool DOMMessageQueue::PopMessage(std::string* message) { | 1561 bool DOMMessageQueue::PopMessage(std::string* message) { |
1529 DCHECK(message); | 1562 DCHECK(message); |
1530 if (message_queue_.empty()) | 1563 if (renderer_crashed_ || message_queue_.empty()) |
1531 return false; | 1564 return false; |
1532 *message = message_queue_.front(); | 1565 *message = message_queue_.front(); |
1533 message_queue_.pop(); | 1566 message_queue_.pop(); |
1534 return true; | 1567 return true; |
1535 } | 1568 } |
1536 | 1569 |
1537 class WebContentsAddedObserver::RenderViewCreatedObserver | 1570 class WebContentsAddedObserver::RenderViewCreatedObserver |
1538 : public WebContentsObserver { | 1571 : public WebContentsObserver { |
1539 public: | 1572 public: |
1540 explicit RenderViewCreatedObserver(WebContents* web_contents) | 1573 explicit RenderViewCreatedObserver(WebContents* web_contents) |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2105 RenderWidgetHostViewAura* rwhva = | 2138 RenderWidgetHostViewAura* rwhva = |
2106 static_cast<RenderWidgetHostViewAura*>(rwhv); | 2139 static_cast<RenderWidgetHostViewAura*>(rwhv); |
2107 rwhva->SetOverscrollControllerForTesting(std::move(mock)); | 2140 rwhva->SetOverscrollControllerForTesting(std::move(mock)); |
2108 | 2141 |
2109 return raw_mock; | 2142 return raw_mock; |
2110 } | 2143 } |
2111 | 2144 |
2112 #endif // defined(USE_AURA) | 2145 #endif // defined(USE_AURA) |
2113 | 2146 |
2114 } // namespace content | 2147 } // namespace content |
OLD | NEW |