chromium/chrome/renderer/autofill/form_autofill_browsertest.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include <stddef.h>

#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "base/feature_list.h"
#include "base/format_macros.h"
#include "base/ranges/algorithm.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/test/base/chrome_render_view_test.h"
#include "components/autofill/content/renderer/autofill_agent_test_api.h"
#include "components/autofill/content/renderer/autofill_renderer_test.h"
#include "components/autofill/content/renderer/form_autofill_util.h"
#include "components/autofill/content/renderer/form_cache.h"
#include "components/autofill/content/renderer/test_utils.h"
#include "components/autofill/core/common/autocomplete_parsing_util.h"
#include "components/autofill/core/common/autofill_data_validation.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/field_data_manager.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_data_test_api.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/autofill/core/common/mojom/autofill_types.mojom-shared.h"
#include "components/autofill/core/common/unique_ids.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_vector.h"
#include "third_party/blink/public/web/web_autofill_state.h"
#include "third_party/blink/public/web/web_document.h"
#include "third_party/blink/public/web/web_element.h"
#include "third_party/blink/public/web/web_element_collection.h"
#include "third_party/blink/public/web/web_form_control_element.h"
#include "third_party/blink/public/web/web_form_element.h"
#include "third_party/blink/public/web/web_input_element.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_script_source.h"
#include "third_party/blink/public/web/web_select_element.h"
#include "third_party/blink/public/web/web_select_list_element.h"

#if BUILDFLAG(IS_WIN)
#include "third_party/blink/public/web/win/web_font_rendering.h"
#endif

ASCIIToUTF16;
WebAutofillState;
WebDocument;
WebElement;
WebFormControlElement;
WebFormElement;
WebInputElement;
WebLocalFrame;
WebSelectElement;
WebString;
WebVector;
_;
ElementsAre;
Field;
Optional;
Pair;
Property;

namespace autofill::form_util {
namespace {

struct AutofillFieldCase {};

struct WebElementDescriptor {};

const char kFormHtml[] =;

// This constant uses a mixed-case title tag to be sure that the title match is
// not case-sensitive. Other tests in this file use an all-lower title tag.
const char kUnownedFormHtml[] =;

// This constant has no title tag, and should be passed to
// LoadHTMLWithURLOverride to test the detection of unowned forms by URL.
const char kUnownedUntitledFormHtml[] =;

// This constant does not have a title tag, but should match an unowned form
// anyway because it is not English.
const char kUnownedNonEnglishFormHtml[] =;

std::string RetrievalMethodToString(
    const WebElementDescriptor::RetrievalMethod& method) {}

bool ClickElement(const WebDocument& document,
                  const WebElementDescriptor& element_descriptor) {}

void ApplyFieldsAction(
    const blink::WebDocument& document,
    base::span<const FormFieldData> fields,
    mojom::ActionPersistence action_persistence,
    mojom::FormActionType action_type = mojom::FormActionType::kFill) {}

constexpr CallTimerState kCallTimerStateDummy =;

FormData FindForm(const blink::WebFormControlElement& element) {}

class FormAutofillTest : public test::AutofillRendererTest {};

// We should be able to extract a normal text field.
TEST_F(FormAutofillTest, WebFormControlElementToFormField) {}

// We should be able to extract a text field with autocomplete="off".
TEST_F(FormAutofillTest, WebFormControlElementToFormFieldAutocompleteOff) {}

// We should be able to extract a text field with maxlength specified.
TEST_F(FormAutofillTest, WebFormControlElementToFormFieldMaxLength) {}

// We should be able to extract a text field that has been autofilled.
TEST_F(FormAutofillTest, WebFormControlElementToFormFieldAutofilled) {}

// We should be able to extract a radio or a checkbox field that has been
// autofilled.
TEST_F(FormAutofillTest, WebFormControlElementToClickableFormField) {}

// We should be able to extract a <select> field.
TEST_F(FormAutofillTest, WebFormControlElementToFormFieldSelect) {}

// We copy extra attributes for the select field.
TEST_F(FormAutofillTest,
       WebFormControlElementToFormFieldSelect_ExtraAttributes) {}

// When faced with <select> field with *many* options, we should trim them to a
// reasonable number.
TEST_F(FormAutofillTest, WebFormControlElementToFormFieldLongSelect) {}

// Test that we use the aria-label as the content if the <option> has no text.
TEST_F(FormAutofillTest, WebFormControlElementToFormFieldSelectListAriaLabel) {}

// Test that the content for the <option> can be computed when the <option>s
// have nested HTML nodes.
TEST_F(FormAutofillTest,
       WebFormControlElementToFormFieldSelectListNestedNodes) {}

// We should be able to extract a <textarea> field.
TEST_F(FormAutofillTest, WebFormControlElementToFormFieldTextArea) {}

// We should be able to extract an <input type=month> field.
TEST_F(FormAutofillTest, WebFormControlElementToFormFieldMonthInput) {}

// We should be able to extract password fields.
TEST_F(FormAutofillTest, WebFormControlElementToPasswordFormField) {}

// We should be able to extract the autocompletetype attribute.
TEST_F(FormAutofillTest, WebFormControlElementToFormFieldAutocompletetype) {}

TEST_F(FormAutofillTest, DetectTextDirectionFromDirectStyle) {}

TEST_F(FormAutofillTest, DetectTextDirectionFromDirectDIRAttribute) {}

TEST_F(FormAutofillTest, DetectTextDirectionFromParentStyle) {}

TEST_F(FormAutofillTest, DetectTextDirectionFromParentDIRAttribute) {}

TEST_F(FormAutofillTest, DetectTextDirectionWhenStyleAndDIRAttributeMixed) {}

TEST_F(FormAutofillTest, TextAlignOverridesDirection) {}

TEST_F(FormAutofillTest,
       DetectTextDirectionWhenParentHasBothDIRAttributeAndStyle) {}

TEST_F(FormAutofillTest, DetectTextDirectionWhenAncestorHasInlineStyle) {}

TEST_F(FormAutofillTest, WebFormElementToFormData) {}

TEST_F(FormAutofillTest, WebFormElementConsiderNonControlLabelableElements) {}

// We should not be able to serialize a form with too many fillable fields.
TEST_F(FormAutofillTest, WebFormElementToFormData_TooManyFields) {}

// Tests that the `should_autocomplete` is set to false for all the fields when
// an autocomplete='off' attribute is set for the form in HTML.
TEST_F(FormAutofillTest, WebFormElementToFormData_AutocompleteOff_OnForm) {}

// Tests that the `should_autocomplete` is set to false only for the field
// which has an autocomplete='off' attribute set for it in HTML.
TEST_F(FormAutofillTest, WebFormElementToFormData_AutocompleteOff_OnField) {}

// `should_autocomplete` must be set to false for the field with
// autocomplete='one-time-code' attribute set in HTML.
TEST_F(FormAutofillTest, WebFormElementToFormData_AutocompleteOff_OneTimeCode) {}

// Tests CSS classes are set.
TEST_F(FormAutofillTest, WebFormElementToFormData_CssClasses) {}

// Tests id attributes are set.
TEST_F(FormAutofillTest, WebFormElementToFormData_IdAttributes) {}

TEST_F(FormAutofillTest, ExtractForms) {}

TEST_F(FormAutofillTest, ExtractMultipleForms) {}

TEST_F(FormAutofillTest, OnlyExtractNewForms) {}

// We should not report additional forms for empty forms.
TEST_F(FormAutofillTest, ExtractFormsNoFields) {}

TEST_F(FormAutofillTest, WebFormElementToFormData_Autocomplete) {}

TEST_F(FormAutofillTest, FindFormForInputElement) {}

TEST_F(FormAutofillTest, FindFormForInputElementForUnownedForm) {}

TEST_F(FormAutofillTest, FindFormForTextAreaElement) {}

TEST_F(FormAutofillTest, FindFormForTextAreaElementForUnownedForm) {}

// Test regular FillForm function.
TEST_F(FormAutofillTest, FillForm) {}

TEST_F(FormAutofillTest, FillFormForUnownedForm) {}

TEST_F(FormAutofillTest, FillFormForUnownedUntitledForm) {}

TEST_F(FormAutofillTest, FillFormForUnownedNonEnglishForm) {}

TEST_F(FormAutofillTest, FillFormForUnownedNonASCIIForm) {}

TEST_F(FormAutofillTest, PreviewFormX) {}

TEST_F(FormAutofillTest, PreviewFormForUnownedForm) {}

TEST_F(FormAutofillTest, PreviewFormForUnownedUntitledForm) {}

TEST_F(FormAutofillTest, PreviewFormForUnownedNonEnglishForm) {}


TEST_F(FormAutofillTest, Labels) {}

// <label for=fieldId> elements are correctly assigned to their inputs. Multiple
// labels are separated with a space.
// TODO(crbug.com/40229922): Simplify the test using `ExpectLabels()`. This
// requires some refactoring of the fixture, as only owned forms are supported
// at the moment.
TEST_F(FormAutofillTest, LabelForAttribute) {}

// Tests that when a label is assigned to an input, text behind it is considered
// as a fallback.
// The label is assigned to the input without the for-attribute, by declaring it
// it inside the label.
TEST_F(FormAutofillTest, LabelTextBehindInput) {}

TEST_F(FormAutofillTest, LabelsWithSpans) {}

// This test is different from FormAutofillTest.Labels in that the label
// elements for= attribute is set to the name of the form control element it is
// a label for instead of the id of the form control element.  This is invalid
// because the for= attribute must be set to the id of the form control element;
// however, current label parsing code will extract the text from the previous
// label element and apply it to the following input field.
TEST_F(FormAutofillTest, InvalidLabels) {}

// This test has three form control elements, only one of which has a label
// element associated with it.
TEST_F(FormAutofillTest, OneLabelElement) {}

TEST_F(FormAutofillTest, LabelsInferredFromText) {}

TEST_F(FormAutofillTest, LabelsInferredFromParagraph) {}

TEST_F(FormAutofillTest, LabelsInferredFromBold) {}

TEST_F(FormAutofillTest, LabelsInferredPriorToImgOrBr) {}

TEST_F(FormAutofillTest, LabelsInferredFromTableCell) {}

TEST_F(FormAutofillTest, LabelsInferredFromTableCellTH) {}

TEST_F(FormAutofillTest, LabelsInferredFromTableCellNested) {}

TEST_F(FormAutofillTest, LabelsInferredFromTableEmptyTDs) {}

TEST_F(FormAutofillTest, LabelsInferredFromPreviousTD) {}

// <script>, <noscript> and <option> tags are excluded when the labels are
// inferred.
// Also <!-- comment --> is excluded.
TEST_F(FormAutofillTest, LabelsInferredFromTableWithSpecialElements) {}

TEST_F(FormAutofillTest, LabelsInferredFromTableLabels) {}

TEST_F(FormAutofillTest, LabelsInferredFromTableTDInterveningElements) {}

// Verify that we correctly infer labels when the label text spans multiple
// adjacent HTML elements, not separated by whitespace.
TEST_F(FormAutofillTest, LabelsInferredFromTableAdjacentElements) {}

// Verify that we correctly infer labels when the label text resides in the
// previous row.
TEST_F(FormAutofillTest, LabelsInferredFromTableRow) {}

// Verify that we correctly infer labels when enclosed within a list item.
TEST_F(FormAutofillTest, LabelsInferredFromListItem) {}

TEST_F(FormAutofillTest, LabelsInferredFromDefinitionList) {}

TEST_F(FormAutofillTest, LabelsInferredWithSameName) {}

TEST_F(FormAutofillTest, LabelsInferredWithImageTags) {}

TEST_F(FormAutofillTest, LabelsInferredFromDivTable) {}

TEST_F(FormAutofillTest, LabelsInferredFromDivSiblingTable) {}

TEST_F(FormAutofillTest, LabelsInferredFromLabelInDivTable) {}

TEST_F(FormAutofillTest, LabelsInferredFromDefinitionListRatherThanDivTable) {}

TEST_F(FormAutofillTest, FillFormMaxLength) {}

TEST_F(FormAutofillTest, FillFormMaxLengthForUnownedForm) {}

// This test uses negative values of the maxlength attribute for input elements.
// In this case, the maxlength of the input elements is set to the default
// maxlength (defined in WebKit.)
TEST_F(FormAutofillTest, FillFormNegativeMaxLength) {}

TEST_F(FormAutofillTest, FillFormNegativeMaxLengthForUnownedForm) {}

TEST_F(FormAutofillTest, FillFormEmptyName) {}

TEST_F(FormAutofillTest, FillFormEmptyNameForUnownedForm) {}

TEST_F(FormAutofillTest, FillFormEmptyFormNames) {}

TEST_F(FormAutofillTest, FillFormEmptyFormNamesForUnownedForm) {}

TEST_F(FormAutofillTest, ThreePartPhone) {}

TEST_F(FormAutofillTest, MaxLengthFields) {}

// This test re-creates the experience of typing in a field then selecting a
// profile from the Autofill suggestions popup.  The field that is being typed
// into should be filled even though it's not technically empty.
TEST_F(FormAutofillTest, FillFormNonEmptyField) {}

TEST_F(FormAutofillTest, FillFormNonEmptyFieldsWithDefaultValues) {}

TEST_F(FormAutofillTest, FillFormModifyValues) {}

TEST_F(FormAutofillTest, FillFormModifyInitiatingValue) {}

TEST_F(FormAutofillTest, FillFormJSModifiesUserInputValue) {}

TEST_F(FormAutofillTest, FillFormNonEmptyFieldsWithPlaceholderValues) {}

TEST_F(FormAutofillTest, FillFormNonEmptyFieldForUnownedForm) {}

TEST_F(FormAutofillTest, UndoAutofill) {}

TEST_F(FormAutofillTest, ClearPreviewedElements) {}

TEST_F(FormAutofillTest, ClearPreviewedFormWithElementForUnownedForm) {}

TEST_F(FormAutofillTest, ClearPreviewedFormWithNonEmptyInitiatingNode) {}

TEST_F(FormAutofillTest,
       ClearPreviewedFormWithNonEmptyInitiatingNodeForUnownedForm) {}

TEST_F(FormAutofillTest, ClearPreviewedFormWithAutofilledInitiatingNode) {}

TEST_F(FormAutofillTest,
       ClearPreviewedFormWithAutofilledInitiatingNodeForUnownedForm) {}

// If we have multiple labels per id, the labels concatenated into label string.
TEST_F(FormAutofillTest, MultipleLabelsPerElement) {}

TEST_F(FormAutofillTest, ClickElement) {}

TEST_F(FormAutofillTest, SelectOneAsText) {}

TEST_F(FormAutofillTest, UnownedFormElementsToFormDataWithoutForm) {}

TEST_F(FormAutofillTest, UnownedFormElementsToFormDataWithForm) {}

TEST_F(FormAutofillTest, FormlessForms) {}

TEST_F(FormAutofillTest, FormCache_ExtractNewForms) {}

TEST_F(FormAutofillTest, AriaLabelAndDescription) {}

TEST_F(FormAutofillTest, AriaLabelAndDescription2) {}

}  // namespace
}  // namespace autofill::form_util