OLD | NEW |
| (Empty) |
1 // Copyright 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 #import <UIKit/UIKit.h> | |
6 | |
7 #include "base/mac/scoped_nsobject.h" | |
8 #include "base/strings/sys_string_conversions.h" | |
9 #import "ios/chrome/browser/find_in_page/find_in_page_controller.h" | |
10 #import "ios/chrome/browser/web/chrome_web_test.h" | |
11 #import "ios/web/public/web_state/web_state.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | |
13 #include "testing/gtest_mac.h" | |
14 #import "third_party/ocmock/OCMock/OCMock.h" | |
15 | |
16 // Unit tests for the models/resources/find_in_page.js JavaScript file. | |
17 | |
18 namespace { | |
19 | |
20 // JavaScript invocation to search for 'foo' (for 1000 milliseconds). | |
21 NSString* kJavaScriptToSearchForFoo = | |
22 @"__gCrWeb.findInPage.highlightWord('foo', false, 1000)"; | |
23 | |
24 // Other JavaScript functions invoked by the tests. | |
25 NSString* kJavaScriptIncrementIndex = @"__gCrWeb.findInPage.incrementIndex()"; | |
26 NSString* kJavaScriptDecrementIndex = @"__gCrWeb.findInPage.decrementIndex()"; | |
27 NSString* kJavaScriptGoNext = @"__gCrWeb.findInPage.goNext()"; | |
28 NSString* kJavaScriptGoPrev = @"__gCrWeb.findInPage.goPrev()"; | |
29 | |
30 // JavaScript variables accessed by the tests. | |
31 NSString* kJavaScriptIndex = @"__gCrWeb.findInPage.index"; | |
32 NSString* kJavaScriptSpansLength = @"__gCrWeb.findInPage.spans.length"; | |
33 | |
34 // HTML that contains several occurences of the string 'foo', some visible and | |
35 // some not visible (the first 'foo' is hidden, the next is visible, the next is | |
36 // hidden and so on until the final 'foo' which is hidden. | |
37 NSString* kHtmlWithFoos = @"<html><body>" | |
38 " <span style='display:none'>foo</span>" | |
39 " <span>foo</span>" | |
40 " <span style='display:none'>foo</span>" | |
41 " <span>foo</span>" | |
42 " <span style='display:none'>foo</span>" | |
43 " <span>foo</span>" | |
44 " <span style='display:none'>foo</span>" | |
45 "</body></html>"; | |
46 | |
47 // The number of times 'foo' occurs in |kHtmlWithFoos| (hidden and visible). | |
48 const int kNumberOfFoosInHtml = 7; | |
49 | |
50 // HTML that contains several occurences of the string 'foo', none visible. | |
51 NSString* kHtmlWithNoVisibleFoos = @"<html><body>" | |
52 " <span style='display:none'>foo</span>" | |
53 " <span style='display:none'>foo</span>" | |
54 " <span style='display:none'>foo</span>" | |
55 " <span style='display:none'>foo</span>" | |
56 " <span style='display:none'>foo</span>" | |
57 " <span style='display:none'>foo</span>" | |
58 "</body></html>"; | |
59 | |
60 // Test fixture to test Find In Page JS. | |
61 class FindInPageJsTest : public ChromeWebTest { | |
62 public: | |
63 // Loads the given HTML, then loads the |findInPage| JavaScript. | |
64 void LoadHtml(NSString* html) { | |
65 ChromeWebTest::LoadHtml(html); | |
66 [findInPageController_ initFindInPage]; | |
67 } | |
68 | |
69 // Runs the given JavaScript and asserts that the result matches the given | |
70 // |expected_value|. | |
71 void AssertJavaScriptValue(NSString* script, int expected_value) { | |
72 id result = ExecuteJavaScript(script); | |
73 EXPECT_TRUE(result) << " in script: " << base::SysNSStringToUTF8(script); | |
74 EXPECT_EQ(expected_value, [result intValue]) | |
75 << " in script: " << base::SysNSStringToUTF8(script); | |
76 } | |
77 | |
78 // Loads the test HTML containing 'foo' strings and invokes the JavaScript | |
79 // necessary to search for and highlight any matches. Note that the JavaScript | |
80 // sets the current index to the first visible occurence of 'foo'. | |
81 void SearchForFoo() { | |
82 LoadHtml(kHtmlWithFoos); | |
83 | |
84 // Assert the index and span count contain their initialized values | |
85 AssertJavaScriptValue(kJavaScriptIndex, -1); | |
86 AssertJavaScriptValue(kJavaScriptSpansLength, 0); | |
87 | |
88 // Search for 'foo'. Performing the search sets the index to point to the | |
89 // first visible occurence of 'foo'. | |
90 ExecuteJavaScript(kJavaScriptToSearchForFoo); | |
91 AssertJavaScriptValue(kJavaScriptIndex, 1); | |
92 AssertJavaScriptValue(kJavaScriptSpansLength, kNumberOfFoosInHtml); | |
93 } | |
94 | |
95 void SetUp() override { | |
96 ChromeWebTest::SetUp(); | |
97 mockDelegate_.reset([[OCMockObject | |
98 niceMockForProtocol:@protocol(FindInPageControllerDelegate)] retain]); | |
99 findInPageController_.reset([[FindInPageController alloc] | |
100 initWithWebState:web_state() | |
101 delegate:mockDelegate_]); | |
102 } | |
103 | |
104 base::scoped_nsobject<FindInPageController> findInPageController_; | |
105 base::scoped_nsobject<id> mockDelegate_; | |
106 }; | |
107 | |
108 // Performs a search, then calls |incrementIndex| to loop through the | |
109 // matches, ensuring that when the end is reached the index wraps back to zero. | |
110 TEST_F(FindInPageJsTest, IncrementIndex) { | |
111 SearchForFoo(); | |
112 | |
113 // Increment index until it hits the max index. | |
114 for (int i = 2; i < kNumberOfFoosInHtml; i++) { | |
115 ExecuteJavaScript(kJavaScriptIncrementIndex); | |
116 AssertJavaScriptValue(kJavaScriptIndex, i); | |
117 } | |
118 | |
119 // Increment index one more time and it should wrap back to zero. | |
120 ExecuteJavaScript(kJavaScriptIncrementIndex); | |
121 AssertJavaScriptValue(kJavaScriptIndex, 0); | |
122 }; | |
123 | |
124 // Performs a search, then calls |decrementIndex| to loop through the | |
125 // matches, ensuring that when the beginning is reached the index wraps back to | |
126 // the end of the page. | |
127 TEST_F(FindInPageJsTest, DecrementIndex) { | |
128 SearchForFoo(); | |
129 | |
130 // Since the first visible 'foo' is at index 1, decrement once to get to zero. | |
131 ExecuteJavaScript(kJavaScriptDecrementIndex); | |
132 AssertJavaScriptValue(kJavaScriptIndex, 0); | |
133 | |
134 // Decrement index until it hits zero again. Note that the first time | |
135 // |decrementIndex| is called the index wraps from zero to the max index. | |
136 for (int i = kNumberOfFoosInHtml - 1; i >= 0; i--) { | |
137 ExecuteJavaScript(kJavaScriptDecrementIndex); | |
138 AssertJavaScriptValue(kJavaScriptIndex, i); | |
139 } | |
140 }; | |
141 | |
142 // Performs a search, then calls |goNext| to loop through the visible matches, | |
143 // ensuring that hidden matches are skipped and that when the end is reached the | |
144 // index wraps back to the beginning of the page. | |
145 TEST_F(FindInPageJsTest, GoNext) { | |
146 SearchForFoo(); | |
147 | |
148 // Since the first visible 'foo' is at index 1, and every other 'foo' is | |
149 // hidden, after calling goNext the index should be at 3. | |
150 ExecuteJavaScript(kJavaScriptGoNext); | |
151 AssertJavaScriptValue(kJavaScriptIndex, 3); | |
152 | |
153 // The next visible 'foo' is at index 5. | |
154 ExecuteJavaScript(kJavaScriptGoNext); | |
155 AssertJavaScriptValue(kJavaScriptIndex, 5); | |
156 | |
157 // Calling |goNext| again wraps around to the first visible foo. | |
158 ExecuteJavaScript(kJavaScriptGoNext); | |
159 AssertJavaScriptValue(kJavaScriptIndex, 1); | |
160 }; | |
161 | |
162 // Performs a search, then calls |goPrev| to loop through the visible matches, | |
163 // ensuring that hidden matches are skipped and that when the beginning is | |
164 // reached the index wraps back to the end of the page. | |
165 TEST_F(FindInPageJsTest, GoPrev) { | |
166 SearchForFoo(); | |
167 | |
168 // Calling |goPrev| will wrap around to the end of the page, and since the | |
169 // last 'foo' is hidden, we want |kNumberOfFoosInHtml| - 2. | |
170 ExecuteJavaScript(kJavaScriptGoPrev); | |
171 AssertJavaScriptValue(kJavaScriptIndex, 5); | |
172 | |
173 // Since every other 'foo' is hidden, the prior visible 'foo' is at index 3. | |
174 ExecuteJavaScript(kJavaScriptGoPrev); | |
175 AssertJavaScriptValue(kJavaScriptIndex, 3); | |
176 }; | |
177 | |
178 TEST_F(FindInPageJsTest, NoneVisible) { | |
179 LoadHtml(kHtmlWithNoVisibleFoos); | |
180 | |
181 // Assert the index and span count contain their initialized values | |
182 AssertJavaScriptValue(kJavaScriptIndex, -1); | |
183 AssertJavaScriptValue(kJavaScriptSpansLength, 0); | |
184 | |
185 // Search for 'foo'. Performing the search sets the index to point to 0 since | |
186 // there are no visible occurrences of 'foo'. | |
187 ExecuteJavaScript(kJavaScriptToSearchForFoo); | |
188 AssertJavaScriptValue(kJavaScriptIndex, 0); | |
189 AssertJavaScriptValue(kJavaScriptSpansLength, 6); | |
190 | |
191 ExecuteJavaScript(kJavaScriptGoPrev); | |
192 AssertJavaScriptValue(kJavaScriptIndex, 0); | |
193 | |
194 ExecuteJavaScript(kJavaScriptGoNext); | |
195 AssertJavaScriptValue(kJavaScriptIndex, 0); | |
196 } | |
197 | |
198 TEST_F(FindInPageJsTest, SearchForNonAscii) { | |
199 NSString* const kNonAscii = @"รก"; | |
200 NSString* const htmlFormat = @"<html>" | |
201 "<meta charset=\"UTF-8\">" | |
202 "<body>%@</body>" | |
203 "</html>"; | |
204 LoadHtml([NSString stringWithFormat:htmlFormat, kNonAscii]); | |
205 // Assert the index and span count contain their initialized values. | |
206 AssertJavaScriptValue(kJavaScriptIndex, -1); | |
207 AssertJavaScriptValue(kJavaScriptSpansLength, 0); | |
208 | |
209 // Search for the non-Ascii value. Performing the search sets the index to | |
210 // point to the first visible occurence of the non-Ascii. | |
211 NSString* result = ExecuteJavaScript([NSString | |
212 stringWithFormat:@"__gCrWeb.findInPage.highlightWord('%@', false, 1000)", | |
213 kNonAscii]); | |
214 DCHECK(result); | |
215 AssertJavaScriptValue(kJavaScriptIndex, 0); | |
216 AssertJavaScriptValue(kJavaScriptSpansLength, 1); | |
217 } | |
218 | |
219 } // namespace | |
OLD | NEW |