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/memory/scoped_vector.h"
12 #include "base/values.h"
13 #import "ios/testing/ocmock_complex_type_helper.h"
14 #include "ios/web/public/test/web_test_util.h"
15 #import "ios/web/public/web_state/crw_web_controller_observer.h"
16 #import "ios/web/public/web_state/js/crw_js_injection_manager.h"
17 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
18 #import "ios/web/test/crw_fake_web_controller_observer.h"
19 #include "ios/web/test/web_test.h"
20 #include "testing/gtest_mac.h"
24 // A mixin class for testing with CRWWKWebViewWebController or
25 // CRWUIWebViewWebController.
26 template <typename WebTestT>
27 class CRWWebControllerObserverTest : public WebTestT {
29 virtual void SetUp() {
31 fake_web_controller_observer_.reset(
32 [[CRWFakeWebControllerObserver alloc] initWithCommandPrefix:@"test"]);
33 [WebTestT::webController_ addObserver:fake_web_controller_observer_];
36 virtual void TearDown() {
37 [WebTestT::webController_ removeObserver:fake_web_controller_observer_];
38 fake_web_controller_observer_.reset();
42 base::scoped_nsobject<CRWFakeWebControllerObserver>
43 fake_web_controller_observer_;
46 // Concrete test fixture to test UIWebView-based web controller observing.
47 typedef CRWWebControllerObserverTest<web::UIWebViewWebTest>
48 CRWUIWebViewWebControllerObserverTest;
50 // Concrete test fixture to test WKWebView-based web controller observing.
51 typedef CRWWebControllerObserverTest<web::WKWebViewWebTest>
52 CRWWKWebViewWebControllerObserverTest;
54 WEB_TEST_F(CRWUIWebViewWebControllerObserverTest,
55 CRWWKWebViewWebControllerObserverTest,
57 EXPECT_FALSE([this->fake_web_controller_observer_ pageLoaded]);
58 this->LoadHtml(@"<p></p>");
59 EXPECT_TRUE([this->fake_web_controller_observer_ pageLoaded]);
62 // Tests that web controller receives a JS message from the page.
63 WEB_TEST_F(CRWUIWebViewWebControllerObserverTest,
64 CRWWKWebViewWebControllerObserverTest,
66 this->LoadHtml(@"<p></p>");
67 ASSERT_EQ(0U, [this->fake_web_controller_observer_ commandsReceived].size());
68 base::DictionaryValue command;
69 command.SetString("command", "test.testMessage");
71 base::JSONWriter::Write(&command, &message);
72 this->RunJavaScript([NSString
73 stringWithFormat:@"__gCrWeb.message.invokeOnHost(%s)", message.c_str()]);
74 this->WaitForBackgroundTasks();
75 ASSERT_EQ(1U, [this->fake_web_controller_observer_ commandsReceived].size());
76 EXPECT_TRUE([this->fake_web_controller_observer_ commandsReceived][0]->Equals(
80 // Tests that web controller receives an immediate JS message from the page.
81 WEB_TEST_F(CRWUIWebViewWebControllerObserverTest,
82 CRWWKWebViewWebControllerObserverTest,
83 HandleImmediateCommand) {
84 this->LoadHtml(@"<p></p>");
85 ASSERT_NSNE(@"http://testimmediate#target",
86 [this->webController_ externalRequestWindowName]);
87 // The only valid immediate commands are window.unload and externalRequest.
88 base::DictionaryValue command;
89 command.SetString("command", "externalRequest");
90 command.SetString("href", "http://testimmediate");
91 command.SetString("target", "target");
92 command.SetString("referrerPolicy", "referrerPolicy");
94 base::JSONWriter::Write(&command, &message);
96 [NSString stringWithFormat:@"__gCrWeb.message.invokeOnHostImmediate(%s)",
98 this->WaitForBackgroundTasks();
99 ASSERT_NSEQ(@"http://testimmediate#target",
100 [this->webController_ externalRequestWindowName]);
103 // Send a large number of commands and check each one is immediately received.
104 WEB_TEST_F(CRWUIWebViewWebControllerObserverTest,
105 CRWWKWebViewWebControllerObserverTest,
106 HandleMultipleCommands) {
107 this->LoadHtml(@"<p></p>");
109 base::DictionaryValue command;
110 command.SetString("command", "test.testMessage");
111 int kNumberMessages = 200;
112 for (int count = 0; count <= kNumberMessages; count++) {
114 command.SetInteger("number", count);
115 base::JSONWriter::Write(&command, &message);
117 [this->fake_web_controller_observer_ commandsReceived].size());
119 [NSString stringWithFormat:@"__gCrWeb.message.invokeOnHost(%s)",
121 this->WaitForBackgroundTasks();
123 [this->fake_web_controller_observer_ commandsReceived].size());
125 [this->fake_web_controller_observer_ commandsReceived][0]->Equals(
127 [this->fake_web_controller_observer_ commandsReceived].clear();
129 [this->fake_web_controller_observer_ commandsReceived].size());