#include "ui/views/controls/textfield/textfield_unittest.h"
#include <stddef.h>
#include <stdint.h>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/command_line.h"
#include "base/format_macros.h"
#include "base/i18n/rtl.h"
#include "base/memory/raw_ptr.h"
#include "base/pickle.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 "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/base/clipboard/test/test_clipboard.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"
#include "ui/base/emoji/emoji_panel_helper.h"
#include "ui/base/ime/constants.h"
#include "ui/base/ime/ime_key_event_dispatcher.h"
#include "ui/base/ime/init/input_method_factory.h"
#include "ui/base/ime/input_method_base.h"
#include "ui/base/ime/text_edit_commands.h"
#include "ui/base/ime/text_input_client.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h"
#include "ui/base/ui_base_switches_util.h"
#include "ui/events/event.h"
#include "ui/events/event_processor.h"
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/test/event_generator.h"
#include "ui/events/test/keyboard_layout.h"
#include "ui/gfx/render_text.h"
#include "ui/gfx/render_text_test_api.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/touch_selection/touch_selection_metrics.h"
#include "ui/views/accessibility/atomic_view_ax_tree_manager.h"
#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/accessibility/view_ax_platform_node_delegate.h"
#include "ui/views/border.h"
#include "ui/views/controls/textfield/textfield_model.h"
#include "ui/views/controls/textfield/textfield_test_api.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/style/platform_style.h"
#include "ui/views/test/ax_event_counter.h"
#include "ui/views/test/test_views_delegate.h"
#include "ui/views/test/widget_test.h"
#include "ui/views/views_features.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_utils.h"
#include "url/gurl.h"
#if BUILDFLAG(IS_WIN)
#include "base/win/windows_version.h"
#endif
#if BUILDFLAG(IS_LINUX)
#include "ui/linux/fake_linux_ui.h"
#include "ui/linux/linux_ui.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ui/aura/window.h"
#include "ui/wm/core/ime_util_chromeos.h"
#endif
#if BUILDFLAG(IS_MAC)
#include "ui/base/cocoa/secure_password_input.h"
#include "ui/base/cocoa/text_services_context_menu.h"
#endif
#if BUILDFLAG(IS_OZONE)
#include "ui/events/ozone/layout/keyboard_layout_engine_test_utils.h"
#endif
namespace views::test {
const char16_t kHebrewLetterSamekh = …;
ui::GestureEvent
CreateTestGestureEvent(int x, int y, const ui::GestureEventDetails& details) { … }
class TextfieldDestroyerController : public TextfieldController { … };
class TextfieldFocuser : public View { … };
BEGIN_METADATA(…)
class MockInputMethod : public ui::InputMethodBase { … };
MockInputMethod::MockInputMethod() : … { … }
MockInputMethod::~MockInputMethod() = default;
ui::EventDispatchDetails MockInputMethod::DispatchKeyEvent(ui::KeyEvent* key) { … }
void MockInputMethod::OnTextInputTypeChanged(ui::TextInputClient* client) { … }
void MockInputMethod::CancelComposition(const ui::TextInputClient* client) { … }
bool MockInputMethod::IsCandidatePopupOpen() const { … }
void MockInputMethod::OnWillChangeFocusedClient(
ui::TextInputClient* focused_before,
ui::TextInputClient* focused) { … }
void MockInputMethod::Clear() { … }
void MockInputMethod::SetCompositionTextForNextKey(
const ui::CompositionText& composition) { … }
void MockInputMethod::SetResultTextForNextKey(const std::u16string& result) { … }
void MockInputMethod::ClearStates() { … }
bool MockInputMethod::HasComposition() { … }
void MockInputMethod::ClearComposition() { … }
class TestTextfield : public views::Textfield { … };
BEGIN_METADATA(…)
TextfieldTest::TextfieldTest() { … }
TextfieldTest::~TextfieldTest() = default;
void TextfieldTest::SetUp() { … }
void TextfieldTest::TearDown() { … }
ui::ClipboardBuffer TextfieldTest::GetAndResetCopiedToClipboard() { … }
std::u16string TextfieldTest::GetClipboardText(
ui::ClipboardBuffer clipboard_buffer) { … }
void TextfieldTest::SetClipboardText(ui::ClipboardBuffer clipboard_buffer,
const std::u16string& text) { … }
void TextfieldTest::ContentsChanged(Textfield* sender,
const std::u16string& new_contents) { … }
void TextfieldTest::OnBeforeUserAction(Textfield* sender) { … }
void TextfieldTest::OnAfterUserAction(Textfield* sender) { … }
void TextfieldTest::OnAfterCutOrCopy(ui::ClipboardBuffer clipboard_type) { … }
void TextfieldTest::InitTextfield(int count) { … }
void TextfieldTest::PrepareTextfieldsInternal(int count,
Textfield* textfield,
View* container,
gfx::Rect bounds) { … }
ui::MenuModel* TextfieldTest::GetContextMenuModel() { … }
bool TextfieldTest::TestingNativeMac() const { … }
bool TextfieldTest::TestingNativeCrOs() const { … }
void TextfieldTest::SendKeyPress(ui::KeyboardCode key_code, int flags) { … }
void TextfieldTest::SendKeyEvent(ui::KeyboardCode key_code,
bool alt,
bool shift,
bool control_or_command,
bool caps_lock) { … }
void TextfieldTest::SendKeyEvent(ui::KeyboardCode key_code,
bool shift,
bool control_or_command) { … }
void TextfieldTest::SendKeyEvent(ui::KeyboardCode key_code) { … }
void TextfieldTest::SendKeyEvent(char16_t ch) { … }
void TextfieldTest::SendKeyEvent(char16_t ch, int flags) { … }
void TextfieldTest::SendKeyEvent(char16_t ch, int flags, bool from_vk) { … }
void TextfieldTest::DispatchMockInputMethodKeyEvent() { … }
void TextfieldTest::SendHomeEvent(bool shift) { … }
void TextfieldTest::SendEndEvent(bool shift) { … }
void TextfieldTest::SendWordEvent(ui::KeyboardCode key, bool shift) { … }
void TextfieldTest::SendAlternateCut() { … }
void TextfieldTest::SendAlternateCopy() { … }
void TextfieldTest::SendAlternatePaste() { … }
View* TextfieldTest::GetFocusedView() { … }
int TextfieldTest::GetCursorPositionX(int cursor_pos) { … }
int TextfieldTest::GetCursorYForTesting() { … }
gfx::Rect TextfieldTest::GetCursorBounds() { … }
gfx::Rect TextfieldTest::GetCursorBounds(const gfx::SelectionModel& sel) { … }
gfx::Rect TextfieldTest::GetDisplayRect() { … }
gfx::Rect TextfieldTest::GetCursorViewRect() { … }
void TextfieldTest::MouseClick(const gfx::Rect bound, int x_offset) { … }
void TextfieldTest::NonClientMouseClick() { … }
void TextfieldTest::VerifyTextfieldContextMenuContents(
bool textfield_has_selection,
bool can_undo,
ui::MenuModel* menu) { … }
void TextfieldTest::PressMouseButton(ui::EventFlags mouse_button_flags) { … }
void TextfieldTest::ReleaseMouseButton(ui::EventFlags mouse_button_flags) { … }
void TextfieldTest::PressLeftMouseButton() { … }
void TextfieldTest::ReleaseLeftMouseButton() { … }
void TextfieldTest::ClickLeftMouseButton() { … }
void TextfieldTest::ClickRightMouseButton() { … }
void TextfieldTest::DragMouseTo(const gfx::Point& where) { … }
void TextfieldTest::MoveMouseTo(const gfx::Point& where) { … }
void TextfieldTest::TapAtCursor(ui::EventPointerType pointer_type) { … }
TextfieldTestApi TextfieldTest::GetTextfieldTestApi() { … }
MockInputMethod* TextfieldTest::input_method() { … }
TextfieldModel* TextfieldTest::model() { … }
TEST_F(TextfieldTest, ModelChangesTest) { … }
TEST_F(TextfieldTest, Scroll) { … }
TEST_F(TextfieldTest, ScrollUpdatesScrollXAccessibilityAttribute) { … }
TEST_F(TextfieldTest,
SetTextWithoutCaretBoundsChangeNotification_ModelEditHistory) { … }
TEST_F(TextfieldTest, KeyTest) { … }
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
TEST_F(TextfieldTest, KeyTestControlModifier) { … }
#endif
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
#define MAYBE_KeysWithModifiersTest …
#else
#define MAYBE_KeysWithModifiersTest …
#endif
TEST_F(TextfieldTest, MAYBE_KeysWithModifiersTest) { … }
TEST_F(TextfieldTest, ControlAndSelectTest) { … }
TEST_F(TextfieldTest, WordSelection) { … }
TEST_F(TextfieldTest, LineSelection) { … }
TEST_F(TextfieldTest, MoveUpDownAndModifySelection) { … }
TEST_F(TextfieldTest, MovePageUpDownAndModifySelection) { … }
TEST_F(TextfieldTest, MoveParagraphForwardBackwardAndModifySelection) { … }
TEST_F(TextfieldTest, ModifySelectionWithMultipleSelections) { … }
TEST_F(TextfieldTest, InsertionDeletionTest) { … }
TEST_F(TextfieldTest, DeletionWithSelection) { … }
TEST_F(TextfieldTest, DeletionWithMultipleSelections) { … }
TEST_F(TextfieldTest, DeletionWithEditCommands) { … }
TEST_F(TextfieldTest, PasswordTest) { … }
TEST_F(TextfieldTest, PasswordSelectWordTest) { … }
TEST_F(TextfieldTest, TextInputType_InsertionTest) { … }
TEST_F(TextfieldTest, ShouldDoLearning) { … }
TEST_F(TextfieldTest, TextInputType) { … }
TEST_F(TextfieldTest, OnKeyPress) { … }
TEST_F(TextfieldTest, OnKeyPressBinding) { … }
TEST_F(TextfieldTest, CursorMovement) { … }
TEST_F(TextfieldTest, CursorMovementWithMultipleSelections) { … }
TEST_F(TextfieldTest, ShouldShowCursor) { … }
#if BUILDFLAG(IS_MAC)
TEST_F(TextfieldTest, MacCursorAlphaTest) {
InitTextfield();
const int cursor_y = GetCursorYForTesting();
MoveMouseTo(gfx::Point(GetCursorPositionX(0), cursor_y));
ClickRightMouseButton();
EXPECT_TRUE(textfield_->HasFocus());
const float kOpaque = 1.0;
EXPECT_FLOAT_EQ(kOpaque, GetTextfieldTestApi().CursorLayerOpacity());
GetTextfieldTestApi().FlashCursor();
const float kAlmostTransparent = 1.0 / 255.0;
EXPECT_FLOAT_EQ(kAlmostTransparent,
GetTextfieldTestApi().CursorLayerOpacity());
GetTextfieldTestApi().FlashCursor();
EXPECT_FLOAT_EQ(kOpaque, GetTextfieldTestApi().CursorLayerOpacity());
const float kTransparent = 0.0;
GetTextfieldTestApi().SetCursorLayerOpacity(kTransparent);
ASSERT_FLOAT_EQ(kTransparent, GetTextfieldTestApi().CursorLayerOpacity());
GetTextfieldTestApi().UpdateCursorVisibility();
EXPECT_FLOAT_EQ(kOpaque, GetTextfieldTestApi().CursorLayerOpacity());
}
#endif
TEST_F(TextfieldTest, FocusTraversalTest) { … }
TEST_F(TextfieldTest, ContextMenuDisplayTest) { … }
TEST_F(TextfieldTest, DoubleAndTripleClickTest) { … }
TEST_F(TextfieldTest, SelectionOnRightClick) { … }
TEST_F(TextfieldTest, DragToSelect) { … }
TEST_F(TextfieldTest, DragUpOrDownSelectsToEnd) { … }
#if BUILDFLAG(IS_WIN)
TEST_F(TextfieldTest, DragAndDrop_AcceptDrop) {
InitTextfield();
textfield_->SetText(u"hello world");
ui::OSExchangeData data;
std::u16string string(u"string ");
data.SetString(string);
int formats = 0;
std::set<ui::ClipboardFormatType> format_types;
textfield_->SetEnabled(false);
EXPECT_FALSE(textfield_->GetDropFormats(&formats, &format_types));
EXPECT_EQ(0, formats);
EXPECT_TRUE(format_types.empty());
EXPECT_FALSE(textfield_->CanDrop(data));
textfield_->SetEnabled(true);
textfield_->SetReadOnly(true);
EXPECT_FALSE(textfield_->GetDropFormats(&formats, &format_types));
EXPECT_EQ(0, formats);
EXPECT_TRUE(format_types.empty());
EXPECT_FALSE(textfield_->CanDrop(data));
textfield_->SetReadOnly(false);
EXPECT_TRUE(textfield_->GetDropFormats(&formats, &format_types));
EXPECT_EQ(ui::OSExchangeData::STRING, formats);
EXPECT_TRUE(format_types.empty());
EXPECT_TRUE(textfield_->CanDrop(data));
gfx::PointF drop_point(GetCursorPositionX(6), 0);
ui::DropTargetEvent drop(
data, drop_point, drop_point,
ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_MOVE);
EXPECT_EQ(ui::DragDropTypes::DRAG_COPY | ui::DragDropTypes::DRAG_MOVE,
textfield_->OnDragUpdated(drop));
ui::mojom::DragOperation output_drag_op = ui::mojom::DragOperation::kNone;
auto cb = textfield_->GetDropCallback(drop);
std::move(cb).Run(drop, output_drag_op, nullptr);
EXPECT_EQ(ui::mojom::DragOperation::kCopy, output_drag_op);
EXPECT_EQ(u"hello string world", textfield_->GetText());
ui::OSExchangeData bad_data;
bad_data.SetFilename(base::FilePath(FILE_PATH_LITERAL("x")));
ui::ClipboardFormatType fmt = ui::ClipboardFormatType::BitmapType();
bad_data.SetPickledData(fmt, base::Pickle());
bad_data.SetFileContents(base::FilePath(L"x"), "x");
bad_data.SetHtml(std::u16string(u"x"), GURL("x.org"));
ui::DownloadFileInfo download(base::FilePath(), nullptr);
bad_data.provider().SetDownloadFileInfo(&download);
EXPECT_FALSE(textfield_->CanDrop(bad_data));
}
#endif
TEST_F(TextfieldTest, DragAndDrop_InitiateDrag) { … }
TEST_F(TextfieldTest, DragAndDrop_ToTheRight) { … }
TEST_F(TextfieldTest, DragAndDrop_ToTheLeft) { … }
TEST_F(TextfieldTest, DropCallbackCancelled) { … }
TEST_F(TextfieldTest, DragAndDrop_Canceled) { … }
TEST_F(TextfieldTest, ReadOnlyTest) { … }
TEST_F(TextfieldTest, TextInputClientTest) { … }
TEST_F(TextfieldTest, UndoRedoTest) { … }
#if !BUILDFLAG(IS_MAC)
TEST_F(TextfieldTest, RedoWithCtrlY) { … }
#endif
#if BUILDFLAG(IS_MAC)
TEST_F(TextfieldTest, Yank) {
InitTextfield(2);
textfield_->SetText(u"abcdef");
textfield_->SetSelectedRange(gfx::Range(2, 4));
SendKeyPress(ui::VKEY_Y, ui::EF_CONTROL_DOWN);
EXPECT_EQ(u"abef", textfield_->GetText());
EXPECT_EQ(gfx::Range(2), textfield_->GetSelectedRange());
SendKeyPress(ui::VKEY_K, ui::EF_CONTROL_DOWN);
EXPECT_EQ(u"ab", textfield_->GetText());
EXPECT_EQ(gfx::Range(2), textfield_->GetSelectedRange());
SendKeyPress(ui::VKEY_Y, ui::EF_CONTROL_DOWN);
SendKeyPress(ui::VKEY_Y, ui::EF_CONTROL_DOWN);
EXPECT_EQ(u"abefef", textfield_->GetText());
EXPECT_EQ(gfx::Range(6), textfield_->GetSelectedRange());
SendKeyEvent(ui::VKEY_BACK);
SendKeyPress(ui::VKEY_Y, ui::EF_CONTROL_DOWN);
EXPECT_EQ(u"abefeef", textfield_->GetText());
EXPECT_EQ(gfx::Range(7), textfield_->GetSelectedRange());
widget_->GetFocusManager()->AdvanceFocus(false);
EXPECT_EQ(2, GetFocusedView()->GetID());
Textfield* textfield2 = static_cast<Textfield*>(GetFocusedView());
EXPECT_TRUE(textfield2->GetText().empty());
textfield2->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
SendKeyPress(ui::VKEY_Y, ui::EF_CONTROL_DOWN);
EXPECT_EQ(u"ef", textfield2->GetText());
EXPECT_EQ(gfx::Range(2), textfield2->GetSelectedRange());
textfield2->SetText(u"hello");
textfield2->SetSelectedRange(gfx::Range(0));
SendKeyPress(ui::VKEY_K, ui::EF_CONTROL_DOWN);
EXPECT_TRUE(textfield2->GetText().empty());
textfield_->RequestFocus();
textfield_->SetSelectedRange(gfx::Range(0));
SendKeyPress(ui::VKEY_Y, ui::EF_CONTROL_DOWN);
EXPECT_EQ(u"efabefeef", textfield_->GetText());
}
#endif
TEST_F(TextfieldTest, CutCopyPaste) { … }
TEST_F(TextfieldTest, CutCopyPasteWithEditCommand) { … }
TEST_F(TextfieldTest, SelectWordFromEmptySelection) { … }
TEST_F(TextfieldTest, SelectWordFromNonEmptySelection) { … }
TEST_F(TextfieldTest, SelectWordFromNonAlphaNumericFragment) { … }
TEST_F(TextfieldTest, SelectWordFromWhitespaceFragment) { … }
TEST_F(TextfieldTest, SelectCommands) { … }
#if !BUILDFLAG(IS_MAC)
TEST_F(TextfieldTest, SelectCommandsFromTouchEvent) { … }
#endif
TEST_F(TextfieldTest, OvertypeMode) { … }
TEST_F(TextfieldTest, TextCursorDisplayTest) { … }
TEST_F(TextfieldTest, TextCursorDisplayInRTLTest) { … }
TEST_F(TextfieldTest, TextCursorPositionInRTLTest) { … }
TEST_F(TextfieldTest, TextCursorPositionInLTRTest) { … }
TEST_F(TextfieldTest, HitInsideTextAreaTest) { … }
TEST_F(TextfieldTest, HitOutsideTextAreaTest) { … }
TEST_F(TextfieldTest, HitOutsideTextAreaInRTLTest) { … }
TEST_F(TextfieldTest, OverflowTest) { … }
TEST_F(TextfieldTest, OverflowInRTLTest) { … }
TEST_F(TextfieldTest, PasswordProtected) { … }
TEST_F(TextfieldTest, CommitComposingTextTest) { … }
TEST_F(TextfieldTest, CommitEmptyComposingTextTest) { … }
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
TEST_F(TextfieldTest, SetCompositionFromExistingTextTest) { … }
#endif
TEST_F(TextfieldTest, GetCompositionCharacterBoundsTest) { … }
TEST_F(TextfieldTest, GetCompositionCharacterBounds_ComplexText) { … }
TEST_F(TextfieldTest, KeepInitiallySelectedWord) { … }
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
TEST_F(TextfieldTest, SelectionClipboard) { … }
TEST_F(TextfieldTest, SelectionClipboard_Password) { … }
#endif
TEST_F(TextfieldTest, TestLongPressInitiatesDragDrop) { … }
#if !BUILDFLAG(IS_MAC)
TEST_F(TextfieldTest, ScrollToAdjustDisplayOffset) { … }
TEST_F(TextfieldTest, TwoFingerScroll) { … }
TEST_F(TextfieldTest, ScrollToPlaceCursor) { … }
TEST_F(TextfieldTest, ScrollToPlaceCursorAdjustsDisplayOffset) { … }
TEST_F(TextfieldTest, TwoFingerScrollUpdate) { … }
TEST_F(TextfieldTest, LongPressSelection) { … }
TEST_F(TextfieldTest, LongPressDragSelectionLTRForward) { … }
TEST_F(TextfieldTest, LongPressDragSelectionLTRBackward) { … }
TEST_F(TextfieldTest, LongPressDragSelectionRTLForward) { … }
TEST_F(TextfieldTest, LongPressDragSelectionRTLBackward) { … }
TEST_F(TextfieldTest, DoubleTapSelection) { … }
TEST_F(TextfieldTest, TripleTapSelection) { … }
TEST_F(TextfieldTest, DoublePressDragSelection) { … }
TEST_F(TextfieldTest, TouchSelectionDraggingMetrics) { … }
#endif
TEST_F(TextfieldTest, GetTextfieldBaseline_FontFallbackTest) { … }
TEST_F(TextfieldTest, DestroyingTextfieldFromOnKeyEvent) { … }
TEST_F(TextfieldTest, CursorBlinkRestartsOnInsertOrReplace) { … }
TEST_F(TextfieldTest, InitialAccessibilityProperties) { … }
TEST_F(TextfieldTest, SetAccessibleNameNotifiesAccessibilityEvent) { … }
#if BUILDFLAG(IS_WIN)
TEST_F(TextfieldTest, AccessibilityAttributes) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(::features::kUiaProvider);
InitTextfield();
ViewAXPlatformNodeDelegate* delegate =
static_cast<ViewAXPlatformNodeDelegate*>(
&textfield_->GetViewAccessibility());
textfield_->GetViewAccessibility().EnsureAtomicViewAXTreeManager();
textfield_->SetText(u"this is the textfield");
textfield_->SetBounds(1, 2, 3, 4);
ui::AXNodeData actual =
delegate->GetAtomicViewAXTreeManagerForTesting()->GetRoot()->data();
EXPECT_EQ(ax::mojom::Role::kTextField, actual.role);
EXPECT_TRUE(actual.HasState(ax::mojom::State::kEditable) &&
actual.HasState(ax::mojom::State::kFocusable));
EXPECT_EQ(textfield_->GetAccessibleName(),
actual.GetString16Attribute(ax::mojom::StringAttribute::kName));
EXPECT_EQ(textfield_->GetText(),
actual.GetString16Attribute(ax::mojom::StringAttribute::kValue));
EXPECT_EQ(
textfield_->GetPlaceholderText(),
actual.GetString16Attribute(ax::mojom::StringAttribute::kPlaceholder));
EXPECT_EQ(static_cast<const int>(textfield_->GetSelectedRange().start()),
actual.GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart));
EXPECT_EQ(static_cast<const int>(textfield_->GetSelectedRange().end()),
actual.GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd));
EXPECT_EQ(gfx::Rect(1, 2, 3, 4),
gfx::ToEnclosingRect(actual.relative_bounds.bounds));
EXPECT_EQ(textfield_->GetBoundsInScreen(),
delegate->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
ui::AXClippingBehavior::kUnclipped, nullptr));
}
#endif
TEST_F(TextfieldTest, AccessiblePlaceholderTest) { … }
TEST_F(TextfieldTest, AccessibleTextSelectBound) { … }
TEST_F(TextfieldTest, AccessibleNameFromLabel) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(TextfieldTest, VirtualKeyboardFocusEnsureCaretNotInRect) {
InitTextfield();
aura::Window* root_window = GetRootWindow(widget_.get());
int keyboard_height = 200;
gfx::Rect root_bounds = root_window->bounds();
gfx::Rect orig_widget_bounds = gfx::Rect(0, 300, 400, 200);
gfx::Rect shifted_widget_bounds = gfx::Rect(0, 200, 400, 200);
gfx::Rect keyboard_view_bounds =
gfx::Rect(0, root_bounds.height() - keyboard_height, root_bounds.width(),
keyboard_height);
widget_->SetBounds(orig_widget_bounds);
input_method()->SetFocusedTextInputClient(textfield_);
EXPECT_EQ(widget_->GetNativeView()->bounds(), orig_widget_bounds);
input_method()->SetVirtualKeyboardBounds(keyboard_view_bounds);
EXPECT_EQ(widget_->GetNativeView()->bounds(), shifted_widget_bounds);
input_method()->DetachTextInputClient(textfield_);
wm::RestoreWindowBoundsOnClientFocusLost(
widget_->GetNativeView()->GetToplevelWindow());
EXPECT_EQ(widget_->GetNativeView()->bounds(), orig_widget_bounds);
}
#endif
#if !BUILDFLAG(IS_MAC)
TEST_F(TextfieldTest, TapActivatesTouchSelection) { … }
TEST_F(TextfieldTest, ClearingFocusDeactivatesTouchSelection) { … }
TEST_F(TextfieldTest, TapOnSelection) { … }
TEST_F(TextfieldTest, LongPressOnSelection) { … }
TEST_F(TextfieldTest, TouchSelectionInUnfocusableTextfield) { … }
#endif
TEST_F(TextfieldTest, MoveCaret) { … }
TEST_F(TextfieldTest, MoveRangeSelectionExtent) { … }
TEST_F(TextfieldTest, MoveRangeSelectionExtentToTextEnd) { … }
TEST_F(TextfieldTest, MoveRangeSelectionExtentByCharacter) { … }
TEST_F(TextfieldTest, MoveRangeSelectionExtentExpandByWord) { … }
TEST_F(TextfieldTest, MoveRangeSelectionExtentShrinkByCharacter) { … }
TEST_F(TextfieldTest, MoveRangeSelectionExtentOffset) { … }
TEST_F(TextfieldTest, MoveRangeSelectionExtentNonEmptySelection) { … }
TEST_F(TextfieldTest, SelectBetweenCoordinates) { … }
TEST_F(TextfieldTest, AccessiblePasswordTest) { … }
TEST_F(TextfieldTest, AccessibleRole) { … }
TEST_F(TextfieldTest, AccessibleReadOnly) { … }
TEST_F(TextfieldTest, CursorVisibility) { … }
TEST_F(TextfieldTest, AccessibleValue) { … }
TEST_F(TextfieldTest, FitToLocalBounds) { … }
TEST_F(TextfieldTest, CursorViewHeight) { … }
TEST_F(TextfieldTest, CursorViewHeightAtDiffDSF) { … }
TEST_F(TextfieldTest, TextfieldBoundsChangeTest) { … }
TEST_F(TextfieldTest, TextfieldInitialization) { … }
TEST_F(TextfieldTest, SwitchFocusInKeyDown) { … }
TEST_F(TextfieldTest, SendingDeletePreservesShiftFlag) { … }
TEST_F(TextfieldTest, EmojiItem_EmptyField) { … }
TEST_F(TextfieldTest, EmojiItem_ReadonlyField) { … }
TEST_F(TextfieldTest, EmojiItem_FieldWithText) { … }
#if BUILDFLAG(IS_MAC)
TEST_F(TextfieldTest, TextServicesContextMenuTextDirectionTest) {
InitTextfield();
EXPECT_TRUE(textfield_->context_menu_controller());
EXPECT_TRUE(GetContextMenuModel());
textfield_->ChangeTextDirectionAndLayoutAlignment(
base::i18n::TextDirection::LEFT_TO_RIGHT);
GetTextfieldTestApi().UpdateContextMenu();
EXPECT_FALSE(textfield_->IsCommandIdChecked(
ui::TextServicesContextMenu::kWritingDirectionDefault));
EXPECT_TRUE(textfield_->IsCommandIdChecked(
ui::TextServicesContextMenu::kWritingDirectionLtr));
EXPECT_FALSE(textfield_->IsCommandIdChecked(
ui::TextServicesContextMenu::kWritingDirectionRtl));
textfield_->ChangeTextDirectionAndLayoutAlignment(
base::i18n::TextDirection::RIGHT_TO_LEFT);
GetTextfieldTestApi().UpdateContextMenu();
EXPECT_FALSE(textfield_->IsCommandIdChecked(
ui::TextServicesContextMenu::kWritingDirectionDefault));
EXPECT_FALSE(textfield_->IsCommandIdChecked(
ui::TextServicesContextMenu::kWritingDirectionLtr));
EXPECT_TRUE(textfield_->IsCommandIdChecked(
ui::TextServicesContextMenu::kWritingDirectionRtl));
}
TEST_F(TextfieldTest, LookUpPassword) {
InitTextfield();
textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
const std::u16string kText = u"Willie Wagtail";
textfield_->SetText(kText);
textfield_->SelectAll(false);
ui::MenuModel* context_menu = GetContextMenuModel();
EXPECT_TRUE(context_menu);
EXPECT_GT(context_menu->GetItemCount(), 0u);
EXPECT_NE(context_menu->GetCommandIdAt(0), IDS_CONTENT_CONTEXT_LOOK_UP);
EXPECT_NE(context_menu->GetLabelAt(0),
l10n_util::GetStringFUTF16(IDS_CONTENT_CONTEXT_LOOK_UP, kText));
}
TEST_F(TextfieldTest, SecurePasswordInput) {
InitTextfield();
ASSERT_FALSE(ui::ScopedPasswordInputEnabler::IsPasswordInputEnabled());
textfield_->OnFocus();
EXPECT_FALSE(ui::ScopedPasswordInputEnabler::IsPasswordInputEnabled());
textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
textfield_->OnFocus();
EXPECT_TRUE(ui::ScopedPasswordInputEnabler::IsPasswordInputEnabled());
textfield_->OnBlur();
EXPECT_FALSE(ui::ScopedPasswordInputEnabler::IsPasswordInputEnabled());
}
#endif
TEST_F(TextfieldTest, AccessibilitySelectionEvents) { … }
TEST_F(TextfieldTest, AccessibilitySelectionEventsOnInitialFocus) { … }
TEST_F(TextfieldTest, FocusReasonMouse) { … }
TEST_F(TextfieldTest, FocusReasonTouchTap) { … }
TEST_F(TextfieldTest, FocusReasonPenTap) { … }
TEST_F(TextfieldTest, FocusReasonMultipleEvents) { … }
TEST_F(TextfieldTest, FocusReasonFocusBlurFocus) { … }
TEST_F(TextfieldTest, KeyboardObserverForPenInput) { … }
TEST_F(TextfieldTest, ChangeTextDirectionAndLayoutAlignmentTest) { … }
TEST_F(TextfieldTest, AccessibilityTextDirection) { … }
TEST_F(TextfieldTest, TextChangedCallbackTest) { … }
TEST_F(TextfieldTest, InsertInvalidCharsTest) { … }
TEST_F(TextfieldTest, ScrollCommands) { … }
TEST_F(TextfieldTest, AccessibleTextDirectionRTL) { … }
TEST_F(TextfieldTest, AccessibleDefaultActionVerb) { … }
#if BUILDFLAG(SUPPORTS_AX_TEXT_OFFSETS)
TEST_F(TextfieldTest, WordOffsets) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(::features::kUiaProvider);
InitTextfield();
ui::AXNodeData node_data;
textfield_->SetText(u"abc 12 34 def hij :' $*() ");
textfield_->GetViewAccessibility().GetAccessibleNodeData(&node_data);
std::vector<int32_t> expected_starts = {0, 4, 7, 10, 14};
std::vector<int32_t> expected_ends = {3, 6, 9, 13, 17};
EXPECT_EQ(
node_data.GetIntListAttribute(ax::mojom::IntListAttribute::kWordStarts),
expected_starts);
EXPECT_EQ(
node_data.GetIntListAttribute(ax::mojom::IntListAttribute::kWordEnds),
expected_ends);
}
TEST_F(TextfieldTest, AccessibleGraphemeOffsets) {
struct TestCase {
std::u16string text;
std::vector<int32_t> expected_offsets;
};
const auto kTestCases = std::to_array<TestCase>({
{std::u16string(), {}},
{u"asdfghkl:/", {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}},
{u"اللغة العربيي",
{120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0, 10}},
{u"\u0915\u093fabc\u0915\u093f", {0, 20, 30, 40, 50, 70}},
{u"ab\u0915\u093fcd", {0, 10, 20, 40, 50, 60}},
{u"ab\U0001D11Ecd", {0, 10, 20, 30, 40, 50}},
});
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(::features::kUiaProvider);
InitTextfield();
constexpr int kGlyphWidth = 10;
gfx::test::RenderTextTestApi(GetTextfieldTestApi().GetRenderText())
.SetGlyphWidth(kGlyphWidth);
GetTextfieldTestApi().GetRenderText()->SetDisplayRect(
gfx::Rect(0, 0, 20 * kGlyphWidth, 100));
for (size_t i = 0; i < kTestCases.size(); i++) {
SCOPED_TRACE(base::StringPrintf("Testing cases[%" PRIuS "]", i));
textfield_->SetText(kTestCases[i].text);
ui::AXNodeData node_data;
textfield_->GetViewAccessibility().GetAccessibleNodeData(&node_data);
EXPECT_EQ(node_data.GetIntListAttribute(
ax::mojom::IntListAttribute::kCharacterOffsets),
kTestCases[i].expected_offsets);
}
}
TEST_F(TextfieldTest, AccessibleGraphemeOffsetsObscured) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(::features::kUiaProvider);
InitTextfield();
textfield_->SetText(u"abcdef");
ASSERT_FALSE(GetTextfieldTestApi().GetRenderText()->obscured());
ui::AXNodeData node_data;
textfield_->GetViewAccessibility().GetAccessibleNodeData(&node_data);
std::vector<int32_t> non_obscured_offsets = node_data.GetIntListAttribute(
ax::mojom::IntListAttribute::kCharacterOffsets);
textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
textfield_->GetViewAccessibility().GetAccessibleNodeData(&node_data);
EXPECT_NE(node_data.GetIntListAttribute(
ax::mojom::IntListAttribute::kCharacterOffsets),
non_obscured_offsets);
}
TEST_F(TextfieldTest, AccessibleGraphemeOffsetsElidedTail) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(::features::kUiaProvider);
InitTextfield();
constexpr int kGlyphWidth = 10;
GetTextfieldTestApi().GetRenderText()->SetDisplayRect(
gfx::Rect(0, 0, 5 * kGlyphWidth, 100));
GetTextfieldTestApi().GetRenderText()->SetElideBehavior(gfx::ELIDE_TAIL);
gfx::test::RenderTextTestApi(GetTextfieldTestApi().GetRenderText())
.SetGlyphWidth(kGlyphWidth);
textfield_->SetText(u"abcdef");
ui::AXNodeData node_data;
textfield_->GetViewAccessibility().GetAccessibleNodeData(&node_data);
std::vector<int32_t> expected_offsets = {0, 10, 20, 30, 40, 40, 40};
EXPECT_EQ(node_data.GetIntListAttribute(
ax::mojom::IntListAttribute::kCharacterOffsets),
expected_offsets);
}
TEST_F(TextfieldTest, AccessibleGraphemeOffsetsIndependentOfDisplayOffset) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(::features::kUiaProvider);
InitTextfield();
gfx::test::RenderTextTestApi render_text_test_api(
GetTextfieldTestApi().GetRenderText());
constexpr int kGlyphWidth = 10;
render_text_test_api.SetGlyphWidth(kGlyphWidth);
GetTextfieldTestApi().GetRenderText()->SetDisplayRect(
gfx::Rect(kGlyphWidth * 10, 20));
textfield_->SetTextWithoutCaretBoundsChangeNotification(
u"3.141592653589793238462", 0);
GetTextfieldTestApi().SetDisplayOffsetX(0);
ui::AXNodeData node_data;
textfield_->GetViewAccessibility().GetAccessibleNodeData(&node_data);
std::vector<int32_t> expected_offsets = {
0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110,
120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230};
EXPECT_EQ(node_data.GetIntListAttribute(
ax::mojom::IntListAttribute::kCharacterOffsets),
expected_offsets);
GetTextfieldTestApi().SetDisplayOffsetX(-100);
EXPECT_EQ(GetTextfieldTestApi().GetDisplayOffsetX(), -100);
ui::AXNodeData node_data_2;
textfield_->GetViewAccessibility().GetAccessibleNodeData(&node_data_2);
EXPECT_EQ(node_data_2.GetIntListAttribute(
ax::mojom::IntListAttribute::kCharacterOffsets),
expected_offsets);
}
#endif
}