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 ec91284fda82f772e28cf9f8769ecf2e129d3a40..4eeae684e4cfc3b7379916637fb8300b205e378b 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" |
@@ -413,19 +415,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"; |
@@ -816,10 +817,25 @@ 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); |
+ // TODO(lukasza): ExecuteScript should just call |
+ // ExecuteJavaScriptWithUserGestureForTests and avoid modifying the original |
+ // script (and at that point we should merge it with and remove |
+ // ExecuteUnmodifiedScript). 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::string actual_response; |
+ if (!ExecuteScriptAndExtractString(adapter, new_script, &actual_response)) |
+ return false; |
+ DCHECK_EQ(expected_response, actual_response); |
+ |
+ return true; |
} |
bool ExecuteScriptWithoutUserGesture(const ToRenderFrameHost& adapter, |
@@ -829,6 +845,12 @@ bool ExecuteScriptWithoutUserGesture(const ToRenderFrameHost& adapter, |
nullptr); |
} |
+void ExecuteUnmodifiedScript(const ToRenderFrameHost& adapter, |
+ const std::string& script) { |
+ adapter.render_frame_host()->ExecuteJavaScriptWithUserGestureForTests( |
+ base::UTF8ToUTF16(script)); |
+} |
+ |
bool ExecuteScriptAndExtractDouble(const ToRenderFrameHost& adapter, |
const std::string& script, double* result) { |
DCHECK(result); |
@@ -999,12 +1021,10 @@ bool ExecuteWebUIResourceTest(WebContents* web_contents, |
script.append("\n"); |
} |
- if (!ExecuteScript(web_contents, script)) |
- return false; |
+ ExecuteUnmodifiedScript(web_contents, script); |
DOMMessageQueue message_queue; |
- if (!ExecuteScript(web_contents, "runTests()")) |
- return false; |
+ ExecuteUnmodifiedScript(web_contents, "runTests()"); |
std::string message; |
do { |
@@ -1492,7 +1512,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(); |
} |
@@ -1503,6 +1523,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; |
@@ -1515,7 +1536,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); |
@@ -1526,7 +1547,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(); |