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 |