Commit b5af8188 authored by Olivier Robin's avatar Olivier Robin Committed by Commit Bot

Add tests for form_autofill_utils

FindChildText, FindChildTextWithIgnoreList, InferLabelFromDivTableTest
sometimes have behavior that don't match the documentation.
Add some tests to capture these scenarios so they can be fixed in a
future CL.

Bug: 796918
Change-Id: I02ecb156149c8bd82470beaeff5ae2075710e380
Reviewed-on: https://chromium-review.googlesource.com/840020
Commit-Queue: Olivier Robin <olivierrobin@chromium.org>
Reviewed-by: default avatarSylvain Defresne <sdefresne@chromium.org>
Reviewed-by: default avatarSebastien Seguin-Gagnon <sebsg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#525983}
parent 915a3e2f
......@@ -402,6 +402,7 @@ if (!is_ios) {
sources = [
"autofill/content/browser/risk/fingerprint_browsertest.cc",
"autofill/content/renderer/form_autofill_util_browsertest.cc",
"autofill/content/renderer/password_form_conversion_utils_browsertest.cc",
"dom_distiller/content/browser/distillable_page_utils_browsertest.cc",
"dom_distiller/content/browser/distiller_page_web_contents_browsertest.cc",
......
......@@ -1831,5 +1831,17 @@ base::string16 FindChildText(const WebNode& node) {
return FindChildTextWithIgnoreList(node, std::set<WebNode>());
}
base::string16 FindChildTextWithIgnoreListForTesting(
const WebNode& node,
const std::set<WebNode>& divs_to_skip) {
return FindChildTextWithIgnoreList(node, divs_to_skip);
}
base::string16 InferLabelForElementForTesting(
const WebFormControlElement& element,
const std::vector<base::char16>& stop_words) {
return InferLabelForElement(element, stop_words);
}
} // namespace form_util
} // namespace autofill
......@@ -7,6 +7,7 @@
#include <stddef.h>
#include <set>
#include <vector>
#include "base/macros.h"
......@@ -278,6 +279,14 @@ void PreviewSuggestion(const base::string16& suggestion,
// Whitespace is trimmed from text accumulated at descendant nodes.
base::string16 FindChildText(const blink::WebNode& node);
// Exposed for testing purpose
base::string16 FindChildTextWithIgnoreListForTesting(
const blink::WebNode& node,
const std::set<blink::WebNode>& divs_to_skip);
base::string16 InferLabelForElementForTesting(
const blink::WebFormControlElement& element,
const std::vector<base::char16>& stop_words);
} // namespace form_util
} // namespace autofill
......
// Copyright (c) 2017 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.
#include "components/autofill/content/renderer/form_autofill_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/test/render_view_test.h"
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/WebVector.h"
#include "third_party/WebKit/public/web/WebDocument.h"
#include "third_party/WebKit/public/web/WebElement.h"
#include "third_party/WebKit/public/web/WebElementCollection.h"
#include "third_party/WebKit/public/web/WebFormControlElement.h"
#include "third_party/WebKit/public/web/WebFormElement.h"
#include "third_party/WebKit/public/web/WebInputElement.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebSelectElement.h"
using blink::WebDocument;
using blink::WebElement;
using blink::WebFormControlElement;
using blink::WebFormElement;
using blink::WebInputElement;
using blink::WebLocalFrame;
using blink::WebSelectElement;
using blink::WebString;
using blink::WebVector;
struct AutofillFieldUtilCase {
const char* description;
const char* html;
const char* expected_label;
};
const char kElevenChildren[] =
"<div id='target'>"
"<div>child0</div>"
"<div>child1</div>"
"<div>child2</div>"
"<div>child3</div>"
"<div>child4</div>"
"<div>child5</div>"
"<div>child6</div>"
"<div>child7</div>"
"<div>child8</div>"
"<div>child9</div>"
"<div>child10</div>"
"</div>";
const char kElevenChildrenExpected[] =
"child0child1child2child3child4child5child6child7child8";
const char kElevenChildrenNested[] =
"<div id='target'>"
"<div>child0"
"<div>child1"
"<div>child2"
"<div>child3"
"<div>child4"
"<div>child5"
"<div>child6"
"<div>child7"
"<div>child8"
"<div>child9"
"<div>child10"
"</div></div></div></div></div></div></div></div></div></div></div></div>";
// Take 10 elements -1 for target element, -1 as text is a leaf element.
const char kElevenChildrenNestedExpected[] = "child0child1child2child3child4";
const char kSkipElement[] =
"<div id='target'>"
"<div>child0</div>"
"<div class='skip'>child1</div>"
"<div>child2</div>"
"</div>";
// TODO(crbug.com/796918): Should be child0child2
const char kSkipElementExpected[] = "child0";
const char kDivTableExample1[] =
"<div>"
"<div>label</div><div><input id='target'/></div>"
"</div>";
const char kDivTableExample1Expected[] = "label";
const char kDivTableExample2[] =
"<div>"
"<div>label</div>"
"<div>should be skipped<input/></div>"
"<div><input id='target'/></div>"
"</div>";
const char kDivTableExample2Expected[] = "label";
const char kDivTableExample3[] =
"<div>"
"<div>should be skipped<input/></div>"
"<div>label</div>"
"<div><input id='target'/></div>"
"</div>";
const char kDivTableExample3Expected[] = "label";
const char kDivTableExample4[] =
"<div>"
"<div>should be skipped<input/></div>"
"label"
"<div><input id='target'/></div>"
"</div>";
// TODO(crbug.com/796918): Should be label
const char kDivTableExample4Expected[] = "";
const char kDivTableExample5[] =
"<div>"
"<div>label<div><input id='target'/></div>behind</div>"
"</div>";
// TODO(crbug.com/796918): Should be label
const char kDivTableExample5Expected[] = "labelbehind";
const char kDivTableExample6[] =
"<div>"
"<div>label<div><div>-<div><input id='target'/></div></div>"
"</div>";
// TODO(crbug.com/796918): Should be "label" or "label-"
const char kDivTableExample6Expected[] = "";
class FormAutofillUtilsTest : public content::RenderViewTest {
public:
FormAutofillUtilsTest() : content::RenderViewTest() {}
~FormAutofillUtilsTest() override {}
};
TEST_F(FormAutofillUtilsTest, FindChildTextTest) {
static const AutofillFieldUtilCase test_cases[] = {
{"simple test", "<div id='target'>test</div>", "test"},
{"Concatenate test", "<div id='target'><span>one</span>two</div>",
"onetwo"},
// TODO(crbug.com/796918): should be "onetwo"
{"Ignore input", "<div id='target'>one<input value='test'/>two</div>",
"one"},
{"Trim", "<div id='target'> one<span>two </span></div>", "onetwo"},
{"eleven children", kElevenChildren, kElevenChildrenExpected},
// TODO(crbug.com/796918): Depth is only 5 elements
{"eleven children nested", kElevenChildrenNested,
kElevenChildrenNestedExpected},
};
for (auto test_case : test_cases) {
SCOPED_TRACE(test_case.description);
LoadHTML(test_case.html);
WebLocalFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame);
WebElement target = web_frame->GetDocument().GetElementById("target");
ASSERT_FALSE(target.IsNull());
EXPECT_EQ(base::UTF8ToUTF16(test_case.expected_label),
autofill::form_util::FindChildText(target));
}
}
TEST_F(FormAutofillUtilsTest, FindChildTextSkipElementTest) {
static const AutofillFieldUtilCase test_cases[] = {
{"Skip div element", kSkipElement, kSkipElementExpected},
};
for (auto test_case : test_cases) {
SCOPED_TRACE(test_case.description);
LoadHTML(test_case.html);
WebLocalFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame);
WebElement target = web_frame->GetDocument().GetElementById("target");
ASSERT_FALSE(target.IsNull());
WebVector<WebElement> web_to_skip =
web_frame->GetDocument().QuerySelectorAll("div[class='skip']");
std::set<blink::WebNode> to_skip;
for (size_t i = 0; i < web_to_skip.size(); ++i) {
to_skip.insert(web_to_skip[i]);
}
EXPECT_EQ(base::UTF8ToUTF16(test_case.expected_label),
autofill::form_util::FindChildTextWithIgnoreListForTesting(
target, to_skip));
}
}
TEST_F(FormAutofillUtilsTest, InferLabelForElementTest) {
std::vector<base::char16> stop_words;
stop_words.push_back(static_cast<base::char16>('-'));
static const AutofillFieldUtilCase test_cases[] = {
{"DIV table test 1", kDivTableExample1, kDivTableExample1Expected},
{"DIV table test 2", kDivTableExample2, kDivTableExample2Expected},
{"DIV table test 3", kDivTableExample3, kDivTableExample3Expected},
{"DIV table test 4", kDivTableExample4, kDivTableExample4Expected},
{"DIV table test 5", kDivTableExample5, kDivTableExample5Expected},
{"DIV table test 6", kDivTableExample6, kDivTableExample6Expected},
};
for (auto test_case : test_cases) {
SCOPED_TRACE(test_case.description);
LoadHTML(test_case.html);
WebLocalFrame* web_frame = GetMainFrame();
ASSERT_NE(nullptr, web_frame);
WebElement target = web_frame->GetDocument().GetElementById("target");
ASSERT_FALSE(target.IsNull());
const WebFormControlElement form_target =
target.ToConst<WebFormControlElement>();
ASSERT_FALSE(form_target.IsNull());
EXPECT_EQ(base::UTF8ToUTF16(test_case.expected_label),
autofill::form_util::InferLabelForElementForTesting(form_target,
stop_words));
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment