| Index: ios/chrome/browser/web/find_in_page_js_unittest.mm
|
| diff --git a/ios/chrome/browser/web/find_in_page_js_unittest.mm b/ios/chrome/browser/web/find_in_page_js_unittest.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..89ee82120b92075a7a536edd60b51cbea64a3c40
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/web/find_in_page_js_unittest.mm
|
| @@ -0,0 +1,219 @@
|
| +// Copyright 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#import <UIKit/UIKit.h>
|
| +
|
| +#include "base/mac/scoped_nsobject.h"
|
| +#include "base/strings/sys_string_conversions.h"
|
| +#import "ios/chrome/browser/find_in_page/find_in_page_controller.h"
|
| +#import "ios/chrome/browser/web/chrome_web_test.h"
|
| +#import "ios/web/public/web_state/web_state.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "testing/gtest_mac.h"
|
| +#import "third_party/ocmock/OCMock/OCMock.h"
|
| +
|
| +// Unit tests for the models/resources/find_in_page.js JavaScript file.
|
| +
|
| +namespace {
|
| +
|
| +// JavaScript invocation to search for 'foo' (for 1000 milliseconds).
|
| +NSString* kJavaScriptToSearchForFoo =
|
| + @"__gCrWeb.findInPage.highlightWord('foo', false, 1000)";
|
| +
|
| +// Other JavaScript functions invoked by the tests.
|
| +NSString* kJavaScriptIncrementIndex = @"__gCrWeb.findInPage.incrementIndex()";
|
| +NSString* kJavaScriptDecrementIndex = @"__gCrWeb.findInPage.decrementIndex()";
|
| +NSString* kJavaScriptGoNext = @"__gCrWeb.findInPage.goNext()";
|
| +NSString* kJavaScriptGoPrev = @"__gCrWeb.findInPage.goPrev()";
|
| +
|
| +// JavaScript variables accessed by the tests.
|
| +NSString* kJavaScriptIndex = @"__gCrWeb.findInPage.index";
|
| +NSString* kJavaScriptSpansLength = @"__gCrWeb.findInPage.spans.length";
|
| +
|
| +// HTML that contains several occurences of the string 'foo', some visible and
|
| +// some not visible (the first 'foo' is hidden, the next is visible, the next is
|
| +// hidden and so on until the final 'foo' which is hidden.
|
| +NSString* kHtmlWithFoos = @"<html><body>"
|
| + " <span style='display:none'>foo</span>"
|
| + " <span>foo</span>"
|
| + " <span style='display:none'>foo</span>"
|
| + " <span>foo</span>"
|
| + " <span style='display:none'>foo</span>"
|
| + " <span>foo</span>"
|
| + " <span style='display:none'>foo</span>"
|
| + "</body></html>";
|
| +
|
| +// The number of times 'foo' occurs in |kHtmlWithFoos| (hidden and visible).
|
| +const int kNumberOfFoosInHtml = 7;
|
| +
|
| +// HTML that contains several occurences of the string 'foo', none visible.
|
| +NSString* kHtmlWithNoVisibleFoos = @"<html><body>"
|
| + " <span style='display:none'>foo</span>"
|
| + " <span style='display:none'>foo</span>"
|
| + " <span style='display:none'>foo</span>"
|
| + " <span style='display:none'>foo</span>"
|
| + " <span style='display:none'>foo</span>"
|
| + " <span style='display:none'>foo</span>"
|
| + "</body></html>";
|
| +
|
| +// Test fixture to test Find In Page JS.
|
| +class FindInPageJsTest : public ChromeWebTest {
|
| + public:
|
| + // Loads the given HTML, then loads the |findInPage| JavaScript.
|
| + void LoadHtml(NSString* html) {
|
| + ChromeWebTest::LoadHtml(html);
|
| + [findInPageController_ initFindInPage];
|
| + }
|
| +
|
| + // Runs the given JavaScript and asserts that the result matches the given
|
| + // |expected_value|.
|
| + void AssertJavaScriptValue(NSString* script, int expected_value) {
|
| + id result = ExecuteJavaScript(script);
|
| + EXPECT_TRUE(result) << " in script: " << base::SysNSStringToUTF8(script);
|
| + EXPECT_EQ(expected_value, [result intValue])
|
| + << " in script: " << base::SysNSStringToUTF8(script);
|
| + }
|
| +
|
| + // Loads the test HTML containing 'foo' strings and invokes the JavaScript
|
| + // necessary to search for and highlight any matches. Note that the JavaScript
|
| + // sets the current index to the first visible occurence of 'foo'.
|
| + void SearchForFoo() {
|
| + LoadHtml(kHtmlWithFoos);
|
| +
|
| + // Assert the index and span count contain their initialized values
|
| + AssertJavaScriptValue(kJavaScriptIndex, -1);
|
| + AssertJavaScriptValue(kJavaScriptSpansLength, 0);
|
| +
|
| + // Search for 'foo'. Performing the search sets the index to point to the
|
| + // first visible occurence of 'foo'.
|
| + ExecuteJavaScript(kJavaScriptToSearchForFoo);
|
| + AssertJavaScriptValue(kJavaScriptIndex, 1);
|
| + AssertJavaScriptValue(kJavaScriptSpansLength, kNumberOfFoosInHtml);
|
| + }
|
| +
|
| + void SetUp() override {
|
| + ChromeWebTest::SetUp();
|
| + mockDelegate_.reset([[OCMockObject
|
| + niceMockForProtocol:@protocol(FindInPageControllerDelegate)] retain]);
|
| + findInPageController_.reset([[FindInPageController alloc]
|
| + initWithWebState:web_state()
|
| + delegate:mockDelegate_]);
|
| + }
|
| +
|
| + base::scoped_nsobject<FindInPageController> findInPageController_;
|
| + base::scoped_nsobject<id> mockDelegate_;
|
| +};
|
| +
|
| +// Performs a search, then calls |incrementIndex| to loop through the
|
| +// matches, ensuring that when the end is reached the index wraps back to zero.
|
| +TEST_F(FindInPageJsTest, IncrementIndex) {
|
| + SearchForFoo();
|
| +
|
| + // Increment index until it hits the max index.
|
| + for (int i = 2; i < kNumberOfFoosInHtml; i++) {
|
| + ExecuteJavaScript(kJavaScriptIncrementIndex);
|
| + AssertJavaScriptValue(kJavaScriptIndex, i);
|
| + }
|
| +
|
| + // Increment index one more time and it should wrap back to zero.
|
| + ExecuteJavaScript(kJavaScriptIncrementIndex);
|
| + AssertJavaScriptValue(kJavaScriptIndex, 0);
|
| +};
|
| +
|
| +// Performs a search, then calls |decrementIndex| to loop through the
|
| +// matches, ensuring that when the beginning is reached the index wraps back to
|
| +// the end of the page.
|
| +TEST_F(FindInPageJsTest, DecrementIndex) {
|
| + SearchForFoo();
|
| +
|
| + // Since the first visible 'foo' is at index 1, decrement once to get to zero.
|
| + ExecuteJavaScript(kJavaScriptDecrementIndex);
|
| + AssertJavaScriptValue(kJavaScriptIndex, 0);
|
| +
|
| + // Decrement index until it hits zero again. Note that the first time
|
| + // |decrementIndex| is called the index wraps from zero to the max index.
|
| + for (int i = kNumberOfFoosInHtml - 1; i >= 0; i--) {
|
| + ExecuteJavaScript(kJavaScriptDecrementIndex);
|
| + AssertJavaScriptValue(kJavaScriptIndex, i);
|
| + }
|
| +};
|
| +
|
| +// Performs a search, then calls |goNext| to loop through the visible matches,
|
| +// ensuring that hidden matches are skipped and that when the end is reached the
|
| +// index wraps back to the beginning of the page.
|
| +TEST_F(FindInPageJsTest, GoNext) {
|
| + SearchForFoo();
|
| +
|
| + // Since the first visible 'foo' is at index 1, and every other 'foo' is
|
| + // hidden, after calling goNext the index should be at 3.
|
| + ExecuteJavaScript(kJavaScriptGoNext);
|
| + AssertJavaScriptValue(kJavaScriptIndex, 3);
|
| +
|
| + // The next visible 'foo' is at index 5.
|
| + ExecuteJavaScript(kJavaScriptGoNext);
|
| + AssertJavaScriptValue(kJavaScriptIndex, 5);
|
| +
|
| + // Calling |goNext| again wraps around to the first visible foo.
|
| + ExecuteJavaScript(kJavaScriptGoNext);
|
| + AssertJavaScriptValue(kJavaScriptIndex, 1);
|
| +};
|
| +
|
| +// Performs a search, then calls |goPrev| to loop through the visible matches,
|
| +// ensuring that hidden matches are skipped and that when the beginning is
|
| +// reached the index wraps back to the end of the page.
|
| +TEST_F(FindInPageJsTest, GoPrev) {
|
| + SearchForFoo();
|
| +
|
| + // Calling |goPrev| will wrap around to the end of the page, and since the
|
| + // last 'foo' is hidden, we want |kNumberOfFoosInHtml| - 2.
|
| + ExecuteJavaScript(kJavaScriptGoPrev);
|
| + AssertJavaScriptValue(kJavaScriptIndex, 5);
|
| +
|
| + // Since every other 'foo' is hidden, the prior visible 'foo' is at index 3.
|
| + ExecuteJavaScript(kJavaScriptGoPrev);
|
| + AssertJavaScriptValue(kJavaScriptIndex, 3);
|
| +};
|
| +
|
| +TEST_F(FindInPageJsTest, NoneVisible) {
|
| + LoadHtml(kHtmlWithNoVisibleFoos);
|
| +
|
| + // Assert the index and span count contain their initialized values
|
| + AssertJavaScriptValue(kJavaScriptIndex, -1);
|
| + AssertJavaScriptValue(kJavaScriptSpansLength, 0);
|
| +
|
| + // Search for 'foo'. Performing the search sets the index to point to 0 since
|
| + // there are no visible occurrences of 'foo'.
|
| + ExecuteJavaScript(kJavaScriptToSearchForFoo);
|
| + AssertJavaScriptValue(kJavaScriptIndex, 0);
|
| + AssertJavaScriptValue(kJavaScriptSpansLength, 6);
|
| +
|
| + ExecuteJavaScript(kJavaScriptGoPrev);
|
| + AssertJavaScriptValue(kJavaScriptIndex, 0);
|
| +
|
| + ExecuteJavaScript(kJavaScriptGoNext);
|
| + AssertJavaScriptValue(kJavaScriptIndex, 0);
|
| +}
|
| +
|
| +TEST_F(FindInPageJsTest, SearchForNonAscii) {
|
| + NSString* const kNonAscii = @"รก";
|
| + NSString* const htmlFormat = @"<html>"
|
| + "<meta charset=\"UTF-8\">"
|
| + "<body>%@</body>"
|
| + "</html>";
|
| + LoadHtml([NSString stringWithFormat:htmlFormat, kNonAscii]);
|
| + // Assert the index and span count contain their initialized values.
|
| + AssertJavaScriptValue(kJavaScriptIndex, -1);
|
| + AssertJavaScriptValue(kJavaScriptSpansLength, 0);
|
| +
|
| + // Search for the non-Ascii value. Performing the search sets the index to
|
| + // point to the first visible occurence of the non-Ascii.
|
| + NSString* result = ExecuteJavaScript([NSString
|
| + stringWithFormat:@"__gCrWeb.findInPage.highlightWord('%@', false, 1000)",
|
| + kNonAscii]);
|
| + DCHECK(result);
|
| + AssertJavaScriptValue(kJavaScriptIndex, 0);
|
| + AssertJavaScriptValue(kJavaScriptSpansLength, 1);
|
| +}
|
| +
|
| +} // namespace
|
|
|