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 3 // found in the LICENSE file. 4 5 #ifndef CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_ 6 #define CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_ 7 8 #include <memory> 9 #include <string> 10 #include <utility> 11 #include <vector> 12 13 #include "base/callback.h" 14 #include "base/compiler_specific.h" 15 #include "base/containers/flat_set.h" 16 #include "base/containers/queue.h" 17 #include "base/files/scoped_temp_dir.h" 18 #include "base/json/json_writer.h" 19 #include "base/macros.h" 20 #include "base/memory/ref_counted.h" 21 #include "base/memory/weak_ptr.h" 22 #include "base/optional.h" 23 #include "base/process/process.h" 24 #include "base/run_loop.h" 25 #include "base/strings/string16.h" 26 #include "base/test/metrics/histogram_tester.h" 27 #include "build/build_config.h" 28 #include "cc/test/pixel_test_utils.h" 29 #include "components/viz/common/quads/compositor_frame.h" 30 #include "content/public/browser/browser_message_filter.h" 31 #include "content/public/browser/notification_observer.h" 32 #include "content/public/browser/notification_registrar.h" 33 #include "content/public/browser/render_frame_metadata_provider.h" 34 #include "content/public/browser/render_process_host_observer.h" 35 #include "content/public/browser/render_widget_host.h" 36 #include "content/public/browser/web_contents_delegate.h" 37 #include "content/public/browser/web_contents_observer.h" 38 #include "content/public/common/content_switches.h" 39 #include "content/public/common/isolated_world_ids.h" 40 #include "content/public/common/page_type.h" 41 #include "content/public/common/untrustworthy_context_menu_params.h" 42 #include "content/public/test/fake_frame_widget.h" 43 #include "ipc/message_filter.h" 44 #include "net/base/load_flags.h" 45 #include "services/network/public/mojom/network_service.mojom.h" 46 #include "storage/common/file_system/file_system_types.h" 47 #include "testing/gtest/include/gtest/gtest.h" 48 #include "third_party/blink/public/common/input/web_input_event.h" 49 #include "third_party/blink/public/common/input/web_mouse_event.h" 50 #include "third_party/blink/public/common/input/web_mouse_wheel_event.h" 51 #include "third_party/blink/public/mojom/frame/frame.mojom-test-utils.h" 52 #include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" 53 #include "ui/accessibility/ax_node_data.h" 54 #include "ui/accessibility/ax_tree_update.h" 55 #include "ui/display/display_switches.h" 56 #include "ui/events/keycodes/dom/dom_code.h" 57 #include "ui/events/keycodes/dom/dom_key.h" 58 #include "ui/events/keycodes/keyboard_codes.h" 59 #include "ui/events/types/event_type.h" 60 #include "url/gurl.h" 61 62 #if defined(OS_WIN) 63 #include "base/win/scoped_handle.h" 64 #endif 65 66 namespace gfx { 67 class Point; 68 } 69 70 namespace net { 71 class CanonicalCookie; 72 namespace test_server { 73 class EmbeddedTestServer; 74 } 75 // TODO(svaldez): Remove typedef once EmbeddedTestServer has been migrated 76 // out of net::test_server. 77 using test_server::EmbeddedTestServer; 78 } 79 80 namespace ui { 81 class AXPlatformNodeDelegate; 82 } 83 84 #if defined(OS_WIN) 85 namespace Microsoft { 86 namespace WRL { 87 template <typename> 88 class ComPtr; 89 } // namespace WRL 90 } // namespace Microsoft 91 92 typedef int PROPERTYID; 93 #endif 94 95 // A collections of functions designed for use with content_browsertests and 96 // browser_tests. 97 // TO BE CLEAR: any function here must work against both binaries. If it only 98 // works with browser_tests, it should be in chrome\test\base\ui_test_utils.h. 99 // If it only works with content_browsertests, it should be in 100 // content\test\content_browser_test_utils.h. 101 102 namespace blink { 103 struct FrameVisualProperties; 104 } 105 106 namespace content { 107 108 class BrowserContext; 109 class FrameTreeNode; 110 class NavigationHandle; 111 class NavigationRequest; 112 class RenderFrameMetadataProviderImpl; 113 class RenderFrameProxyHost; 114 class RenderWidgetHost; 115 class RenderWidgetHostView; 116 class ScopedAllowRendererCrashes; 117 class ToRenderFrameHost; 118 class WebContents; 119 120 // Navigates |web_contents| to |url|, blocking until the navigation finishes. 121 // Returns true if the page was loaded successfully and the last committed URL 122 // matches |url|. This is a browser-initiated navigation that simulates a user 123 // typing |url| into the address bar. 124 WARN_UNUSED_RESULT bool NavigateToURL(WebContents* web_contents, 125 const GURL& url); 126 127 // Same as above, but takes in an additional URL, |expected_commit_url|, to 128 // which the navigation should eventually commit. This is useful for cases 129 // like redirects, where navigation starts on one URL but ends up committing a 130 // different URL. This function will return true if navigating to |url| 131 // results in a successful commit to |expected_commit_url|. 132 WARN_UNUSED_RESULT bool NavigateToURL(WebContents* web_contents, 133 const GURL& url, 134 const GURL& expected_commit_url); 135 136 // Navigates |web_contents| to |url|, blocking until the given number of 137 // navigations finishes. 138 void NavigateToURLBlockUntilNavigationsComplete(WebContents* web_contents, 139 const GURL& url, 140 int number_of_navigations); 141 142 // Perform a renderer-initiated navigation of |window| to |url|, blocking 143 // until the navigation finishes. The navigation is done by assigning 144 // location.href in the frame |adapter|. Returns true if the page was loaded 145 // successfully and the last committed URL matches |url|. 146 WARN_UNUSED_RESULT bool NavigateToURLFromRenderer( 147 const ToRenderFrameHost& adapter, 148 const GURL& url); 149 // Similar to above but takes in an additional URL, |expected_commit_url|, to 150 // which the navigation should eventually commit. (See the browser-initiated 151 // counterpart for more details). 152 WARN_UNUSED_RESULT bool NavigateToURLFromRenderer( 153 const ToRenderFrameHost& adapter, 154 const GURL& url, 155 const GURL& expected_commit_url); 156 WARN_UNUSED_RESULT bool NavigateToURLFromRendererWithoutUserGesture( 157 const ToRenderFrameHost& adapter, 158 const GURL& url); 159 160 // Navigate a frame with ID |iframe_id| to |url|, blocking until the navigation 161 // finishes. Uses a renderer-initiated navigation from script code in the 162 // main frame. 163 bool NavigateIframeToURL(WebContents* web_contents, 164 const std::string& iframe_id, 165 const GURL& url); 166 167 // Similar to |NavigateIframeToURL()| but returns as soon as the navigation is 168 // initiated. 169 bool BeginNavigateIframeToURL(WebContents* web_contents, 170 const std::string& iframe_id, 171 const GURL& url); 172 173 // Generate a URL for a file path including a query string. 174 GURL GetFileUrlWithQuery(const base::FilePath& path, 175 const std::string& query_string); 176 177 // Checks whether the page type of the last committed navigation entry matches 178 // |page_type|. 179 bool IsLastCommittedEntryOfPageType(WebContents* web_contents, 180 content::PageType page_type); 181 182 // Waits for |web_contents| to stop loading. If |web_contents| is not loading 183 // returns immediately. Tests should use WaitForLoadStop instead and check that 184 // last navigation succeeds, and this function should only be used if the 185 // navigation leads to web_contents being destroyed. 186 void WaitForLoadStopWithoutSuccessCheck(WebContents* web_contents); 187 188 // Waits for |web_contents| to stop loading. If |web_contents| is not loading 189 // returns immediately. Returns true if the last navigation succeeded (resulted 190 // in a committed navigation entry of type PAGE_TYPE_NORMAL). 191 // TODO(alexmos): tests that use this function to wait for successful 192 // navigations should be refactored to do EXPECT_TRUE(WaitForLoadStop()). 193 bool WaitForLoadStop(WebContents* web_contents); 194 195 // If a test uses a beforeunload dialog, it must be prepared to avoid flakes. 196 // This function collects everything that needs to be done, except for user 197 // activation which is triggered only when |trigger_user_activation| is true. 198 // Note that beforeunload dialog attempts are ignored unless the frame has 199 // received a user activation. 200 void PrepContentsForBeforeUnloadTest(WebContents* web_contents, 201 bool trigger_user_activation = true); 202 203 #if defined(USE_AURA) || defined(OS_ANDROID) 204 // If WebContent's view is currently being resized, this will wait for the ack 205 // from the renderer that the resize is complete and for the 206 // WindowEventDispatcher to release the pointer moves. If there's no resize in 207 // progress, the method will return right away. 208 void WaitForResizeComplete(WebContents* web_contents); 209 #endif // defined(USE_AURA) || defined(OS_ANDROID) 210 211 // Allows tests to set the last committed origin of |render_frame_host|, to 212 // simulate a scenario that might happen with a compromised renderer or might 213 // not otherwise be possible. 214 void OverrideLastCommittedOrigin(RenderFrameHost* render_frame_host, 215 const url::Origin& origin); 216 217 // Causes the specified web_contents to crash. Blocks until it is crashed. 218 void CrashTab(WebContents* web_contents); 219 220 // Sets up a commit interceptor to alter commits for |target_url| to change 221 // their commit URL to |new_url| and origin to |new_origin|. This will happen 222 // for all commits in |web_contents|. 223 void PwnCommitIPC(WebContents* web_contents, 224 const GURL& target_url, 225 const GURL& new_url, 226 const url::Origin& new_origin); 227 228 // Causes the specified web_contents to issue an OnUnresponsiveRenderer event 229 // to its observers. 230 void SimulateUnresponsiveRenderer(WebContents* web_contents, 231 RenderWidgetHost* widget); 232 233 // Simulates clicking at the center of the given tab asynchronously; modifiers 234 // may contain bits from WebInputEvent::Modifiers. Sends the event through 235 // RenderWidgetHostInputEventRouter and thus can target OOPIFs. 236 void SimulateMouseClick(WebContents* web_contents, 237 int modifiers, 238 blink::WebMouseEvent::Button button); 239 240 // Simulates clicking at the point |point| of the given tab asynchronously; 241 // modifiers may contain bits from WebInputEvent::Modifiers. Sends the event 242 // through RenderWidgetHostInputEventRouter and thus can target OOPIFs. 243 void SimulateMouseClickAt(WebContents* web_contents, 244 int modifiers, 245 blink::WebMouseEvent::Button button, 246 const gfx::Point& point); 247 248 // Retrieves the center coordinates of the element with id |id| and simulates a 249 // mouse click there using SimulateMouseClickAt(). 250 void SimulateMouseClickOrTapElementWithId(content::WebContents* web_contents, 251 const std::string& id); 252 253 // Simulates MouseDown at the center of the given RenderWidgetHost's area. 254 // This does not send a corresponding MouseUp. 255 void SendMouseDownToWidget(RenderWidgetHost* target, 256 int modifiers, 257 blink::WebMouseEvent::Button button); 258 259 // Simulates asynchronously a mouse enter/move/leave event. The mouse event is 260 // routed through RenderWidgetHostInputEventRouter and thus can target OOPIFs. 261 void SimulateMouseEvent(WebContents* web_contents, 262 blink::WebInputEvent::Type type, 263 const gfx::Point& point); 264 void SimulateMouseEvent(WebContents* web_contents, 265 blink::WebInputEvent::Type type, 266 blink::WebMouseEvent::Button button, 267 const gfx::Point& point); 268 269 // Simulate a mouse wheel event. 270 void SimulateMouseWheelEvent(WebContents* web_contents, 271 const gfx::Point& point, 272 const gfx::Vector2d& delta, 273 const blink::WebMouseWheelEvent::Phase phase); 274 275 #if !defined(OS_MAC) 276 // Simulate a mouse wheel event with the ctrl modifier set. 277 void SimulateMouseWheelCtrlZoomEvent(WebContents* web_contents, 278 const gfx::Point& point, 279 bool zoom_in, 280 blink::WebMouseWheelEvent::Phase phase); 281 282 void SimulateTouchscreenPinch(WebContents* web_contents, 283 const gfx::PointF& anchor, 284 float scale_change, 285 base::OnceClosure on_complete); 286 287 #endif // !defined(OS_MAC) 288 289 // Sends a GesturePinch Begin/Update/End sequence. 290 void SimulateGesturePinchSequence(WebContents* web_contents, 291 const gfx::Point& point, 292 float scale, 293 blink::WebGestureDevice source_device); 294 295 // Sends a simple, three-event (Begin/Update/End) gesture scroll. 296 void SimulateGestureScrollSequence(WebContents* web_contents, 297 const gfx::Point& point, 298 const gfx::Vector2dF& delta); 299 300 void SimulateGestureFlingSequence(WebContents* web_contents, 301 const gfx::Point& point, 302 const gfx::Vector2dF& velocity); 303 304 void SimulateGestureEvent(WebContents* web_contents, 305 const blink::WebGestureEvent& gesture_event, 306 const ui::LatencyInfo& latency); 307 308 // Taps the screen at |point|, using gesture Tap or TapDown. 309 void SimulateTapAt(WebContents* web_contents, const gfx::Point& point); 310 void SimulateTapDownAt(WebContents* web_contents, const gfx::Point& point); 311 312 // A helper function for SimulateTap(Down)At. 313 void SimulateTouchGestureAt(WebContents* web_contents, 314 const gfx::Point& point, 315 blink::WebInputEvent::Type type); 316 317 #if defined(USE_AURA) 318 // Generates a TouchEvent of |event_type| at |point|. 319 void SimulateTouchEventAt(WebContents* web_contents, 320 ui::EventType event_type, 321 const gfx::Point& point); 322 323 void SimulateLongTapAt(WebContents* web_contents, const gfx::Point& point); 324 #endif 325 326 // Taps the screen with modifires at |point|. 327 void SimulateTapWithModifiersAt(WebContents* web_contents, 328 unsigned Modifiers, 329 const gfx::Point& point); 330 331 // Sends a key press asynchronously. 332 // |key| specifies the UIEvents (aka: DOM4Events) value of the key. 333 // |code| specifies the UIEvents (aka: DOM4Events) value of the physical key. 334 // |key_code| alone is good enough for scenarios that only need the char 335 // value represented by a key event and not the physical key on the keyboard 336 // or the keyboard layout. 337 // If set to true, the modifiers |control|, |shift|, |alt|, and |command| are 338 // pressed down first before the key event, and released after. 339 void SimulateKeyPress(WebContents* web_contents, 340 ui::DomKey key, 341 ui::DomCode code, 342 ui::KeyboardCode key_code, 343 bool control, 344 bool shift, 345 bool alt, 346 bool command); 347 348 // Like SimulateKeyPress(), but does not send the char (AKA keypress) event. 349 // This is useful for arrow keys and other key presses that do not generate 350 // characters. 351 void SimulateKeyPressWithoutChar(WebContents* web_contents, 352 ui::DomKey key, 353 ui::DomCode code, 354 ui::KeyboardCode key_code, 355 bool control, 356 bool shift, 357 bool alt, 358 bool command); 359 360 // Reset touch action for the embedder of a BrowserPluginGuest. 361 void ResetTouchAction(RenderWidgetHost* host); 362 363 // Requests mouse lock on the implementation of the given RenderWidgetHost 364 void RequestMouseLock(RenderWidgetHost* host, 365 bool user_gesture, 366 bool request_unadjusted_movement); 367 368 // Spins a run loop until effects of previously forwarded input are fully 369 // realized. 370 void RunUntilInputProcessed(RenderWidgetHost* host); 371 372 // Returns a string representation of a given |referrer_policy|. This is used to 373 // setup <meta name=referrer> tags in documents used for referrer-policy-based 374 // tests. The value `no-meta` indicates no tag should be created. 375 std::string ReferrerPolicyToString( 376 network::mojom::ReferrerPolicy referrer_policy); 377 378 // For testing, bind FakeFrameWidget to a RenderWidgetHost associated 379 // with a given RenderFrameHost 380 mojo::PendingAssociatedReceiver<blink::mojom::FrameWidget> 381 BindFakeFrameWidgetInterfaces(RenderFrameHost* frame); 382 383 // Set |active| state for a RenderWidgetHost associated with a given 384 // RenderFrameHost 385 void SimulateActiveStateForWidget(RenderFrameHost* frame, bool active); 386 387 // Holds down modifier keys for the duration of its lifetime and releases them 388 // upon destruction. This allows simulating multiple input events without 389 // simulating modifier key releases in between. 390 class ScopedSimulateModifierKeyPress { 391 public: 392 ScopedSimulateModifierKeyPress(WebContents* web_contents, 393 bool control, 394 bool shift, 395 bool alt, 396 bool command); 397 ~ScopedSimulateModifierKeyPress(); 398 399 // Similar to SimulateMouseClickAt(). 400 void MouseClickAt(int additional_modifiers, 401 blink::WebMouseEvent::Button button, 402 const gfx::Point& point); 403 404 // Similar to SimulateKeyPress(). 405 void KeyPress(ui::DomKey key, ui::DomCode code, ui::KeyboardCode key_code); 406 407 // Similar to SimulateKeyPressWithoutChar(). 408 void KeyPressWithoutChar(ui::DomKey key, 409 ui::DomCode code, 410 ui::KeyboardCode key_code); 411 412 private: 413 WebContents* const web_contents_; 414 int modifiers_; 415 const bool control_; 416 const bool shift_; 417 const bool alt_; 418 const bool command_; 419 420 DISALLOW_COPY_AND_ASSIGN(ScopedSimulateModifierKeyPress); 421 }; 422 423 // Method to check what devices we have on the system. 424 bool IsWebcamAvailableOnSystem(WebContents* web_contents); 425 426 // Allow ExecuteScript* methods to target either a WebContents or a 427 // RenderFrameHost. Targeting a WebContents means executing the script in the 428 // RenderFrameHost returned by WebContents::GetMainFrame(), which is the main 429 // frame. Pass a specific RenderFrameHost to target it. Embedders may declare 430 // additional ConvertToRenderFrameHost functions for convenience. 431 class ToRenderFrameHost { 432 public: 433 template <typename T> ToRenderFrameHost(T * frame_convertible_value)434 ToRenderFrameHost(T* frame_convertible_value) 435 : render_frame_host_(ConvertToRenderFrameHost(frame_convertible_value)) {} 436 437 // Extract the underlying frame. render_frame_host()438 RenderFrameHost* render_frame_host() const { return render_frame_host_; } 439 440 private: 441 RenderFrameHost* render_frame_host_; 442 }; 443 444 RenderFrameHost* ConvertToRenderFrameHost(RenderFrameHost* render_view_host); 445 RenderFrameHost* ConvertToRenderFrameHost(WebContents* web_contents); 446 447 // Semi-deprecated: in new code, prefer ExecJs() -- it works the same, but has 448 // better error handling. (Note: still use ExecuteScript() on pages with a 449 // Content Security Policy). 450 // 451 // Executes the passed |script| in the specified frame with the user gesture. 452 // 453 // Appends |domAutomationController.send(...)| to the end of |script| and waits 454 // until the response comes back (pumping the message loop while waiting). The 455 // |script| itself should not invoke domAutomationController.send(); if you want 456 // to call domAutomationController.send(...) yourself and extract the result, 457 // then use one of ExecuteScriptAndExtract... functions). 458 // 459 // Returns true on success (if the renderer responded back with the expected 460 // value). Returns false otherwise (e.g. if the script threw an exception 461 // before calling the appended |domAutomationController.send(...)|, or if the 462 // renderer died or if the renderer called |domAutomationController.send(...)| 463 // with a malformed or unexpected value). 464 // 465 // See also: 466 // - ExecJs (preferred replacement with better errror handling) 467 // - EvalJs (if you want to retrieve a value) 468 // - ExecuteScriptAsync (if you don't want to block for |script| completion) 469 // - DOMMessageQueue (to manually wait for domAutomationController.send(...)) 470 bool ExecuteScript(const ToRenderFrameHost& adapter, 471 const std::string& script) WARN_UNUSED_RESULT; 472 473 // Same as content::ExecuteScript but doesn't send a user gesture to the 474 // renderer. 475 bool ExecuteScriptWithoutUserGesture(const ToRenderFrameHost& adapter, 476 const std::string& script) 477 WARN_UNUSED_RESULT; 478 479 // Similar to ExecuteScript above, but 480 // - Doesn't modify the |script|. 481 // - Kicks off execution of the |script| in the specified frame and returns 482 // immediately (without waiting for a response from the renderer and/or 483 // without checking that the script succeeded). 484 void ExecuteScriptAsync(const ToRenderFrameHost& adapter, 485 const std::string& script); 486 487 // The following methods execute the passed |script| in the specified frame and 488 // sets |result| to the value passed to "window.domAutomationController.send" by 489 // the executed script. They return true on success, false if the script 490 // execution failed or did not evaluate to the expected type. 491 // 492 // Semi-deprecated: Consider using EvalJs() or EvalJsWithManualReply() instead, 493 // which handle errors better and don't require an out-param. If the target 494 // document doesn't have a CSP. See the comment on EvalJs() for migration tips. 495 bool ExecuteScriptAndExtractDouble(const ToRenderFrameHost& adapter, 496 const std::string& script, 497 double* result) WARN_UNUSED_RESULT; 498 bool ExecuteScriptAndExtractInt(const ToRenderFrameHost& adapter, 499 const std::string& script, 500 int* result) WARN_UNUSED_RESULT; 501 bool ExecuteScriptAndExtractBool(const ToRenderFrameHost& adapter, 502 const std::string& script, 503 bool* result) WARN_UNUSED_RESULT; 504 bool ExecuteScriptAndExtractString(const ToRenderFrameHost& adapter, 505 const std::string& script, 506 std::string* result) WARN_UNUSED_RESULT; 507 508 // Same as above but the script executed without user gesture. 509 bool ExecuteScriptWithoutUserGestureAndExtractDouble( 510 const ToRenderFrameHost& adapter, 511 const std::string& script, 512 double* result) WARN_UNUSED_RESULT; 513 bool ExecuteScriptWithoutUserGestureAndExtractInt( 514 const ToRenderFrameHost& adapter, 515 const std::string& script, 516 int* result) WARN_UNUSED_RESULT; 517 bool ExecuteScriptWithoutUserGestureAndExtractBool( 518 const ToRenderFrameHost& adapter, 519 const std::string& script, 520 bool* result) WARN_UNUSED_RESULT; 521 bool ExecuteScriptWithoutUserGestureAndExtractString( 522 const ToRenderFrameHost& adapter, 523 const std::string& script, 524 std::string* result) WARN_UNUSED_RESULT; 525 526 // JsLiteralHelper is a helper class that determines what types are legal to 527 // pass to StringifyJsLiteral. Legal types include int, string, StringPiece, 528 // char*, bool, double, GURL, url::Origin, and base::Value&&. 529 template <typename T> 530 struct JsLiteralHelper { 531 // This generic version enables passing any type from which base::Value can be 532 // instantiated. This covers int, string, double, bool, base::Value&&, etc. 533 template <typename U> ConvertJsLiteralHelper534 static base::Value Convert(U&& arg) { 535 return base::Value(std::forward<U>(arg)); 536 } 537 ConvertJsLiteralHelper538 static base::Value Convert(const base::Value& value) { 539 return value.Clone(); 540 } 541 ConvertJsLiteralHelper542 static base::Value Convert(const base::ListValue& value) { 543 return value.Clone(); 544 } 545 }; 546 547 // Specialization allowing GURL to be passed to StringifyJsLiteral. 548 template <> 549 struct JsLiteralHelper<GURL> { 550 static base::Value Convert(const GURL& url) { 551 return base::Value(url.spec()); 552 } 553 }; 554 555 // Specialization allowing url::Origin to be passed to StringifyJsLiteral. 556 template <> 557 struct JsLiteralHelper<url::Origin> { 558 static base::Value Convert(const url::Origin& url) { 559 return base::Value(url.Serialize()); 560 } 561 }; 562 563 // Helper for variadic ListValueOf() -- zero-argument base case. 564 inline void ConvertToBaseValueList(base::Value::ListStorage* list) {} 565 566 // Helper for variadic ListValueOf() -- case with at least one argument. 567 // 568 // |first| can be any type explicitly convertible to base::Value 569 // (including int/string/StringPiece/char*/double/bool), or any type that 570 // JsLiteralHelper is specialized for -- like URL and url::Origin, which emit 571 // string literals. 572 template <typename T, typename... Args> 573 void ConvertToBaseValueList(base::Value::ListStorage* list, 574 T&& first, 575 Args&&... rest) { 576 using ValueType = std::remove_cv_t<std::remove_reference_t<T>>; 577 list->push_back(JsLiteralHelper<ValueType>::Convert(std::forward<T>(first))); 578 ConvertToBaseValueList(list, std::forward<Args>(rest)...); 579 } 580 581 // Construct a list-type base::Value from a mix of arguments. 582 // 583 // Each |arg| can be any type explicitly convertible to base::Value 584 // (including int/string/StringPiece/char*/double/bool), or any type that 585 // JsLiteralHelper is specialized for -- like URL and url::Origin, which emit 586 // string literals. |args| can be a mix of different types. 587 template <typename... Args> 588 base::ListValue ListValueOf(Args&&... args) { 589 base::Value::ListStorage values; 590 ConvertToBaseValueList(&values, std::forward<Args>(args)...); 591 return base::ListValue(std::move(values)); 592 } 593 594 // Replaces $1, $2, $3, etc in |script_template| with JS literal values 595 // constructed from |args|, similar to base::ReplaceStringPlaceholders. 596 // 597 // Unlike StringPrintf or manual concatenation, this version will properly 598 // escape string content, even if it contains slashes or quotation marks. 599 // 600 // Each |arg| can be any type explicitly convertible to base::Value 601 // (including int/string/StringPiece/char*/double/bool), or any type that 602 // JsLiteralHelper is specialized for -- like URL and url::Origin, which emit 603 // string literals. |args| can be a mix of different types. 604 // 605 // Example 1: 606 // 607 // GURL page_url("http://example.com"); 608 // EXPECT_TRUE(ExecuteScript( 609 // shell(), JsReplace("window.open($1, '_blank');", page_url))); 610 // 611 // $1 is replaced with a double-quoted JS string literal: 612 // "http://example.com". Note that quotes around $1 are not required. 613 // 614 // Example 2: 615 // 616 // bool forced_reload = true; 617 // EXPECT_TRUE(ExecuteScript( 618 // shell(), JsReplace("window.location.reload($1);", forced_reload))); 619 // 620 // This becomes "window.location.reload(true);" -- because bool values are 621 // supported by base::Value. Numbers, lists, and dicts also work. 622 template <typename... Args> 623 std::string JsReplace(base::StringPiece script_template, Args&&... args) { 624 base::Value::ListStorage values; 625 ConvertToBaseValueList(&values, std::forward<Args>(args)...); 626 std::vector<std::string> replacements(values.size()); 627 for (size_t i = 0; i < values.size(); ++i) { 628 CHECK(base::JSONWriter::Write(values[i], &replacements[i])); 629 } 630 return base::ReplaceStringPlaceholders(script_template, replacements, 631 nullptr); 632 } 633 634 // The return value of EvalJs. Captures the value (or the error) arising from 635 // script execution. When used with gtest assertions, EvalJsResult generally 636 // behaves like its wrapped value. 637 // 638 // An EvalJsResult can be consumed in two ways: 639 // 640 // (1) [preferred] Pass it directly to an EXPECT_EQ() macro. It has 641 // overloaded operator== against std::string, bool, int, double, 642 // nullptr_t, and base::Value. This will produce readable assertion 643 // failures if there is a type mismatch, or if an exception was thrown -- 644 // errors are never equal to anything. 645 // 646 // For boolean results, note that EXPECT_TRUE(..) and EXPECT_FALSE() 647 // won't compile; use EXPECT_EQ(true, ...) instead. This is intentional, 648 // since EXPECT_TRUE() could be read ambiguously as either "expect 649 // successful execution", "expect truthy value of any type", or "expect 650 // boolean value 'true'". 651 // 652 // (2) [use when necessary] Extract the underlying value of an expected type, 653 // by calling ExtractString(), ExtractInt(), etc. This will produce a 654 // CHECK failure if the execution didn't result in the appropriate type 655 // of result, or if an exception was thrown. 656 struct EvalJsResult { 657 const base::Value value; // Value; if things went well. 658 const std::string error; // Error; if things went badly. 659 660 // Creates an ExecuteScript result. If |error| is non-empty, |value| will be 661 // ignored. 662 EvalJsResult(base::Value value, const std::string& error); 663 664 // Copy ctor. 665 EvalJsResult(const EvalJsResult& value); 666 667 // Extract a result value of the requested type, or die trying. 668 // 669 // If there was an error, or if returned value is of a different type, these 670 // will fail with a CHECK. Use Extract methods only when accessing the 671 // result value is necessary; prefer operator== and EXPECT_EQ() instead: 672 // they don't CHECK, and give better error messages. 673 const std::string& ExtractString() const WARN_UNUSED_RESULT; 674 int ExtractInt() const WARN_UNUSED_RESULT; 675 bool ExtractBool() const WARN_UNUSED_RESULT; 676 double ExtractDouble() const WARN_UNUSED_RESULT; 677 base::ListValue ExtractList() const WARN_UNUSED_RESULT; 678 }; 679 680 // Enables EvalJsResult to be used directly in ASSERT/EXPECT macros: 681 // 682 // ASSERT_EQ("ab", EvalJs(rfh, "'a' + 'b'")) 683 // ASSERT_EQ(2, EvalJs(rfh, "1 + 1")) 684 // ASSERT_EQ(nullptr, EvalJs(rfh, "var a = 1 + 1")) 685 // 686 // Error values never return true for any comparison operator. 687 template <typename T> 688 bool operator==(const T& a, const EvalJsResult& b) { 689 return b.error.empty() && (JsLiteralHelper<T>::Convert(a) == b.value); 690 } 691 692 template <typename T> 693 bool operator!=(const T& a, const EvalJsResult& b) { 694 return b.error.empty() && (JsLiteralHelper<T>::Convert(a) != b.value); 695 } 696 697 template <typename T> 698 bool operator>=(const T& a, const EvalJsResult& b) { 699 return b.error.empty() && (JsLiteralHelper<T>::Convert(a) >= b.value); 700 } 701 702 template <typename T> 703 bool operator<=(const T& a, const EvalJsResult& b) { 704 return b.error.empty() && (JsLiteralHelper<T>::Convert(a) <= b.value); 705 } 706 707 template <typename T> 708 bool operator<(const T& a, const EvalJsResult& b) { 709 return b.error.empty() && (JsLiteralHelper<T>::Convert(a) < b.value); 710 } 711 712 template <typename T> 713 bool operator>(const T& a, const EvalJsResult& b) { 714 return b.error.empty() && (JsLiteralHelper<T>::Convert(a) > b.value); 715 } 716 717 inline bool operator==(std::nullptr_t a, const EvalJsResult& b) { 718 return b.error.empty() && (base::Value() == b.value); 719 } 720 721 // Provides informative failure messages when the result of EvalJs() is 722 // used in a failing ASSERT_EQ or EXPECT_EQ. 723 void PrintTo(const EvalJsResult& bar, ::std::ostream* os); 724 725 enum EvalJsOptions { 726 EXECUTE_SCRIPT_DEFAULT_OPTIONS = 0, 727 728 // By default, EvalJs runs with a user gesture. This bit flag disables 729 // that. 730 EXECUTE_SCRIPT_NO_USER_GESTURE = (1 << 0), 731 732 // This bit controls how the result is obtained. By default, EvalJs's runner 733 // script will call domAutomationController.send() with the completion 734 // value. Setting this bit will disable that, requiring |script| to provide 735 // its own call to domAutomationController.send() instead. 736 EXECUTE_SCRIPT_USE_MANUAL_REPLY = (1 << 1), 737 738 // By default, when the script passed to EvalJs evaluates to a Promise, the 739 // execution continues until the Promise resolves, and the resolved value is 740 // returned. Setting this bit disables such Promise resolution. 741 EXECUTE_SCRIPT_NO_RESOLVE_PROMISES = (1 << 2), 742 }; 743 744 // EvalJs() -- run |script| in |execution_target| and return its value or error. 745 // 746 // Example simple usage: 747 // 748 // EXPECT_EQ("https://abcd.com", EvalJs(render_frame_host, "self.origin")); 749 // EXPECT_EQ(5, EvalJs(render_frame_host, "history.length")); 750 // EXPECT_EQ(false, EvalJs(render_frame_host, "history.length > 5")); 751 // 752 // The result value of |script| is its "statement completion value" -- the same 753 // semantics used by Javascript's own eval() function. If |script| 754 // raises exceptions, or is syntactically invalid, an error is captured instead, 755 // including a full stack trace. 756 // 757 // The return value of EvalJs() may be used directly in EXPECT_EQ() 758 // macros, and compared for against std::string, int, or any other type for 759 // which base::Value has a constructor. If an error was thrown by the script, 760 // any comparison operators will always return false. 761 // 762 // If |script|'s captured completion value is a Promise, this function blocks 763 // until the Promise is resolved. This enables a usage pattern where |script| 764 // may call an async function, and use the await keyword to wait for 765 // events to fire. For example: 766 // 767 // EXPECT_EQ(200, EvalJs(rfh, "(async () => { var resp = (await fetch(url));" 768 // " return resp.status; })()"); 769 // 770 // In the above example, the immediately-invoked function expression results in 771 // a Promise (that's what async functions do); EvalJs will continue blocking 772 // until the Promise resolves, which happens when the async function returns 773 // the HTTP status code -- which is expected, in this case, to be 200. 774 // 775 // Quick migration guide for users of the classic ExecuteScriptAndExtract*(): 776 // - If your page has a Content SecurityPolicy, don't migrate [yet]; CSP can 777 // interfere with the internal mechanism used here. 778 // - Get rid of the out-param. You call EvalJs no matter what your return 779 // type is. 780 // - If possible, pass the result of EvalJs() into the second argument of an 781 // EXPECT_EQ macro. This will trigger failure (and a nice message) if an 782 // error occurs. 783 // - Eliminate calls to domAutomationController.send() in |script|. In simple 784 // cases, |script| is just an expression you want the value of. 785 // - When a script previously installed a callback or event listener that 786 // invoked domAutomationController.send(x) asynchronously, there is a choice: 787 // * Preferred, but more rewriting: Use EvalJs with a Promise which 788 // resolves to the value you previously passed to send(). 789 // * Less rewriting of |script|, but with some drawbacks: Use 790 // EXECUTE_SCRIPT_USE_MANUAL_REPLY in |options|, or EvalJsWithManualReply. 791 // When specified, this means that |script| must continue to call 792 // domAutomationController.send(). Note that this option option disables 793 // some error-catching safeguards, but you still get the benefit of having 794 // an EvalJsResult that can be passed to EXPECT. 795 // 796 // Why prefer EvalJs over ExecuteScriptAndExtractString(), etc? Because: 797 // 798 // - It's one function, that does everything, and more succinctly. 799 // - Can be used directly in EXPECT_EQ macros (no out- param pointers like 800 // ExecuteScriptAndExtractBool()) -- no temporary variable is required, 801 // usually resulting in fewer lines of code. 802 // - JS exceptions are reliably captured and will appear as C++ assertion 803 // failures. 804 // - JS stack traces arising from exceptions are annotated with the 805 // corresponding source code; this also appears in C++ assertion failures. 806 // - Delayed response is supported via Promises and JS async/await. 807 // - |script| doesn't need to call domAutomationController.send directly. 808 // - When a script doesn't produce a result, it's likely an assertion 809 // failure rather than a hang. Doesn't get confused by crosstalk with 810 // other callers of domAutomationController.send() -- script results carry 811 // a GUID. 812 // - Lists, dicts, null values, etc. can be returned as base::Values. 813 // 814 // It is guaranteed that EvalJs works even when the target frame is frozen. 815 EvalJsResult EvalJs(const ToRenderFrameHost& execution_target, 816 const std::string& script, 817 int options = EXECUTE_SCRIPT_DEFAULT_OPTIONS, 818 int32_t world_id = ISOLATED_WORLD_ID_GLOBAL) 819 WARN_UNUSED_RESULT; 820 821 // Like EvalJs(), except that |script| must call domAutomationController.send() 822 // itself. This is the same as specifying the EXECUTE_SCRIPT_USE_MANUAL_REPLY 823 // option to EvalJs. 824 EvalJsResult EvalJsWithManualReply(const ToRenderFrameHost& execution_target, 825 const std::string& script, 826 int options = EXECUTE_SCRIPT_DEFAULT_OPTIONS, 827 int32_t world_id = ISOLATED_WORLD_ID_GLOBAL) 828 WARN_UNUSED_RESULT; 829 830 // Like EvalJs(), but runs |raf_script| inside a requestAnimationFrame handler, 831 // and runs |script| after the rendering update has completed. By the time 832 // this method returns, any IPCs sent from the renderer process to the browser 833 // process during the lifecycle update should already have been received and 834 // processed by the browser. 835 EvalJsResult EvalJsAfterLifecycleUpdate( 836 const ToRenderFrameHost& execution_target, 837 const std::string& raf_script, 838 const std::string& script, 839 int options = EXECUTE_SCRIPT_DEFAULT_OPTIONS, 840 int32_t world_id = ISOLATED_WORLD_ID_GLOBAL) WARN_UNUSED_RESULT; 841 842 // Run a script exactly the same as EvalJs(), but ignore the resulting value. 843 // 844 // Returns AssertionSuccess() if |script| ran successfully, and 845 // AssertionFailure() if |script| contained a syntax error or threw an 846 // exception. 847 // 848 // Unlike ExecuteScript(), this catches syntax errors and uncaught exceptions, 849 // and gives more useful error messages when things go wrong. Prefer ExecJs to 850 // ExecuteScript(), unless your page has a CSP. 851 ::testing::AssertionResult ExecJs(const ToRenderFrameHost& execution_target, 852 const std::string& script, 853 int options = EXECUTE_SCRIPT_DEFAULT_OPTIONS, 854 int32_t world_id = ISOLATED_WORLD_ID_GLOBAL) 855 WARN_UNUSED_RESULT; 856 857 // Walks the frame tree of the specified WebContents and returns the sole 858 // frame that matches the specified predicate function. This function will 859 // DCHECK if no frames match the specified predicate, or if more than one 860 // frame matches. 861 RenderFrameHost* FrameMatchingPredicate( 862 WebContents* web_contents, 863 base::RepeatingCallback<bool(RenderFrameHost*)> predicate); 864 865 // Predicates for use with FrameMatchingPredicate. 866 bool FrameMatchesName(const std::string& name, RenderFrameHost* frame); 867 bool FrameIsChildOfMainFrame(RenderFrameHost* frame); 868 bool FrameHasSourceUrl(const GURL& url, RenderFrameHost* frame); 869 870 // Finds the child frame at the specified |index| for |frame| and returns its 871 // RenderFrameHost. Returns nullptr if such child frame does not exist. 872 RenderFrameHost* ChildFrameAt(RenderFrameHost* frame, size_t index); 873 874 // Executes the WebUI resource test runner injecting each resource ID in 875 // |js_resource_ids| prior to executing the tests. 876 // 877 // Returns true if tests ran successfully, false otherwise. 878 bool ExecuteWebUIResourceTest(WebContents* web_contents, 879 const std::vector<int>& js_resource_ids); 880 881 // Returns the serialized cookie string for the given url. Uses an inclusive 882 // SameSiteCookieContext by default, which gets cookies regardless of their 883 // SameSite attribute. 884 std::string GetCookies( 885 BrowserContext* browser_context, 886 const GURL& url, 887 net::CookieOptions::SameSiteCookieContext context = 888 net::CookieOptions::SameSiteCookieContext::MakeInclusive()); 889 890 // Returns the canonical cookies for the given url. 891 std::vector<net::CanonicalCookie> GetCanonicalCookies( 892 BrowserContext* browser_context, 893 const GURL& url); 894 895 // Sets a cookie for the given url. Uses an inclusive SameSiteCookieContext by 896 // default, which gets cookies regardless of their SameSite attribute. Returns 897 // true on success. 898 bool SetCookie(BrowserContext* browser_context, 899 const GURL& url, 900 const std::string& value, 901 net::CookieOptions::SameSiteCookieContext context = 902 net::CookieOptions::SameSiteCookieContext::MakeInclusive()); 903 904 // Fetch the histograms data from other processes. This should be called after 905 // the test code has been executed but before performing assertions. 906 void FetchHistogramsFromChildProcesses(); 907 908 // Registers a request handler which redirects to a different host, based 909 // on the request path. The format of the path should be 910 // "/cross-site/hostname/rest/of/path" to redirect the request to 911 // "<scheme>://hostname:<port>/rest/of/path", where <scheme> and <port> 912 // are the values for the instance of EmbeddedTestServer. 913 // 914 // By default, redirection will be done using HTTP 302 response, but in some 915 // cases (e.g. to preserve HTTP method and POST body across redirects as 916 // prescribed by https://tools.ietf.org/html/rfc7231#section-6.4.7) a test might 917 // want to use HTTP 307 response instead. This can be accomplished by replacing 918 // "/cross-site/" URL substring above with "/cross-site-307/". 919 // 920 // |embedded_test_server| should not be running when passing it to this function 921 // because adding the request handler won't be thread safe. 922 void SetupCrossSiteRedirector(net::EmbeddedTestServer* embedded_test_server); 923 924 // Waits until all resources have loaded in the given RenderFrameHost. 925 // When the load completes, this function sends a "pageLoadComplete" message 926 // via domAutomationController. The caller should make sure this extra 927 // message is handled properly. 928 bool WaitForRenderFrameReady(RenderFrameHost* rfh) WARN_UNUSED_RESULT; 929 930 // Removes the interface from the associated interface receiver sets attached to 931 // the WebContents. 932 void RemoveWebContentsReceiverSet(WebContents* web_contents, 933 const std::string& interface_name); 934 935 // Enable accessibility support for all of the frames in this WebContents 936 void EnableAccessibilityForWebContents(WebContents* web_contents); 937 938 // Wait until the focused accessible node changes in any WebContents. 939 void WaitForAccessibilityFocusChange(); 940 941 // Retrieve information about the node that's focused in the accessibility tree. 942 ui::AXNodeData GetFocusedAccessibilityNodeInfo(WebContents* web_contents); 943 944 // This is intended to be a robust way to assert that the accessibility 945 // tree eventually gets into the correct state, without worrying about 946 // the exact ordering of events received while getting there. Blocks 947 // until any change happens to the accessibility tree. 948 void WaitForAccessibilityTreeToChange(WebContents* web_contents); 949 950 // Searches the accessibility tree to see if any node's accessible name 951 // is equal to the given name. If not, repeatedly calls 952 // WaitForAccessibilityTreeToChange, above, and then checks again. 953 // Keeps looping until the text is found (or the test times out). 954 void WaitForAccessibilityTreeToContainNodeWithName(WebContents* web_contents, 955 const std::string& name); 956 957 // Get a snapshot of a web page's accessibility tree. 958 ui::AXTreeUpdate GetAccessibilityTreeSnapshot(WebContents* web_contents); 959 960 // Returns the root accessibility node for the given WebContents. 961 ui::AXPlatformNodeDelegate* GetRootAccessibilityNode(WebContents* web_contents); 962 963 // Finds an accessibility node matching the given criteria. 964 struct FindAccessibilityNodeCriteria { 965 FindAccessibilityNodeCriteria(); 966 ~FindAccessibilityNodeCriteria(); 967 base::Optional<ax::mojom::Role> role; 968 base::Optional<std::string> name; 969 }; 970 ui::AXPlatformNodeDelegate* FindAccessibilityNode( 971 WebContents* web_contents, 972 const FindAccessibilityNodeCriteria& criteria); 973 ui::AXPlatformNodeDelegate* FindAccessibilityNodeInSubtree( 974 ui::AXPlatformNodeDelegate* node, 975 const FindAccessibilityNodeCriteria& criteria); 976 977 #if defined(OS_WIN) 978 // Retrieve the specified interface from an accessibility node. 979 template <typename T> 980 Microsoft::WRL::ComPtr<T> QueryInterfaceFromNode( 981 ui::AXPlatformNodeDelegate* node); 982 983 // Call GetPropertyValue with the given UIA property id with variant type 984 // VT_ARRAY | VT_UNKNOWN on the target browser accessibility node to retrieve 985 // an array of automation elements, then validate the name property of the 986 // automation elements with the expected names. 987 void UiaGetPropertyValueVtArrayVtUnknownValidate( 988 PROPERTYID property_id, 989 ui::AXPlatformNodeDelegate* target_node, 990 const std::vector<std::string>& expected_names); 991 #endif 992 993 // Returns the RenderWidgetHost that holds the mouse lock. 994 RenderWidgetHost* GetMouseLockWidget(WebContents* web_contents); 995 996 // Returns the RenderWidgetHost that holds the keyboard lock. 997 RenderWidgetHost* GetKeyboardLockWidget(WebContents* web_contents); 998 999 // Returns the RenderWidgetHost that holds mouse capture, if any. This is 1000 // distinct from MouseLock above in that it is a widget that has requested 1001 // implicit capture, such as during a drag. MouseLock is explicitly gained 1002 // through the JavaScript API. 1003 RenderWidgetHost* GetMouseCaptureWidget(WebContents* web_contents); 1004 1005 // Allows tests to drive keyboard lock functionality without requiring access 1006 // to the RenderWidgetHostImpl header or setting up an HTTP test server. 1007 // |codes| represents the set of keys to lock. If |codes| has no value, then 1008 // all keys will be considered locked. If |codes| has a value, then at least 1009 // one key must be specified. 1010 bool RequestKeyboardLock(WebContents* web_contents, 1011 base::Optional<base::flat_set<ui::DomCode>> codes); 1012 void CancelKeyboardLock(WebContents* web_contents); 1013 1014 // Returns the screen orientation provider that's been set via 1015 // WebContents::SetScreenOrientationDelegate(). May return null. 1016 ScreenOrientationDelegate* GetScreenOrientationDelegate(); 1017 1018 // Returns all the RenderWidgetHostViews inside the |web_contents| that are 1019 // registered in the RenderWidgetHostInputEventRouter. 1020 std::vector<RenderWidgetHostView*> GetInputEventRouterRenderWidgetHostViews( 1021 WebContents* web_contents); 1022 1023 // Returns the focused RenderWidgetHost. 1024 RenderWidgetHost* GetFocusedRenderWidgetHost(WebContents* web_contents); 1025 1026 // Returns whether or not the RenderWidgetHost thinks it is focused. 1027 bool IsRenderWidgetHostFocused(const RenderWidgetHost*); 1028 1029 // Returns the focused WebContents. 1030 WebContents* GetFocusedWebContents(WebContents* web_contents); 1031 1032 // Watches title changes on a WebContents, blocking until an expected title is 1033 // set. 1034 class TitleWatcher : public WebContentsObserver { 1035 public: 1036 // |web_contents| must be non-NULL and needs to stay alive for the 1037 // entire lifetime of |this|. |expected_title| is the title that |this| 1038 // will wait for. 1039 TitleWatcher(WebContents* web_contents, 1040 const base::string16& expected_title); 1041 ~TitleWatcher() override; 1042 1043 // Adds another title to watch for. 1044 void AlsoWaitForTitle(const base::string16& expected_title); 1045 1046 // Waits until the title matches either expected_title or one of the titles 1047 // added with AlsoWaitForTitle. Returns the value of the most recently 1048 // observed matching title. 1049 const base::string16& WaitAndGetTitle() WARN_UNUSED_RESULT; 1050 1051 private: 1052 // Overridden WebContentsObserver methods. 1053 void DidStopLoading() override; 1054 void TitleWasSet(NavigationEntry* entry) override; 1055 1056 void TestTitle(); 1057 1058 std::vector<base::string16> expected_titles_; 1059 base::RunLoop run_loop_; 1060 1061 // The most recently observed expected title, if any. 1062 base::string16 observed_title_; 1063 1064 DISALLOW_COPY_AND_ASSIGN(TitleWatcher); 1065 }; 1066 1067 // Watches a RenderProcessHost and waits for a specified lifecycle event. 1068 class RenderProcessHostWatcher : public RenderProcessHostObserver { 1069 public: 1070 enum WatchType { 1071 WATCH_FOR_PROCESS_READY, 1072 WATCH_FOR_PROCESS_EXIT, 1073 WATCH_FOR_HOST_DESTRUCTION 1074 }; 1075 1076 RenderProcessHostWatcher(RenderProcessHost* render_process_host, 1077 WatchType type); 1078 // Waits for the renderer process that contains the specified web contents. 1079 RenderProcessHostWatcher(WebContents* web_contents, WatchType type); 1080 ~RenderProcessHostWatcher() override; 1081 1082 // Waits until the expected event is triggered. This may only be called once. 1083 void Wait(); 1084 1085 // Returns true if a renderer process exited cleanly (without hitting 1086 // RenderProcessExited with an abnormal TerminationStatus). This should be 1087 // called after Wait(). 1088 bool did_exit_normally() { return did_exit_normally_; } 1089 1090 private: 1091 // Stop observing and drop the reference to the RenderProcessHost. 1092 void ClearProcessHost(); 1093 // Quit the run loop and clean up. 1094 void QuitRunLoop(); 1095 1096 // Overridden RenderProcessHost::LifecycleObserver methods. 1097 void RenderProcessReady(RenderProcessHost* host) override; 1098 void RenderProcessExited(RenderProcessHost* host, 1099 const ChildProcessTerminationInfo& info) override; 1100 void RenderProcessHostDestroyed(RenderProcessHost* host) override; 1101 1102 RenderProcessHost* render_process_host_; 1103 WatchType type_; 1104 bool did_exit_normally_; 1105 1106 std::unique_ptr<ScopedAllowRendererCrashes> allow_renderer_crashes_; 1107 1108 base::RunLoop run_loop_; 1109 base::OnceClosure quit_closure_; 1110 1111 DISALLOW_COPY_AND_ASSIGN(RenderProcessHostWatcher); 1112 }; 1113 1114 // Implementation helper for: 1115 // *) content-internal content::RenderProcessHostBadIpcMessageWaiter 1116 // (declared in //content/test/content_browser_test_utils_internal.h) 1117 // *) content-public content::RenderProcessHostBadMojoMessageWaiter 1118 // (declared below) 1119 // *) maybe in the future: similar helpers for chrome-layer BadMessageReason 1120 class RenderProcessHostKillWaiter { 1121 public: 1122 // |uma_name| is the name of the histogram from which the |bad_message_reason| 1123 // can be extracted. 1124 RenderProcessHostKillWaiter(RenderProcessHost* render_process_host, 1125 const std::string& uma_name); 1126 1127 RenderProcessHostKillWaiter(const RenderProcessHostKillWaiter&) = delete; 1128 RenderProcessHostKillWaiter& operator=(const RenderProcessHostKillWaiter&) = 1129 delete; 1130 1131 // Waits until the renderer process exits. Extracts and returns the bad 1132 // message reason that should be logged in the |uma_name_| histogram. 1133 // Returns |base::nullopt| if the renderer exited normally or didn't log 1134 // the |uma_name_| histogram. 1135 base::Optional<int> Wait() WARN_UNUSED_RESULT; 1136 1137 private: 1138 RenderProcessHostWatcher exit_watcher_; 1139 base::HistogramTester histogram_tester_; 1140 std::string uma_name_; 1141 }; 1142 1143 // Helps tests to wait until the given renderer process is terminated because of 1144 // a bad/invalid mojo message. 1145 // 1146 // Example usage: 1147 // RenderProcessHostBadMojoMessageWaiter kill_waiter(render_process_host); 1148 // ... test code that triggers a renderer kill ... 1149 // EXPECT_EQ("expected error message", kill_waiter.Wait()); 1150 class RenderProcessHostBadMojoMessageWaiter { 1151 public: 1152 explicit RenderProcessHostBadMojoMessageWaiter( 1153 RenderProcessHost* render_process_host); 1154 ~RenderProcessHostBadMojoMessageWaiter(); 1155 1156 RenderProcessHostBadMojoMessageWaiter( 1157 const RenderProcessHostBadMojoMessageWaiter&) = delete; 1158 RenderProcessHostBadMojoMessageWaiter& operator=( 1159 const RenderProcessHostBadMojoMessageWaiter&) = delete; 1160 1161 // Waits until |render_process_host| from the constructor is terminated 1162 // because of a bad/invalid mojo message and returns the associated error 1163 // string. Returns base::nullopt if the process was terminated for an 1164 // unrelated reason. 1165 base::Optional<std::string> Wait() WARN_UNUSED_RESULT; 1166 1167 private: 1168 void OnBadMojoMessage(int render_process_id, const std::string& error); 1169 1170 int monitored_render_process_id_; 1171 base::Optional<std::string> observed_mojo_error_; 1172 RenderProcessHostKillWaiter kill_waiter_; 1173 }; 1174 1175 // Watches for responses from the DOMAutomationController and keeps them in a 1176 // queue. Useful for waiting for a message to be received. 1177 class DOMMessageQueue : public NotificationObserver, 1178 public WebContentsObserver { 1179 public: 1180 // Constructs a DOMMessageQueue and begins listening for messages from the 1181 // DOMAutomationController. Do not construct this until the browser has 1182 // started. 1183 DOMMessageQueue(); 1184 1185 // Same as the default constructor, but only listens for messages 1186 // sent from a particular |web_contents|. 1187 explicit DOMMessageQueue(WebContents* web_contents); 1188 1189 // Same as the constructor with a WebContents, but observes the 1190 // RenderFrameHost deletion. 1191 explicit DOMMessageQueue(RenderFrameHost* render_frame_host); 1192 1193 ~DOMMessageQueue() override; 1194 1195 // Removes all messages in the message queue. 1196 void ClearQueue(); 1197 1198 // Wait for the next message to arrive. |message| will be set to the next 1199 // message. Returns true on success. 1200 bool WaitForMessage(std::string* message) WARN_UNUSED_RESULT; 1201 1202 // If there is a message in the queue, then copies it to |message| and returns 1203 // true. Otherwise (if the queue is empty), returns false. 1204 bool PopMessage(std::string* message) WARN_UNUSED_RESULT; 1205 1206 // Overridden NotificationObserver methods. 1207 void Observe(int type, 1208 const NotificationSource& source, 1209 const NotificationDetails& details) override; 1210 1211 // Overridden WebContentsObserver methods. 1212 void RenderProcessGone(base::TerminationStatus status) override; 1213 void RenderFrameDeleted(RenderFrameHost* render_frame_host) override; 1214 1215 private: 1216 NotificationRegistrar registrar_; 1217 base::queue<std::string> message_queue_; 1218 base::OnceClosure quit_closure_; 1219 bool renderer_crashed_ = false; 1220 RenderFrameHost* render_frame_host_ = nullptr; 1221 1222 DISALLOW_COPY_AND_ASSIGN(DOMMessageQueue); 1223 }; 1224 1225 // Used to wait for a new WebContents to be created. Instantiate this object 1226 // before the operation that will create the window. 1227 class WebContentsAddedObserver { 1228 public: 1229 WebContentsAddedObserver(); 1230 ~WebContentsAddedObserver(); 1231 1232 // Will run a message loop to wait for the new window if it hasn't been 1233 // created since the constructor 1234 WebContents* GetWebContents(); 1235 1236 // Will tell whether RenderViewCreated Callback has invoked 1237 bool RenderViewCreatedCalled(); 1238 1239 private: 1240 class RenderViewCreatedObserver; 1241 1242 void WebContentsCreated(WebContents* web_contents); 1243 1244 // Callback to WebContentCreated(). Cached so that we can unregister it. 1245 base::RepeatingCallback<void(WebContents*)> web_contents_created_callback_; 1246 1247 WebContents* web_contents_; 1248 std::unique_ptr<RenderViewCreatedObserver> child_observer_; 1249 base::OnceClosure quit_closure_; 1250 1251 DISALLOW_COPY_AND_ASSIGN(WebContentsAddedObserver); 1252 }; 1253 1254 // Request a new frame be drawn, returns false if request fails. 1255 bool RequestFrame(WebContents* web_contents); 1256 1257 // This class is intended to synchronize upon the submission of compositor 1258 // frames from the renderer to the display compositor. 1259 // 1260 // This class enables observation of the provided 1261 // RenderFrameMetadataProvider. Which notifies this of every 1262 // subsequent frame submission. Observation ends upon the destruction of this 1263 // class. 1264 // 1265 // Calling Wait will block the browser ui thread until the next time the 1266 // renderer submits a frame. 1267 // 1268 // Tests interested in the associated RenderFrameMetadata will find it cached 1269 // in the RenderFrameMetadataProvider. 1270 class RenderFrameSubmissionObserver 1271 : public RenderFrameMetadataProvider::Observer { 1272 public: 1273 explicit RenderFrameSubmissionObserver( 1274 RenderFrameMetadataProviderImpl* render_frame_metadata_provider); 1275 explicit RenderFrameSubmissionObserver(FrameTreeNode* node); 1276 explicit RenderFrameSubmissionObserver(WebContents* web_contents); 1277 ~RenderFrameSubmissionObserver() override; 1278 1279 // Resets the current |render_frame_count|; 1280 void ResetCounter() { render_frame_count_ = 0; } 1281 1282 // Blocks the browser ui thread until the next OnRenderFrameSubmission. 1283 void WaitForAnyFrameSubmission(); 1284 1285 // Blocks the browser ui thread until the next 1286 // OnRenderFrameMetadataChangedAfterActivation. 1287 void WaitForMetadataChange(); 1288 1289 // Blocks the browser ui thread until RenderFrameMetadata arrives with 1290 // page scale factor matching |expected_page_scale_factor|. 1291 void WaitForPageScaleFactor(float expected_page_scale_factor, 1292 const float tolerance); 1293 1294 // Blocks the browser ui thread until RenderFrameMetadata arrives with 1295 // external page scale factor matching |expected_external_page_scale_factor|. 1296 void WaitForExternalPageScaleFactor(float expected_external_page_scale_factor, 1297 const float tolerance); 1298 1299 // Blocks the browser ui thread until RenderFrameMetadata arrives where its 1300 // scroll offset matches |expected_offset|. 1301 void WaitForScrollOffset(const gfx::Vector2dF& expected_offset); 1302 1303 // Blocks the browser ui thread until RenderFrameMetadata arrives where its 1304 // scroll offset at top matches |expected_scroll_offset_at_top|. 1305 void WaitForScrollOffsetAtTop(bool expected_scroll_offset_at_top); 1306 1307 const cc::RenderFrameMetadata& LastRenderFrameMetadata() const; 1308 1309 // Returns the number of frames submitted since the observer's creation. 1310 int render_frame_count() const { return render_frame_count_; } 1311 1312 // Runs |closure| the next time metadata changes. 1313 void NotifyOnNextMetadataChange(base::OnceClosure closure); 1314 1315 private: 1316 // Exits |run_loop_| unblocking the UI thread. Execution will resume in Wait. 1317 void Quit(); 1318 1319 // Blocks the browser ui thread. 1320 void Wait(); 1321 1322 // RenderFrameMetadataProvider::Observer 1323 void OnRenderFrameMetadataChangedBeforeActivation( 1324 const cc::RenderFrameMetadata& metadata) override; 1325 void OnRenderFrameMetadataChangedAfterActivation() override; 1326 void OnRenderFrameSubmission() override; 1327 void OnLocalSurfaceIdChanged( 1328 const cc::RenderFrameMetadata& metadata) override; 1329 1330 // If true then the next OnRenderFrameSubmission will cancel the blocking 1331 // |run_loop_| otherwise the blocking will continue until the next 1332 // OnRenderFrameMetadataChangedAfterActivation. 1333 bool break_on_any_frame_ = false; 1334 1335 RenderFrameMetadataProviderImpl* render_frame_metadata_provider_ = nullptr; 1336 base::OnceClosure quit_closure_; 1337 // If non-null, run when metadata changes. 1338 base::OnceClosure metadata_change_closure_; 1339 int render_frame_count_ = 0; 1340 }; 1341 1342 // This class is intended to synchronize the renderer main thread, renderer impl 1343 // thread and the browser main thread. 1344 // 1345 // This is accomplished by sending an IPC to RenderWidget, then blocking until 1346 // the ACK is received and processed. 1347 // 1348 // The ACK is sent from compositor thread, when the CompositorFrame is submited 1349 // to the display compositor 1350 // TODO(danakj): This class seems to provide the same as 1351 // RenderFrameSubmissionObserver, consider using that instead. 1352 class MainThreadFrameObserver { 1353 public: 1354 explicit MainThreadFrameObserver(RenderWidgetHost* render_widget_host); 1355 ~MainThreadFrameObserver(); 1356 1357 // Synchronizes the browser main thread with the renderer main thread and impl 1358 // thread. 1359 void Wait(); 1360 1361 private: 1362 void Quit(bool); 1363 1364 RenderWidgetHost* render_widget_host_; 1365 base::OnceClosure quit_closure_; 1366 int routing_id_; 1367 1368 DISALLOW_COPY_AND_ASSIGN(MainThreadFrameObserver); 1369 }; 1370 1371 // Watches for an input msg to be consumed. 1372 class InputMsgWatcher : public RenderWidgetHost::InputEventObserver { 1373 public: 1374 InputMsgWatcher(RenderWidgetHost* render_widget_host, 1375 blink::WebInputEvent::Type type); 1376 ~InputMsgWatcher() override; 1377 1378 bool HasReceivedAck() const; 1379 1380 // Wait until ack message occurs, returning the ack result from 1381 // the message. 1382 blink::mojom::InputEventResultState WaitForAck(); 1383 1384 // Wait for the ack if it hasn't been received, if it has been 1385 // received return the result immediately. 1386 blink::mojom::InputEventResultState GetAckStateWaitIfNecessary(); 1387 1388 blink::mojom::InputEventResultSource last_event_ack_source() const { 1389 return ack_source_; 1390 } 1391 1392 private: 1393 // Overridden InputEventObserver methods. 1394 void OnInputEventAck(blink::mojom::InputEventResultSource source, 1395 blink::mojom::InputEventResultState state, 1396 const blink::WebInputEvent&) override; 1397 1398 RenderWidgetHost* render_widget_host_; 1399 blink::WebInputEvent::Type wait_for_type_; 1400 blink::mojom::InputEventResultState ack_result_; 1401 blink::mojom::InputEventResultSource ack_source_; 1402 base::OnceClosure quit_closure_; 1403 1404 DISALLOW_COPY_AND_ASSIGN(InputMsgWatcher); 1405 }; 1406 1407 // Used to wait for a desired input event ack. 1408 class InputEventAckWaiter : public RenderWidgetHost::InputEventObserver { 1409 public: 1410 // A function determining if a given |event| and its ack are what we're 1411 // waiting for. 1412 using InputEventAckPredicate = 1413 base::RepeatingCallback<bool(blink::mojom::InputEventResultSource source, 1414 blink::mojom::InputEventResultState state, 1415 const blink::WebInputEvent& event)>; 1416 1417 // Wait for an event satisfying |predicate|. 1418 InputEventAckWaiter(RenderWidgetHost* render_widget_host, 1419 InputEventAckPredicate predicate); 1420 // Wait for any event of the given |type|. 1421 InputEventAckWaiter(RenderWidgetHost* render_widget_host, 1422 blink::WebInputEvent::Type type); 1423 ~InputEventAckWaiter() override; 1424 1425 void Wait(); 1426 void Reset(); 1427 1428 // RenderWidgetHost::InputEventObserver: 1429 void OnInputEventAck(blink::mojom::InputEventResultSource source, 1430 blink::mojom::InputEventResultState state, 1431 const blink::WebInputEvent& event) override; 1432 1433 private: 1434 RenderWidgetHost* render_widget_host_; 1435 InputEventAckPredicate predicate_; 1436 bool event_received_; 1437 base::OnceClosure quit_closure_; 1438 1439 DISALLOW_COPY_AND_ASSIGN(InputEventAckWaiter); 1440 }; 1441 1442 // Sets up a ui::TestClipboard for use in browser tests. On Windows, 1443 // clipboard is handled on the IO thread, BrowserTestClipboardScope 1444 // hops messages onto the right thread. 1445 class BrowserTestClipboardScope { 1446 public: 1447 // Sets up a ui::TestClipboard. 1448 BrowserTestClipboardScope(); 1449 1450 // Tears down the clipboard. 1451 ~BrowserTestClipboardScope(); 1452 1453 // Puts text/rtf |rtf| on the clipboard. 1454 void SetRtf(const std::string& rtf); 1455 1456 // Puts plain text |text| on the clipboard. 1457 void SetText(const std::string& text); 1458 1459 // Gets plain text from the clipboard, if any. 1460 void GetText(std::string* text); 1461 1462 private: 1463 DISALLOW_COPY_AND_ASSIGN(BrowserTestClipboardScope); 1464 }; 1465 1466 // This observer is used to wait for its owner Frame to become focused. 1467 class FrameFocusedObserver { 1468 public: 1469 explicit FrameFocusedObserver(RenderFrameHost* owner_host); 1470 ~FrameFocusedObserver(); 1471 1472 void Wait(); 1473 1474 private: 1475 // Private impl struct which hides non public types including FrameTreeNode. 1476 class FrameTreeNodeObserverImpl; 1477 1478 // FrameTreeNode::Observer 1479 std::unique_ptr<FrameTreeNodeObserverImpl> impl_; 1480 1481 DISALLOW_COPY_AND_ASSIGN(FrameFocusedObserver); 1482 }; 1483 1484 // This observer is used to wait for its owner FrameTreeNode to become deleted. 1485 class FrameDeletedObserver { 1486 public: 1487 explicit FrameDeletedObserver(RenderFrameHost* owner_host); 1488 ~FrameDeletedObserver(); 1489 1490 void Wait(); 1491 1492 private: 1493 // Private impl struct which hides non public types including FrameTreeNode. 1494 class FrameTreeNodeObserverImpl; 1495 1496 // FrameTreeNode::Observer 1497 std::unique_ptr<FrameTreeNodeObserverImpl> impl_; 1498 1499 DISALLOW_COPY_AND_ASSIGN(FrameDeletedObserver); 1500 }; 1501 1502 // This class can be used to pause and resume navigations, based on a URL 1503 // match. Note that it only keeps track of one navigation at a time. 1504 // Navigations are paused automatically before hitting the network, and are 1505 // resumed automatically if a Wait method is called for a future event. 1506 // Note: This class is one time use only! After it successfully tracks a 1507 // navigation it will ignore all subsequent navigations. Explicitly create 1508 // multiple instances of this class if you want to pause multiple navigations. 1509 class TestNavigationManager : public WebContentsObserver { 1510 public: 1511 // Monitors any frame in WebContents. 1512 TestNavigationManager(WebContents* web_contents, const GURL& url); 1513 1514 ~TestNavigationManager() override; 1515 1516 // Waits until the navigation request is ready to be sent to the network 1517 // stack. Returns false if the request was aborted before starting. 1518 WARN_UNUSED_RESULT bool WaitForRequestStart(); 1519 1520 // Waits until the navigation response's headers have been received. Returns 1521 // false if the request was aborted before getting a response. 1522 WARN_UNUSED_RESULT bool WaitForResponse(); 1523 1524 // Waits until the navigation has been finished. Will automatically resume 1525 // navigations paused before this point. 1526 void WaitForNavigationFinished(); 1527 1528 // Resume the navigation. 1529 // * Called after |WaitForRequestStart|, it causes the request to be sent. 1530 // * Called after |WaitForResponse|, it causes the response to be committed. 1531 void ResumeNavigation(); 1532 1533 // Returns the NavigationHandle associated with the navigation. It is non-null 1534 // only in between DidStartNavigation(...) and DidFinishNavigation(...). 1535 NavigationHandle* GetNavigationHandle(); 1536 1537 // Whether the navigation successfully committed. 1538 bool was_committed() const { return was_committed_; } 1539 1540 // Whether the navigation successfully committed and was not an error page. 1541 bool was_successful() const { return was_successful_; } 1542 1543 // Allows nestable tasks when running a message loop in the Wait* functions. 1544 // This is useful for utilizing this class from within another message loop. 1545 void AllowNestableTasks(); 1546 1547 protected: 1548 // Derived classes can override if they want to filter out navigations. This 1549 // is called from DidStartNavigation. 1550 virtual bool ShouldMonitorNavigation(NavigationHandle* handle); 1551 1552 private: 1553 enum class NavigationState { 1554 INITIAL = 0, 1555 STARTED = 1, 1556 RESPONSE = 2, 1557 FINISHED = 3, 1558 }; 1559 1560 // WebContentsObserver: 1561 void DidStartNavigation(NavigationHandle* handle) override; 1562 void DidFinishNavigation(NavigationHandle* handle) override; 1563 1564 // Called when the NavigationThrottle pauses the navigation in 1565 // WillStartRequest. 1566 void OnWillStartRequest(); 1567 1568 // Called when the NavigationThrottle pauses the navigation in 1569 // WillProcessResponse. 1570 void OnWillProcessResponse(); 1571 1572 // Waits for the desired state. Returns false if the desired state cannot be 1573 // reached (eg the navigation finishes before reaching this state). 1574 bool WaitForDesiredState(); 1575 1576 // Called when the state of the navigation has changed. This will either stop 1577 // the message loop if the state specified by the user has been reached, or 1578 // resume the navigation if it hasn't been reached yet. 1579 void OnNavigationStateChanged(); 1580 1581 const GURL url_; 1582 NavigationRequest* request_; 1583 bool navigation_paused_; 1584 NavigationState current_state_; 1585 NavigationState desired_state_; 1586 bool was_committed_ = false; 1587 bool was_successful_ = false; 1588 base::OnceClosure quit_closure_; 1589 base::RunLoop::Type message_loop_type_ = base::RunLoop::Type::kDefault; 1590 1591 base::WeakPtrFactory<TestNavigationManager> weak_factory_{this}; 1592 1593 DISALLOW_COPY_AND_ASSIGN(TestNavigationManager); 1594 }; 1595 1596 class NavigationHandleCommitObserver : public content::WebContentsObserver { 1597 public: 1598 NavigationHandleCommitObserver(content::WebContents* web_contents, 1599 const GURL& url); 1600 1601 bool has_committed() const { return has_committed_; } 1602 bool was_same_document() const { return was_same_document_; } 1603 bool was_renderer_initiated() const { return was_renderer_initiated_; } 1604 1605 private: 1606 void DidFinishNavigation(content::NavigationHandle* handle) override; 1607 1608 const GURL url_; 1609 bool has_committed_; 1610 bool was_same_document_; 1611 bool was_renderer_initiated_; 1612 }; 1613 1614 // A test utility that monitors console messages sent to a WebContents. This 1615 // can be used to wait for a message that matches a specific filter, an 1616 // arbitrary message, or monitor all messages sent to the WebContents' console. 1617 class WebContentsConsoleObserver : public WebContentsObserver { 1618 public: 1619 struct Message { 1620 RenderFrameHost* source_frame; 1621 blink::mojom::ConsoleMessageLevel log_level; 1622 base::string16 message; 1623 int32_t line_no; 1624 base::string16 source_id; 1625 }; 1626 1627 // A filter to apply to incoming console messages to determine whether to 1628 // record them. The filter should return `true` if the observer should record 1629 // the message, and stop waiting (if it was waiting). 1630 using Filter = base::RepeatingCallback<bool(const Message& message)>; 1631 1632 explicit WebContentsConsoleObserver(content::WebContents* web_contents); 1633 ~WebContentsConsoleObserver() override; 1634 1635 // Waits for a message to come in that matches the set filter, if any. If no 1636 // filter is set, waits for the first message that comes in. 1637 void Wait(); 1638 1639 // Sets a custom filter to be used while waiting for a message, allowing 1640 // more custom filtering (e.g. based on source). 1641 void SetFilter(Filter filter); 1642 1643 // A convenience method to just match the message against a string pattern. 1644 void SetPattern(std::string pattern); 1645 1646 // A helper method to return the string content (in UTF8) of the message at 1647 // the given |index|. This will cause a test failure if there is no such 1648 // message. 1649 std::string GetMessageAt(size_t index) const; 1650 1651 const std::vector<Message>& messages() const { return messages_; } 1652 1653 private: 1654 // WebContentsObserver: 1655 void OnDidAddMessageToConsole(RenderFrameHost* source_frame, 1656 blink::mojom::ConsoleMessageLevel log_level, 1657 const base::string16& message, 1658 int32_t line_no, 1659 const base::string16& source_id) override; 1660 1661 Filter filter_; 1662 std::string pattern_; 1663 base::RunLoop run_loop_; 1664 std::vector<Message> messages_; 1665 }; 1666 1667 // Static methods that simulates Mojo methods as if they were called by a 1668 // renderer. Used to simulate a compromised renderer. 1669 class PwnMessageHelper { 1670 public: 1671 // Calls Create method in FileSystemHost Mojo interface. 1672 static void FileSystemCreate(RenderProcessHost* process, 1673 int request_id, 1674 GURL path, 1675 bool exclusive, 1676 bool is_directory, 1677 bool recursive); 1678 1679 // Calls Write method in FileSystemHost Mojo interface. 1680 static void FileSystemWrite(RenderProcessHost* process, 1681 int request_id, 1682 GURL file_path, 1683 std::string blob_uuid, 1684 int64_t position); 1685 1686 // Calls OpenURL method in FrameHost Mojo interface. 1687 static void OpenURL(RenderFrameHost* render_frame_host, const GURL& url); 1688 1689 private: 1690 PwnMessageHelper(); // Not instantiable. 1691 1692 DISALLOW_COPY_AND_ASSIGN(PwnMessageHelper); 1693 }; 1694 1695 #if defined(USE_AURA) 1696 1697 // Tests that a |render_widget_host_view| stores a stale content when its frame 1698 // gets evicted. |render_widget_host_view| has to be a RenderWidgetHostViewAura. 1699 void VerifyStaleContentOnFrameEviction( 1700 RenderWidgetHostView* render_widget_host_view); 1701 1702 #endif // defined(USE_AURA) 1703 1704 // This class filters for FrameHostMsg_ContextMenu messages coming in from a 1705 // renderer process, and allows observing the UntrustworthyContextMenuParams as 1706 // sent by the renderer. 1707 class ContextMenuFilter : public content::BrowserMessageFilter { 1708 public: 1709 // Whether or not the ContextMenu should be prevented from performing 1710 // its default action, preventing the context menu from showing. 1711 enum ShowBehavior { kShow, kPreventShow }; 1712 1713 explicit ContextMenuFilter(ShowBehavior behavior = ShowBehavior::kShow); 1714 1715 bool OnMessageReceived(const IPC::Message& message) override; 1716 void Wait(); 1717 void Reset(); 1718 1719 content::UntrustworthyContextMenuParams get_params() { return last_params_; } 1720 1721 private: 1722 ~ContextMenuFilter() override; 1723 1724 void OnContextMenu(const content::UntrustworthyContextMenuParams& params); 1725 1726 std::unique_ptr<base::RunLoop> run_loop_; 1727 base::OnceClosure quit_closure_; 1728 content::UntrustworthyContextMenuParams last_params_; 1729 const ShowBehavior show_behavior_; 1730 1731 DISALLOW_COPY_AND_ASSIGN(ContextMenuFilter); 1732 }; 1733 1734 class UpdateUserActivationStateInterceptor 1735 : public blink::mojom::LocalFrameHostInterceptorForTesting { 1736 public: 1737 UpdateUserActivationStateInterceptor(); 1738 ~UpdateUserActivationStateInterceptor() override; 1739 1740 void Init(content::RenderFrameHost* render_frame_host); 1741 void set_quit_handler(base::OnceClosure handler); 1742 bool update_user_activation_state() { return update_user_activation_state_; } 1743 1744 blink::mojom::LocalFrameHost* GetForwardingInterface() override; 1745 void UpdateUserActivationState( 1746 blink::mojom::UserActivationUpdateType update_type, 1747 blink::mojom::UserActivationNotificationType notification_type) override; 1748 1749 private: 1750 content::RenderFrameHost* render_frame_host_; 1751 blink::mojom::LocalFrameHost* impl_; 1752 base::OnceClosure quit_handler_; 1753 bool update_user_activation_state_ = false; 1754 }; 1755 1756 WebContents* GetEmbedderForGuest(content::WebContents* guest); 1757 1758 // Load the given |url| with |network_context| and return the |net::Error| code. 1759 // 1760 // This overload simulates loading through a URLLoaderFactory created for a 1761 // Browser process. 1762 int LoadBasicRequest(network::mojom::NetworkContext* network_context, 1763 const GURL& url, 1764 int load_flags = net::LOAD_NORMAL); 1765 1766 // Load the given |url| via URLLoaderFactory created by |frame|. Return the 1767 // |net::Error| code. 1768 // 1769 // This overload simulates loading through a URLLoaderFactory created for a 1770 // Renderer process (the factory is driven from the Test/Browser process, but 1771 // has the same properties as factories vended to the Renderer process that 1772 // hosts the |frame|). 1773 int LoadBasicRequest(RenderFrameHost* frame, const GURL& url); 1774 1775 // Ensures that all StoragePartitions for the given BrowserContext have their 1776 // cookies flushed to disk. 1777 void EnsureCookiesFlushed(BrowserContext* browser_context); 1778 1779 // Returns true if there is a valid process for |process_group_name|. Must be 1780 // called on the IO thread. 1781 bool HasValidProcessForProcessGroup(const std::string& process_group_name); 1782 1783 // Performs a simple auto-resize flow and ensures that the embedder gets a 1784 // single response messages back from the guest, with the expected values. 1785 bool TestGuestAutoresize(RenderProcessHost* embedder_rph, 1786 RenderWidgetHost* guest_rwh); 1787 1788 // Class to sniff incoming IPCs for FrameHostMsg_SynchronizeVisualProperties 1789 // messages. This allows the message to continue to the target child so that 1790 // processing can be verified by tests. It also monitors for 1791 // GesturePinchBegin/End events. 1792 class SynchronizeVisualPropertiesMessageFilter 1793 : public content::BrowserMessageFilter { 1794 public: 1795 SynchronizeVisualPropertiesMessageFilter(); 1796 1797 gfx::Rect last_rect() const { return last_rect_; } 1798 1799 void WaitForRect(); 1800 void ResetRectRunLoop(); 1801 1802 // Waits for the next viz::LocalSurfaceId be received and returns it. 1803 viz::LocalSurfaceId WaitForSurfaceId(); 1804 1805 bool pinch_gesture_active_set() { return pinch_gesture_active_set_; } 1806 bool pinch_gesture_active_cleared() { return pinch_gesture_active_cleared_; } 1807 1808 void WaitForPinchGestureEnd(); 1809 1810 protected: 1811 ~SynchronizeVisualPropertiesMessageFilter() override; 1812 1813 private: 1814 void OnSynchronizeFrameHostVisualProperties( 1815 const blink::FrameVisualProperties& visual_properties); 1816 void OnSynchronizeVisualProperties( 1817 const blink::FrameVisualProperties& visual_properties); 1818 // |rect| is in DIPs. 1819 void OnUpdatedFrameRectOnUI(const gfx::Rect& rect); 1820 void OnUpdatedFrameSinkIdOnUI(); 1821 void OnUpdatedSurfaceIdOnUI(viz::LocalSurfaceId surface_id); 1822 1823 bool OnMessageReceived(const IPC::Message& message) override; 1824 1825 base::RunLoop run_loop_; 1826 1827 std::unique_ptr<base::RunLoop> screen_space_rect_run_loop_; 1828 bool screen_space_rect_received_; 1829 gfx::Rect last_rect_; 1830 1831 viz::LocalSurfaceId last_surface_id_; 1832 std::unique_ptr<base::RunLoop> surface_id_run_loop_; 1833 1834 bool pinch_gesture_active_set_; 1835 bool pinch_gesture_active_cleared_; 1836 bool last_pinch_gesture_active_; 1837 std::unique_ptr<base::RunLoop> pinch_end_run_loop_; 1838 1839 DISALLOW_COPY_AND_ASSIGN(SynchronizeVisualPropertiesMessageFilter); 1840 }; 1841 1842 // This class allows monitoring of mouse events received by a specific 1843 // RenderWidgetHost. 1844 class RenderWidgetHostMouseEventMonitor { 1845 public: 1846 explicit RenderWidgetHostMouseEventMonitor(RenderWidgetHost* host); 1847 ~RenderWidgetHostMouseEventMonitor(); 1848 bool EventWasReceived() const { return event_received_; } 1849 void ResetEventReceived() { event_received_ = false; } 1850 const blink::WebMouseEvent& event() const { return event_; } 1851 1852 private: 1853 bool MouseEventCallback(const blink::WebMouseEvent& event) { 1854 event_received_ = true; 1855 event_ = event; 1856 return false; 1857 } 1858 RenderWidgetHost::MouseEventCallback mouse_callback_; 1859 RenderWidgetHost* host_; 1860 bool event_received_; 1861 blink::WebMouseEvent event_; 1862 1863 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostMouseEventMonitor); 1864 }; 1865 1866 // Helper class to track and allow waiting for navigation start events. 1867 class DidStartNavigationObserver : public WebContentsObserver { 1868 public: 1869 explicit DidStartNavigationObserver(WebContents* web_contents); 1870 ~DidStartNavigationObserver() override; 1871 1872 void Wait() { run_loop_.Run(); } 1873 bool observed() { return observed_; } 1874 1875 // If the navigation was observed and is still not finished yet, this returns 1876 // its handle, otherwise it returns nullptr. 1877 NavigationHandle* navigation_handle() { return navigation_handle_; } 1878 1879 // WebContentsObserver override: 1880 void DidStartNavigation(NavigationHandle* navigation_handle) override; 1881 void DidFinishNavigation(NavigationHandle* navigation_handle) override; 1882 1883 private: 1884 bool observed_ = false; 1885 base::RunLoop run_loop_; 1886 NavigationHandle* navigation_handle_ = nullptr; 1887 1888 DISALLOW_COPY_AND_ASSIGN(DidStartNavigationObserver); 1889 }; 1890 1891 // Tracks the creation of RenderFrameProxyHosts that have 1892 // CrossProcessFrameConnectors, and records the initial (post-construction) 1893 // device scale factor in the CrossProcessFrameConnector. 1894 class ProxyDSFObserver { 1895 public: 1896 ProxyDSFObserver(); 1897 ~ProxyDSFObserver(); 1898 1899 // Waits until a single RenderFrameProxyHost with a CrossProcessFrameConnector 1900 // has been created. If a creation occurs before this function is called, it 1901 // returns immediately. 1902 void WaitForOneProxyHostCreation(); 1903 1904 size_t num_creations() { return proxy_host_created_dsf_.size(); } 1905 1906 float get_proxy_host_dsf(unsigned index) { 1907 return proxy_host_created_dsf_[index]; 1908 } 1909 1910 private: 1911 void OnCreation(RenderFrameProxyHost* rfph); 1912 1913 // Make this a vector, just in case we encounter multiple creations prior to 1914 // calling WaitForOneProxyHostCreation(). That way we can confirm we're 1915 // getting the device scale factor we expect. 1916 // Note: We can modify the vector to collect a void* id for each 1917 // RenderFrameProxyHost if we want to expand to cases where multiple creations 1918 // must be observed. 1919 std::vector<float> proxy_host_created_dsf_; 1920 std::unique_ptr<base::RunLoop> runner_; 1921 }; 1922 1923 // Helper used by the wrapper class below. Compares the output of the given 1924 // |web_contents| to the PNG file at |expected_path| across the region defined 1925 // by |snapshot_size| and returns true if the images are equivalent. Uses a 1926 // ManhattanDistancePixelComparator which allows some small differences. If 1927 // the flag switches::kRebaselinePixelTests (--rebaseline-pixel-tests) is set, 1928 // this function will (over)write the reference file with the produced output. 1929 bool CompareWebContentsOutputToReference( 1930 WebContents* web_contents, 1931 const base::FilePath& expected_path, 1932 const gfx::Size& snapshot_size, 1933 const cc::PixelComparator& comparator = 1934 cc::ManhattanDistancePixelComparator()); 1935 1936 typedef base::OnceCallback<void(RenderFrameHost*, RenderFrameHost*)> 1937 RenderFrameHostChangedCallback; 1938 1939 // Runs callback at RenderFrameHostChanged time. On cross-RFH navigations, this 1940 // will run the callback after the new RenderFrameHost committed and is set as 1941 // the current RenderFrameHost, etc. but before the old RenderFrameHost gets 1942 // unloaded. 1943 class RenderFrameHostChangedCallbackRunner : public WebContentsObserver { 1944 public: 1945 explicit RenderFrameHostChangedCallbackRunner( 1946 WebContents* content, 1947 RenderFrameHostChangedCallback callback); 1948 1949 ~RenderFrameHostChangedCallbackRunner() override; 1950 1951 private: 1952 void RenderFrameHostChanged(RenderFrameHost* old_host, 1953 RenderFrameHost* new_host) override; 1954 1955 RenderFrameHostChangedCallback callback_; 1956 1957 DISALLOW_COPY_AND_ASSIGN(RenderFrameHostChangedCallbackRunner); 1958 }; 1959 1960 } // namespace content 1961 1962 #endif // CONTENT_PUBLIC_TEST_BROWSER_TEST_UTILS_H_ 1963