Index: content/public/test/browser_test_utils.cc |
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc |
index b88b61ffe449bd5af1a018dee4025a59c1ab66fe..725456c384ee70162e673e3cfe0556da395ca275 100644 |
--- a/content/public/test/browser_test_utils.cc |
+++ b/content/public/test/browser_test_utils.cc |
@@ -12,6 +12,7 @@ |
#include "base/bind.h" |
#include "base/bind_helpers.h" |
#include "base/command_line.h" |
+#include "base/guid.h" |
#include "base/json/json_reader.h" |
#include "base/macros.h" |
#include "base/process/kill.h" |
@@ -20,6 +21,7 @@ |
#include "base/strings/pattern.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/strings/string_piece.h" |
+#include "base/strings/stringprintf.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/synchronization/waitable_event.h" |
#include "base/test/test_timeouts.h" |
@@ -175,6 +177,36 @@ bool ExecuteScriptHelper(RenderFrameHost* render_frame_host, |
return true; |
} |
+bool ExecuteScriptWithUserGestureControl(RenderFrameHost* frame, |
+ const std::string& script, |
+ bool user_gesture) { |
+ // TODO(lukasza): ExecuteScript should just call |
+ // ExecuteJavaScriptWithUserGestureForTests and avoid modifying the original |
+ // script (and at that point we should merge it with and remove |
+ // ExecuteScriptAsync). This is difficult to change, because many tests |
+ // depend on the message loop pumping done by ExecuteScriptHelper below (this |
+ // is fragile - these tests should wait on a more specific thing instead). |
+ |
+ std::string expected_response = "ExecuteScript-" + base::GenerateGUID(); |
+ std::string new_script = base::StringPrintf( |
+ R"( %s; // Original script. |
+ window.domAutomationController.send('%s'); )", |
+ script.c_str(), expected_response.c_str()); |
+ |
+ std::unique_ptr<base::Value> value; |
+ if (!ExecuteScriptHelper(frame, new_script, user_gesture, &value) || |
+ !value.get()) { |
+ return false; |
+ } |
+ |
+ DCHECK_EQ(base::Value::Type::STRING, value->GetType()); |
+ std::string actual_response; |
+ if (value->GetAsString(&actual_response)) |
+ DCHECK_EQ(expected_response, actual_response); |
+ |
+ return true; |
+} |
+ |
// Specifying a prototype so that we can add the WARN_UNUSED_RESULT attribute. |
bool ExecuteScriptInIsolatedWorldHelper(RenderFrameHost* render_frame_host, |
const int world_id, |
@@ -414,19 +446,18 @@ void AppendGzippedResource(const base::RefCountedMemory& encoded, |
// |
// Returns has-video-input-device to the test if there is a webcam available, |
// no-video-input-devices otherwise. |
-const char kHasVideoInputDeviceOnSystem[] = |
- "(function() {" |
- "navigator.mediaDevices.enumerateDevices()" |
- ".then(function(devices) {" |
- "devices.forEach(function(device) {" |
- "if (device.kind == 'videoinput') {" |
- "window.domAutomationController.send('has-video-input-device');" |
- "return;" |
- "}" |
- "});" |
- "window.domAutomationController.send('no-video-input-devices');" |
- "});" |
- "})()"; |
+const char kHasVideoInputDeviceOnSystem[] = R"( |
+ (function() { |
+ navigator.mediaDevices.enumerateDevices() |
+ .then(function(devices) { |
+ if (devices.some((device) => device.kind == 'videoinput')) { |
+ window.domAutomationController.send('has-video-input-device'); |
+ } else { |
+ window.domAutomationController.send('no-video-input-devices'); |
+ } |
+ }); |
+ })() |
+)"; |
const char kHasVideoInputDevice[] = "has-video-input-device"; |
@@ -817,17 +848,20 @@ RenderFrameHost* ConvertToRenderFrameHost(RenderFrameHost* render_frame_host) { |
bool ExecuteScript(const ToRenderFrameHost& adapter, |
const std::string& script) { |
- std::string new_script = |
- script + ";window.domAutomationController.send(0);"; |
- return ExecuteScriptHelper(adapter.render_frame_host(), new_script, true, |
- nullptr); |
+ return ExecuteScriptWithUserGestureControl(adapter.render_frame_host(), |
+ script, true); |
} |
bool ExecuteScriptWithoutUserGesture(const ToRenderFrameHost& adapter, |
const std::string& script) { |
- std::string new_script = script + ";window.domAutomationController.send(0);"; |
- return ExecuteScriptHelper(adapter.render_frame_host(), new_script, false, |
- nullptr); |
+ return ExecuteScriptWithUserGestureControl(adapter.render_frame_host(), |
+ script, false); |
+} |
+ |
+void ExecuteScriptAsync(const ToRenderFrameHost& adapter, |
+ const std::string& script) { |
+ adapter.render_frame_host()->ExecuteJavaScriptWithUserGestureForTests( |
+ base::UTF8ToUTF16(script)); |
} |
bool ExecuteScriptAndExtractDouble(const ToRenderFrameHost& adapter, |
@@ -1000,12 +1034,10 @@ bool ExecuteWebUIResourceTest(WebContents* web_contents, |
script.append("\n"); |
} |
- if (!ExecuteScript(web_contents, script)) |
- return false; |
+ ExecuteScriptAsync(web_contents, script); |
DOMMessageQueue message_queue; |
- if (!ExecuteScript(web_contents, "runTests()")) |
- return false; |
+ ExecuteScriptAsync(web_contents, "runTests()"); |
std::string message; |
do { |
@@ -1493,7 +1525,7 @@ void DOMMessageQueue::Observe(int type, |
const NotificationDetails& details) { |
Details<std::string> dom_op_result(details); |
message_queue_.push(*dom_op_result.ptr()); |
- if (message_loop_runner_.get()) |
+ if (message_loop_runner_) |
message_loop_runner_->Quit(); |
} |
@@ -1504,6 +1536,7 @@ void DOMMessageQueue::RenderProcessGone(base::TerminationStatus status) { |
case base::TERMINATION_STATUS_STILL_RUNNING: |
break; |
default: |
+ renderer_crashed_ = true; |
if (message_loop_runner_.get()) |
message_loop_runner_->Quit(); |
break; |
@@ -1516,7 +1549,7 @@ void DOMMessageQueue::ClearQueue() { |
bool DOMMessageQueue::WaitForMessage(std::string* message) { |
DCHECK(message); |
- if (message_queue_.empty()) { |
+ if (!renderer_crashed_ && message_queue_.empty()) { |
// This will be quit when a new message comes in. |
message_loop_runner_ = |
new MessageLoopRunner(MessageLoopRunner::QuitMode::IMMEDIATE); |
@@ -1527,7 +1560,7 @@ bool DOMMessageQueue::WaitForMessage(std::string* message) { |
bool DOMMessageQueue::PopMessage(std::string* message) { |
DCHECK(message); |
- if (message_queue_.empty()) |
+ if (renderer_crashed_ || message_queue_.empty()) |
return false; |
*message = message_queue_.front(); |
message_queue_.pop(); |