1 // Copyright 2014 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.
5 #import "ios/web/web_state/ui/crw_web_controller.h"
9 #include "base/json/json_writer.h"
10 #include "base/mac/scoped_nsobject.h"
11 #include "base/values.h"
12 #import "ios/testing/ocmock_complex_type_helper.h"
13 #include "ios/web/public/test/web_test_util.h"
14 #import "ios/web/public/web_state/crw_web_controller_observer.h"
15 #import "ios/web/public/web_state/js/crw_js_injection_manager.h"
16 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
17 #import "ios/web/test/crw_fake_web_controller_observer.h"
18 #include "ios/web/test/web_test.h"
19 #include "testing/gtest_mac.h"
23 // A mixin class for testing with CRWWKWebViewWebController or
24 // CRWUIWebViewWebController.
25 template <typename WebTestT>
26 class CRWWebControllerObserverTest : public WebTestT {
28 virtual void SetUp() {
30 fake_web_controller_observer_.reset(
31 [[CRWFakeWebControllerObserver alloc] initWithCommandPrefix:@"test"]);
32 [WebTestT::webController_ addObserver:fake_web_controller_observer_];
35 virtual void TearDown() {
36 [WebTestT::webController_ removeObserver:fake_web_controller_observer_];
37 fake_web_controller_observer_.reset();
41 base::scoped_nsobject<CRWFakeWebControllerObserver>
42 fake_web_controller_observer_;
45 // Concrete test fixture to test UIWebView-based web controller observing.
46 typedef CRWWebControllerObserverTest<web::WebTestWithUIWebViewWebController>
47 CRWUIWebViewWebControllerObserverTest;
49 // Concrete test fixture to test WKWebView-based web controller observing.
50 typedef CRWWebControllerObserverTest<web::WebTestWithWKWebViewWebController>
51 CRWWKWebViewWebControllerObserverTest;
53 WEB_TEST_F(CRWUIWebViewWebControllerObserverTest,
54 CRWWKWebViewWebControllerObserverTest,
56 EXPECT_FALSE([this->fake_web_controller_observer_ pageLoaded]);
57 this->LoadHtml(@"<p></p>");
58 EXPECT_TRUE([this->fake_web_controller_observer_ pageLoaded]);
61 // Tests that web controller receives a JS message from the page.
62 WEB_TEST_F(CRWUIWebViewWebControllerObserverTest,
63 CRWWKWebViewWebControllerObserverTest,
65 this->LoadHtml(@"<p></p>");
66 ASSERT_EQ(0U, [this->fake_web_controller_observer_ commandsReceived].size());
67 base::DictionaryValue command;
68 command.SetString("command", "test.testMessage");
70 base::JSONWriter::Write(command, &message);
71 this->RunJavaScript([NSString
72 stringWithFormat:@"__gCrWeb.message.invokeOnHost(%s)", message.c_str()]);
73 this->WaitForBackgroundTasks();
74 ASSERT_EQ(1U, [this->fake_web_controller_observer_ commandsReceived].size());
75 EXPECT_TRUE([this->fake_web_controller_observer_ commandsReceived][0]->Equals(
79 // Tests that web controller receives an immediate JS message from the page.
80 WEB_TEST_F(CRWUIWebViewWebControllerObserverTest,
81 CRWWKWebViewWebControllerObserverTest,
82 HandleImmediateCommand) {
83 this->LoadHtml(@"<p></p>");
84 ASSERT_NSNE(@"http://testimmediate#target",
85 [this->webController_ externalRequestWindowName]);
86 // The only valid immediate commands are window.unload and externalRequest.
87 base::DictionaryValue command;
88 command.SetString("command", "externalRequest");
89 command.SetString("href", "http://testimmediate");
90 command.SetString("target", "target");
91 command.SetString("referrerPolicy", "referrerPolicy");
93 base::JSONWriter::Write(command, &message);
95 [NSString stringWithFormat:@"__gCrWeb.message.invokeOnHostImmediate(%s)",
97 this->WaitForBackgroundTasks();
98 ASSERT_NSEQ(@"http://testimmediate#target",
99 [this->webController_ externalRequestWindowName]);
102 // Send a large number of commands and check each one is immediately received.
103 WEB_TEST_F(CRWUIWebViewWebControllerObserverTest,
104 CRWWKWebViewWebControllerObserverTest,
105 HandleMultipleCommands) {
106 this->LoadHtml(@"<p></p>");
108 base::DictionaryValue command;
109 command.SetString("command", "test.testMessage");
110 int kNumberMessages = 200;
111 for (int count = 0; count <= kNumberMessages; count++) {
113 command.SetInteger("number", count);
114 base::JSONWriter::Write(command, &message);
116 [this->fake_web_controller_observer_ commandsReceived].size());
118 [NSString stringWithFormat:@"__gCrWeb.message.invokeOnHost(%s)",
120 this->WaitForBackgroundTasks();
122 [this->fake_web_controller_observer_ commandsReceived].size());
124 [this->fake_web_controller_observer_ commandsReceived][0]->Equals(
126 [this->fake_web_controller_observer_ commandsReceived].clear();
128 [this->fake_web_controller_observer_ commandsReceived].size());