xref: /aosp_15_r20/external/pdfium/fpdfsdk/fpdf_formfill_embeddertest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2015 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <vector>
6 
7 #include "build/build_config.h"
8 #include "constants/ascii.h"
9 #include "core/fxcrt/fx_coordinates.h"
10 #include "core/fxcrt/fx_string.h"
11 #include "core/fxcrt/fx_system.h"
12 #include "core/fxge/cfx_defaultrenderdevice.h"
13 #include "public/cpp/fpdf_scopers.h"
14 #include "public/fpdf_formfill.h"
15 #include "public/fpdf_fwlevent.h"
16 #include "public/fpdf_progressive.h"
17 #include "testing/embedder_test.h"
18 #include "testing/embedder_test_constants.h"
19 #include "testing/embedder_test_mock_delegate.h"
20 #include "testing/embedder_test_timer_handling_delegate.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "third_party/base/check.h"
24 #include "third_party/base/check_op.h"
25 
26 using pdfium::TextFormChecksum;
27 
28 using testing::_;
29 using testing::InSequence;
30 using testing::NiceMock;
31 using testing::StrEq;
32 
33 using FPDFFormFillEmbedderTest = EmbedderTest;
34 
35 // A base class for many related tests that involve clicking and typing into
36 // form fields.
37 class FPDFFormFillInteractiveEmbedderTest : public FPDFFormFillEmbedderTest {
38  protected:
39   FPDFFormFillInteractiveEmbedderTest() = default;
40   ~FPDFFormFillInteractiveEmbedderTest() override = default;
41 
SetUp()42   void SetUp() override {
43     FPDFFormFillEmbedderTest::SetUp();
44     ASSERT_TRUE(OpenDocument(GetDocumentName()));
45     page_ = LoadPage(0);
46     ASSERT_TRUE(page_);
47     FormSanityChecks();
48   }
49 
TearDown()50   void TearDown() override {
51     UnloadPage(page_);
52     FPDFFormFillEmbedderTest::TearDown();
53   }
54 
55   // Returns the name of the PDF to use.
56   virtual const char* GetDocumentName() const = 0;
57 
58   // Returns the type of field(s) in the PDF.
59   virtual int GetFormType() const = 0;
60 
61   // Optionally do some sanity check on the document after loading.
FormSanityChecks()62   virtual void FormSanityChecks() {}
63 
page()64   FPDF_PAGE page() { return page_; }
65 
GetFormTypeAtPoint(const CFX_PointF & point)66   int GetFormTypeAtPoint(const CFX_PointF& point) {
67     return FPDFPage_HasFormFieldAtPoint(form_handle(), page_, point.x, point.y);
68   }
69 
ClickOnFormFieldAtPoint(const CFX_PointF & point)70   void ClickOnFormFieldAtPoint(const CFX_PointF& point) {
71     // Click on the text field or combobox as specified by coordinates.
72     FORM_OnMouseMove(form_handle(), page_, 0, point.x, point.y);
73     FORM_OnLButtonDown(form_handle(), page_, 0, point.x, point.y);
74     FORM_OnLButtonUp(form_handle(), page_, 0, point.x, point.y);
75   }
76 
DoubleClickOnFormFieldAtPoint(const CFX_PointF & point)77   void DoubleClickOnFormFieldAtPoint(const CFX_PointF& point) {
78     // Click on the text field or combobox as specified by coordinates.
79     FORM_OnMouseMove(form_handle(), page_, 0, point.x, point.y);
80     FORM_OnLButtonDoubleClick(form_handle(), page_, 0, point.x, point.y);
81   }
82 
TypeTextIntoTextField(int num_chars,const CFX_PointF & point)83   void TypeTextIntoTextField(int num_chars, const CFX_PointF& point) {
84     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(point));
85     ClickOnFormFieldAtPoint(point);
86 
87     // Type text starting with 'A' to as many chars as specified by |num_chars|.
88     for (int i = 0; i < num_chars; ++i) {
89       FORM_OnChar(form_handle(), page_, 'A' + i, 0);
90     }
91   }
92 
93   // Navigates to text field using the mouse and then selects text via the
94   // shift and specfied left or right arrow key.
SelectTextWithKeyboard(int num_chars,int arrow_key,const CFX_PointF & point)95   void SelectTextWithKeyboard(int num_chars,
96                               int arrow_key,
97                               const CFX_PointF& point) {
98     // Navigate to starting position for selection.
99     ClickOnFormFieldAtPoint(point);
100 
101     // Hold down shift (and don't release until entire text is selected).
102     FORM_OnKeyDown(form_handle(), page_, FWL_VKEY_Shift, 0);
103 
104     // Select text char by char via left or right arrow key.
105     for (int i = 0; i < num_chars; ++i) {
106       FORM_OnKeyDown(form_handle(), page_, arrow_key, FWL_EVENTFLAG_ShiftKey);
107       FORM_OnKeyUp(form_handle(), page_, arrow_key, FWL_EVENTFLAG_ShiftKey);
108     }
109     FORM_OnKeyUp(form_handle(), page_, FWL_VKEY_Shift, 0);
110   }
111 
112   // Uses the mouse to navigate to text field and select text.
SelectTextWithMouse(const CFX_PointF & start,const CFX_PointF & end)113   void SelectTextWithMouse(const CFX_PointF& start, const CFX_PointF& end) {
114     DCHECK_EQ(start.y, end.y);
115 
116     // Navigate to starting position and click mouse.
117     FORM_OnMouseMove(form_handle(), page_, 0, start.x, start.y);
118     FORM_OnLButtonDown(form_handle(), page_, 0, start.x, start.y);
119 
120     // Hold down mouse until reach end of desired selection.
121     FORM_OnMouseMove(form_handle(), page_, 0, end.x, end.y);
122     FORM_OnLButtonUp(form_handle(), page_, 0, end.x, end.y);
123   }
124 
SelectAllTextAtPoint(const CFX_PointF & point)125   void SelectAllTextAtPoint(const CFX_PointF& point) {
126     FocusOnPoint(point);
127     EXPECT_TRUE(FORM_SelectAllText(form_handle(), page_));
128   }
129 
CheckSelection(WideStringView expected_string)130   void CheckSelection(WideStringView expected_string) {
131     unsigned long actual_len =
132         FORM_GetSelectedText(form_handle(), page_, nullptr, 0);
133     ASSERT_NE(actual_len, 0U);
134     ASSERT_LT(actual_len, 1000U);
135 
136     std::vector<unsigned short> buf(actual_len);
137     ASSERT_EQ(actual_len, FORM_GetSelectedText(form_handle(), page_, buf.data(),
138                                                actual_len));
139 
140     int num_chars = (actual_len / sizeof(unsigned short)) - 1;
141     EXPECT_EQ(expected_string, WideString::FromUTF16LE(buf.data(), num_chars));
142   }
143 
FocusOnPoint(const CFX_PointF & point)144   void FocusOnPoint(const CFX_PointF& point) {
145     EXPECT_TRUE(FORM_OnFocus(form_handle(), page(), 0, point.x, point.y));
146   }
147 
CheckFocusedFieldText(WideStringView expected_string)148   void CheckFocusedFieldText(WideStringView expected_string) {
149     unsigned long actual_len =
150         FORM_GetFocusedText(form_handle(), page_, nullptr, 0);
151     ASSERT_NE(actual_len, 0U);
152     ASSERT_LT(actual_len, 1000U);
153 
154     std::vector<unsigned short> buf(actual_len);
155     ASSERT_EQ(actual_len, FORM_GetFocusedText(form_handle(), page_, buf.data(),
156                                               actual_len));
157 
158     int num_chars = (actual_len / sizeof(unsigned short)) - 1;
159     EXPECT_EQ(expected_string, WideString::FromUTF16LE(buf.data(), num_chars));
160   }
161 
CheckCanUndo(bool expected_result)162   void CheckCanUndo(bool expected_result) {
163     EXPECT_EQ(expected_result, !!FORM_CanUndo(form_handle(), page_));
164   }
165 
CheckCanRedo(bool expected_result)166   void CheckCanRedo(bool expected_result) {
167     EXPECT_EQ(expected_result, !!FORM_CanRedo(form_handle(), page_));
168   }
169 
PerformUndo()170   void PerformUndo() { EXPECT_TRUE(FORM_Undo(form_handle(), page_)); }
171 
PerformRedo()172   void PerformRedo() { EXPECT_TRUE(FORM_Redo(form_handle(), page_)); }
173 
SetIndexSelectedShouldSucceed(int index,bool selected)174   void SetIndexSelectedShouldSucceed(int index, bool selected) {
175     EXPECT_TRUE(FORM_SetIndexSelected(form_handle(), page_, index, selected));
176   }
177 
SetIndexSelectedShouldFail(int index,bool selected)178   void SetIndexSelectedShouldFail(int index, bool selected) {
179     EXPECT_FALSE(FORM_SetIndexSelected(form_handle(), page_, index, selected));
180   }
181 
CheckIsIndexSelected(int index,bool expected)182   void CheckIsIndexSelected(int index, bool expected) {
183     EXPECT_EQ(expected, FORM_IsIndexSelected(form_handle(), page_, index));
184   }
185 
186  private:
187   FPDF_PAGE page_ = nullptr;
188 };
189 
190 class FPDFFormFillTextFormEmbedderTest
191     : public FPDFFormFillInteractiveEmbedderTest {
192  protected:
193   FPDFFormFillTextFormEmbedderTest() = default;
194   ~FPDFFormFillTextFormEmbedderTest() override = default;
195 
GetDocumentName() const196   const char* GetDocumentName() const override {
197     // PDF with several form text fields:
198     // - "Text Box" - Regular text box with no special attributes.
199     // - "ReadOnly" - Ff: 1.
200     // - "CharLimit" - MaxLen: 10, V: Elephant.
201     return "text_form_multiple.pdf";
202   }
203 
GetFormType() const204   int GetFormType() const override { return FPDF_FORMFIELD_TEXTFIELD; }
205 
FormSanityChecks()206   void FormSanityChecks() override {
207     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(CharLimitFormBegin()));
208     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(CharLimitFormEnd()));
209     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(RegularFormBegin()));
210     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(RegularFormEnd()));
211   }
212 
SelectAllCharLimitFormTextWithMouse()213   void SelectAllCharLimitFormTextWithMouse() {
214     SelectAllTextAtPoint(CharLimitFormBegin());
215   }
216 
SelectAllRegularFormTextWithMouse()217   void SelectAllRegularFormTextWithMouse() {
218     SelectAllTextAtPoint(RegularFormBegin());
219   }
220 
CharLimitFormBegin() const221   const CFX_PointF& CharLimitFormBegin() const {
222     static const CFX_PointF point = CharLimitFormAtX(kFormBeginX);
223     return point;
224   }
225 
CharLimitFormEnd() const226   const CFX_PointF& CharLimitFormEnd() const {
227     static const CFX_PointF point = CharLimitFormAtX(kFormEndX);
228     return point;
229   }
230 
RegularFormBegin() const231   const CFX_PointF& RegularFormBegin() const {
232     static const CFX_PointF point = RegularFormAtX(kFormBeginX);
233     return point;
234   }
235 
RegularFormEnd() const236   const CFX_PointF& RegularFormEnd() const {
237     static const CFX_PointF point = RegularFormAtX(kFormEndX);
238     return point;
239   }
240 
CharLimitFormAtX(float x)241   static CFX_PointF CharLimitFormAtX(float x) {
242     DCHECK(x >= kFormBeginX);
243     DCHECK(x <= kFormEndX);
244     return CFX_PointF(x, kCharLimitFormY);
245   }
246 
RegularFormAtX(float x)247   static CFX_PointF RegularFormAtX(float x) {
248     DCHECK(x >= kFormBeginX);
249     DCHECK(x <= kFormEndX);
250     return CFX_PointF(x, kRegularFormY);
251   }
252 
253  private:
254   static constexpr float kFormBeginX = 102.0;
255   static constexpr float kFormEndX = 195.0;
256   static constexpr float kCharLimitFormY = 60.0;
257   static constexpr float kRegularFormY = 115.0;
258 };
259 
260 class FPDFFormFillComboBoxFormEmbedderTest
261     : public FPDFFormFillInteractiveEmbedderTest {
262  protected:
263   FPDFFormFillComboBoxFormEmbedderTest() = default;
264   ~FPDFFormFillComboBoxFormEmbedderTest() override = default;
265 
GetDocumentName() const266   const char* GetDocumentName() const override {
267     // PDF with form comboboxes:
268     // - "Combo_Editable" - Ff: 393216, 3 options with pair values.
269     // - "Combo1" - Ff: 131072, 3 options with single values.
270     // - "Combo_ReadOnly" - Ff: 131073, 3 options with single values.
271     return "combobox_form.pdf";
272   }
273 
GetFormType() const274   int GetFormType() const override { return FPDF_FORMFIELD_COMBOBOX; }
275 
FormSanityChecks()276   void FormSanityChecks() override {
277     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(EditableFormBegin()));
278     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(EditableFormEnd()));
279     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(EditableFormDropDown()));
280     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(NonEditableFormBegin()));
281     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(NonEditableFormEnd()));
282     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(NonEditableFormDropDown()));
283   }
284 
SelectEditableFormOption(int item_index)285   void SelectEditableFormOption(int item_index) {
286     DCHECK(item_index >= 0);
287     DCHECK(item_index < 3);
288     SelectOption(item_index, EditableFormDropDown());
289   }
290 
SelectNonEditableFormOption(int item_index)291   void SelectNonEditableFormOption(int item_index) {
292     DCHECK(item_index >= 0);
293     DCHECK(item_index < 26);
294     SelectOption(item_index, NonEditableFormDropDown());
295   }
296 
SelectAllEditableFormTextWithMouse()297   void SelectAllEditableFormTextWithMouse() {
298     SelectAllTextAtPoint(EditableFormBegin());
299   }
300 
FocusOnEditableForm()301   void FocusOnEditableForm() { FocusOnPoint(EditableFormDropDown()); }
302 
FocusOnNonEditableForm()303   void FocusOnNonEditableForm() { FocusOnPoint(NonEditableFormDropDown()); }
304 
EditableFormBegin() const305   const CFX_PointF& EditableFormBegin() const {
306     static const CFX_PointF point = EditableFormAtX(kFormBeginX);
307     return point;
308   }
309 
EditableFormEnd() const310   const CFX_PointF& EditableFormEnd() const {
311     static const CFX_PointF point = EditableFormAtX(kFormEndX);
312     return point;
313   }
314 
EditableFormDropDown() const315   const CFX_PointF& EditableFormDropDown() const {
316     static const CFX_PointF point(kFormDropDownX, kEditableFormY);
317     return point;
318   }
319 
NonEditableFormBegin() const320   const CFX_PointF& NonEditableFormBegin() const {
321     static const CFX_PointF point = NonEditableFormAtX(kFormBeginX);
322     return point;
323   }
324 
NonEditableFormEnd() const325   const CFX_PointF& NonEditableFormEnd() const {
326     static const CFX_PointF point = NonEditableFormAtX(kFormEndX);
327     return point;
328   }
329 
NonEditableFormDropDown() const330   const CFX_PointF& NonEditableFormDropDown() const {
331     static const CFX_PointF point(kFormDropDownX, kNonEditableFormY);
332     return point;
333   }
334 
EditableFormAtX(float x)335   static CFX_PointF EditableFormAtX(float x) {
336     DCHECK(x >= kFormBeginX);
337     DCHECK(x <= kFormEndX);
338     return CFX_PointF(x, kEditableFormY);
339   }
340 
NonEditableFormAtX(float x)341   static CFX_PointF NonEditableFormAtX(float x) {
342     DCHECK(x >= kFormBeginX);
343     DCHECK(x <= kFormEndX);
344     return CFX_PointF(x, kNonEditableFormY);
345   }
346 
347  private:
348   // Selects one of the pre-selected values from a combobox with three options.
349   // Options are specified by |item_index|, which is 0-based.
SelectOption(int item_index,const CFX_PointF & point)350   void SelectOption(int item_index, const CFX_PointF& point) {
351     // Navigate to button for drop down and click mouse to reveal options.
352     ClickOnFormFieldAtPoint(point);
353 
354     // Calculate to Y-coordinate of dropdown option to be selected.
355     constexpr double kChoiceHeight = 15;
356     CFX_PointF option_point = point;
357     option_point.y -= kChoiceHeight * (item_index + 1);
358 
359     // Move left to avoid scrollbar.
360     option_point.x -= 20;
361 
362     // Navigate to option and click mouse to select it.
363     ClickOnFormFieldAtPoint(option_point);
364   }
365 
366   static constexpr float kFormBeginX = 102.0;
367   static constexpr float kFormEndX = 183.0;
368   static constexpr float kFormDropDownX = 192.0;
369   static constexpr float kEditableFormY = 360.0;
370   static constexpr float kNonEditableFormY = 410.0;
371 };
372 
373 class FPDFFormFillListBoxFormEmbedderTest
374     : public FPDFFormFillInteractiveEmbedderTest {
375  protected:
376   FPDFFormFillListBoxFormEmbedderTest() = default;
377   ~FPDFFormFillListBoxFormEmbedderTest() override = default;
378 
GetDocumentName() const379   const char* GetDocumentName() const override {
380     // PDF with form listboxes:
381     // - "Listbox_SingleSelect" - Ff: 0, 3 options with pair values.
382     // - "Listbox_MultiSelect" - Ff: 2097152, 26 options with single values.
383     // - "Listbox_ReadOnly" - Ff: 1, 3 options with single values.
384     // - "Listbox_MultiSelectMultipleIndices" - Ff: 2097152, 5 options with
385     //    single values.
386     // - "Listbox_MultiSelectMultipleValues" - same configs as above.
387     // - "Listbox_MultiSelectMultipleMismatch" - same configs as above.
388     // - "Listbox_SingleSelectLastSelected" - Ff: 0, 10 options with single
389     //    values.
390     return "listbox_form.pdf";
391   }
392 
GetFormType() const393   int GetFormType() const override { return FPDF_FORMFIELD_LISTBOX; }
394 
FormSanityChecks()395   void FormSanityChecks() override {
396     EXPECT_EQ(GetFormType(),
397               GetFormTypeAtPoint(SingleSelectFirstVisibleOption()));
398     EXPECT_EQ(GetFormType(),
399               GetFormTypeAtPoint(SingleSelectSecondVisibleOption()));
400     EXPECT_EQ(GetFormType(),
401               GetFormTypeAtPoint(MultiSelectFirstVisibleOption()));
402     EXPECT_EQ(GetFormType(),
403               GetFormTypeAtPoint(MultiSelectSecondVisibleOption()));
404     EXPECT_EQ(
405         GetFormType(),
406         GetFormTypeAtPoint(MultiSelectMultipleIndicesFirstVisibleOption()));
407     EXPECT_EQ(
408         GetFormType(),
409         GetFormTypeAtPoint(MultiSelectMultipleIndicesSecondVisibleOption()));
410     EXPECT_EQ(
411         GetFormType(),
412         GetFormTypeAtPoint(MultiSelectMultipleValuesFirstVisibleOption()));
413     EXPECT_EQ(
414         GetFormType(),
415         GetFormTypeAtPoint(MultiSelectMultipleValuesSecondVisibleOption()));
416     EXPECT_EQ(
417         GetFormType(),
418         GetFormTypeAtPoint(MultiSelectMultipleMismatchFirstVisibleOption()));
419     EXPECT_EQ(
420         GetFormType(),
421         GetFormTypeAtPoint(MultiSelectMultipleMismatchSecondVisibleOption()));
422     EXPECT_EQ(GetFormType(),
423               GetFormTypeAtPoint(SingleSelectLastSelectedFirstVisibleOption()));
424     EXPECT_EQ(
425         GetFormType(),
426         GetFormTypeAtPoint(SingleSelectLastSelectedSecondVisibleOption()));
427   }
428 
ClickOnSingleSelectFormOption(int item_index)429   void ClickOnSingleSelectFormOption(int item_index) {
430     // Only the first two indices are visible so can only click on those
431     // without scrolling.
432     DCHECK(item_index >= 0);
433     DCHECK(item_index < 2);
434     if (item_index == 0) {
435       ClickOnFormFieldAtPoint(SingleSelectFirstVisibleOption());
436     } else {
437       ClickOnFormFieldAtPoint(SingleSelectSecondVisibleOption());
438     }
439   }
440 
ClickOnMultiSelectFormOption(int item_index)441   void ClickOnMultiSelectFormOption(int item_index) {
442     // Only the first two indices are visible so can only click on those
443     // without scrolling.
444     DCHECK(item_index >= 0);
445     DCHECK(item_index < 2);
446     if (item_index == 0) {
447       ClickOnFormFieldAtPoint(MultiSelectFirstVisibleOption());
448     } else {
449       ClickOnFormFieldAtPoint(MultiSelectSecondVisibleOption());
450     }
451   }
452 
ClickOnMultiSelectMultipleValuesFormOption(int item_index)453   void ClickOnMultiSelectMultipleValuesFormOption(int item_index) {
454     // Only two indices are visible so can only click on those
455     // without scrolling.
456     DCHECK(item_index >= 0);
457     DCHECK(item_index < 2);
458     if (item_index == 0) {
459       ClickOnFormFieldAtPoint(MultiSelectMultipleValuesFirstVisibleOption());
460     } else {
461       ClickOnFormFieldAtPoint(MultiSelectMultipleValuesSecondVisibleOption());
462     }
463   }
464 
ClickOnSingleSelectLastSelectedFormOption(int item_index)465   void ClickOnSingleSelectLastSelectedFormOption(int item_index) {
466     // Only two indices are visible so can only click on those
467     // without scrolling.
468     DCHECK(item_index >= 0);
469     DCHECK(item_index < 2);
470     if (item_index == 0) {
471       ClickOnFormFieldAtPoint(SingleSelectLastSelectedFirstVisibleOption());
472     } else {
473       ClickOnFormFieldAtPoint(SingleSelectLastSelectedSecondVisibleOption());
474     }
475   }
476 
FocusOnSingleSelectForm()477   void FocusOnSingleSelectForm() {
478     FocusOnPoint(SingleSelectFirstVisibleOption());
479   }
480 
FocusOnMultiSelectForm()481   void FocusOnMultiSelectForm() {
482     FocusOnPoint(MultiSelectFirstVisibleOption());
483   }
484 
FocusOnMultiSelectMultipleIndicesForm()485   void FocusOnMultiSelectMultipleIndicesForm() {
486     FocusOnPoint(MultiSelectMultipleIndicesFirstVisibleOption());
487   }
488 
FocusOnMultiSelectMultipleValuesForm()489   void FocusOnMultiSelectMultipleValuesForm() {
490     FocusOnPoint(MultiSelectMultipleValuesFirstVisibleOption());
491   }
492 
FocusOnMultiSelectMultipleMismatchForm()493   void FocusOnMultiSelectMultipleMismatchForm() {
494     FocusOnPoint(MultiSelectMultipleMismatchFirstVisibleOption());
495   }
496 
FocusOnSingleSelectLastSelectedForm()497   void FocusOnSingleSelectLastSelectedForm() {
498     FocusOnPoint(SingleSelectLastSelectedFirstVisibleOption());
499   }
500 
FocusOnPoint(const CFX_PointF & point)501   void FocusOnPoint(const CFX_PointF& point) {
502     EXPECT_EQ(true, FORM_OnFocus(form_handle(), page(), 0, point.x, point.y));
503   }
504 
SingleSelectFirstVisibleOption() const505   const CFX_PointF& SingleSelectFirstVisibleOption() const {
506     static const CFX_PointF point(kFormBeginX, kSingleFormYFirstVisibleOption);
507     return point;
508   }
509 
SingleSelectSecondVisibleOption() const510   const CFX_PointF& SingleSelectSecondVisibleOption() const {
511     static const CFX_PointF point(kFormBeginX, kSingleFormYSecondVisibleOption);
512     return point;
513   }
514 
MultiSelectFirstVisibleOption() const515   const CFX_PointF& MultiSelectFirstVisibleOption() const {
516     static const CFX_PointF point(kFormBeginX, kMultiFormYFirstVisibleOption);
517     return point;
518   }
519 
MultiSelectSecondVisibleOption() const520   const CFX_PointF& MultiSelectSecondVisibleOption() const {
521     static const CFX_PointF point(kFormBeginX, kMultiFormYSecondVisibleOption);
522     return point;
523   }
524 
MultiSelectMultipleIndicesFirstVisibleOption() const525   const CFX_PointF& MultiSelectMultipleIndicesFirstVisibleOption() const {
526     static const CFX_PointF point(kFormBeginX,
527                                   kMultiFormMultipleIndicesYFirstVisibleOption);
528     return point;
529   }
530 
MultiSelectMultipleIndicesSecondVisibleOption() const531   const CFX_PointF& MultiSelectMultipleIndicesSecondVisibleOption() const {
532     static const CFX_PointF point(
533         kFormBeginX, kMultiFormMultipleIndicesYSecondVisibleOption);
534     return point;
535   }
536 
MultiSelectMultipleValuesFirstVisibleOption() const537   const CFX_PointF& MultiSelectMultipleValuesFirstVisibleOption() const {
538     static const CFX_PointF point(kFormBeginX,
539                                   kMultiFormMultipleValuesYFirstVisibleOption);
540     return point;
541   }
542 
MultiSelectMultipleValuesSecondVisibleOption() const543   const CFX_PointF& MultiSelectMultipleValuesSecondVisibleOption() const {
544     static const CFX_PointF point(kFormBeginX,
545                                   kMultiFormMultipleValuesYSecondVisibleOption);
546     return point;
547   }
548 
MultiSelectMultipleMismatchFirstVisibleOption() const549   const CFX_PointF& MultiSelectMultipleMismatchFirstVisibleOption() const {
550     static const CFX_PointF point(
551         kFormBeginX, kMultiFormMultipleMismatchYFirstVisibleOption);
552     return point;
553   }
554 
MultiSelectMultipleMismatchSecondVisibleOption() const555   const CFX_PointF& MultiSelectMultipleMismatchSecondVisibleOption() const {
556     static const CFX_PointF point(
557         kFormBeginX, kMultiFormMultipleMismatchYSecondVisibleOption);
558     return point;
559   }
560 
SingleSelectLastSelectedFirstVisibleOption() const561   const CFX_PointF& SingleSelectLastSelectedFirstVisibleOption() const {
562     static const CFX_PointF point(kFormBeginX,
563                                   kSingleFormLastSelectedYFirstVisibleOption);
564     return point;
565   }
566 
SingleSelectLastSelectedSecondVisibleOption() const567   const CFX_PointF& SingleSelectLastSelectedSecondVisibleOption() const {
568     static const CFX_PointF point(kFormBeginX,
569                                   kSingleFormLastSelectedYSecondVisibleOption);
570     return point;
571   }
572 
573  private:
574   static constexpr float kFormBeginX = 102.0;
575   static constexpr float kSingleFormYFirstVisibleOption = 371.0;
576   static constexpr float kSingleFormYSecondVisibleOption = 358.0;
577   static constexpr float kMultiFormYFirstVisibleOption = 423.0;
578   static constexpr float kMultiFormYSecondVisibleOption = 408.0;
579   static constexpr float kMultiFormMultipleIndicesYFirstVisibleOption = 273.0;
580   static constexpr float kMultiFormMultipleIndicesYSecondVisibleOption = 258.0;
581   static constexpr float kMultiFormMultipleValuesYFirstVisibleOption = 223.0;
582   static constexpr float kMultiFormMultipleValuesYSecondVisibleOption = 208.0;
583   static constexpr float kMultiFormMultipleMismatchYFirstVisibleOption = 173.0;
584   static constexpr float kMultiFormMultipleMismatchYSecondVisibleOption = 158.0;
585   static constexpr float kSingleFormLastSelectedYFirstVisibleOption = 123.0;
586   static constexpr float kSingleFormLastSelectedYSecondVisibleOption = 108.0;
587 };
588 
589 class FPDFFormFillTextFormEmbedderTestVersion2
590     : public FPDFFormFillTextFormEmbedderTest {
SetUp()591   void SetUp() override {
592     SetFormFillInfoVersion(2);
593     FPDFFormFillInteractiveEmbedderTest::SetUp();
594   }
595 };
596 
TEST_F(FPDFFormFillEmbedderTest,FirstTest)597 TEST_F(FPDFFormFillEmbedderTest, FirstTest) {
598   EmbedderTestMockDelegate mock;
599   EXPECT_CALL(mock, Alert(_, _, _, _)).Times(0);
600   EXPECT_CALL(mock, UnsupportedHandler(_)).Times(0);
601   EXPECT_CALL(mock, SetTimer(_, _)).Times(0);
602   EXPECT_CALL(mock, KillTimer(_)).Times(0);
603   EXPECT_CALL(mock, OnFocusChange(_, _, _)).Times(0);
604   EXPECT_CALL(mock, DoURIAction(_)).Times(0);
605   EXPECT_CALL(mock, DoURIActionWithKeyboardModifier(_, _, _)).Times(0);
606   EXPECT_CALL(mock, DoGoToAction(_, _, _, _, _)).Times(0);
607   SetDelegate(&mock);
608 
609   ASSERT_TRUE(OpenDocument("hello_world.pdf"));
610   FPDF_PAGE page = LoadPage(0);
611   EXPECT_TRUE(page);
612   UnloadPage(page);
613 }
614 
TEST_F(FPDFFormFillEmbedderTest,BUG_487928)615 TEST_F(FPDFFormFillEmbedderTest, BUG_487928) {
616   EmbedderTestTimerHandlingDelegate delegate;
617   SetDelegate(&delegate);
618 
619   ASSERT_TRUE(OpenDocument("bug_487928.pdf"));
620   FPDF_PAGE page = LoadPage(0);
621   EXPECT_TRUE(page);
622   DoOpenActions();
623   delegate.AdvanceTime(5000);
624   UnloadPage(page);
625 }
626 
TEST_F(FPDFFormFillEmbedderTest,BUG_507316)627 TEST_F(FPDFFormFillEmbedderTest, BUG_507316) {
628   EmbedderTestTimerHandlingDelegate delegate;
629   SetDelegate(&delegate);
630 
631   ASSERT_TRUE(OpenDocument("bug_507316.pdf"));
632   FPDF_PAGE page = LoadPage(2);
633   EXPECT_TRUE(page);
634   DoOpenActions();
635   delegate.AdvanceTime(4000);
636   UnloadPage(page);
637 }
638 
TEST_F(FPDFFormFillEmbedderTest,BUG_514690)639 TEST_F(FPDFFormFillEmbedderTest, BUG_514690) {
640   ASSERT_TRUE(OpenDocument("hello_world.pdf"));
641   FPDF_PAGE page = LoadPage(0);
642   EXPECT_TRUE(page);
643 
644   // Test that FORM_OnMouseMove() etc. permit null HANDLES and PAGES.
645   FORM_OnMouseMove(nullptr, page, 0, 10.0, 10.0);
646   FORM_OnMouseMove(form_handle(), nullptr, 0, 10.0, 10.0);
647 
648   UnloadPage(page);
649 }
650 
TEST_F(FPDFFormFillEmbedderTest,BUG_900552)651 TEST_F(FPDFFormFillEmbedderTest, BUG_900552) {
652   EmbedderTestTimerHandlingDelegate delegate;
653   SetDelegate(&delegate);
654 
655   ASSERT_TRUE(OpenDocument("bug_900552.pdf"));
656   FPDF_PAGE page = LoadPage(0);
657   ASSERT_TRUE(page);
658   DoOpenActions();
659   delegate.AdvanceTime(4000);
660 
661   // Simulate a repaint.
662   FPDF_BITMAP bitmap = FPDFBitmap_Create(512, 512, 0);
663   ASSERT_TRUE(bitmap);
664   FPDF_RenderPageBitmap_Start(bitmap, page, 0, 0, 512, 512, 0, 0, nullptr);
665   FPDFBitmap_Destroy(bitmap);
666   UnloadPage(page);
667 }
668 
TEST_F(FPDFFormFillEmbedderTest,BUG_901654)669 TEST_F(FPDFFormFillEmbedderTest, BUG_901654) {
670   EmbedderTestTimerHandlingDelegate delegate;
671   SetDelegate(&delegate);
672 
673   ASSERT_TRUE(OpenDocument("bug_901654.pdf"));
674   FPDF_PAGE page = LoadPage(0);
675   ASSERT_TRUE(page);
676   DoOpenActions();
677   delegate.AdvanceTime(4000);
678 
679   // Simulate a repaint.
680   {
681     ScopedFPDFBitmap bitmap(FPDFBitmap_Create(512, 512, 0));
682     FPDF_RenderPageBitmap_Start(bitmap.get(), page, 0, 0, 512, 512, 0, 0,
683                                 nullptr);
684   }
685   UnloadPage(page);
686 }
687 
TEST_F(FPDFFormFillEmbedderTest,BUG_901654_2)688 TEST_F(FPDFFormFillEmbedderTest, BUG_901654_2) {
689   EmbedderTestTimerHandlingDelegate delegate;
690   SetDelegate(&delegate);
691 
692   ASSERT_TRUE(OpenDocument("bug_901654_2.pdf"));
693   FPDF_PAGE page = LoadPage(0);
694   ASSERT_TRUE(page);
695   DoOpenActions();
696   delegate.AdvanceTime(4000);
697 
698   // Simulate a repaint.
699   {
700     ScopedFPDFBitmap bitmap(FPDFBitmap_Create(512, 512, 0));
701     FPDF_RenderPageBitmap_Start(bitmap.get(), page, 0, 0, 512, 512, 0, 0,
702                                 nullptr);
703   }
704   UnloadPage(page);
705 }
706 
TEST_F(FPDFFormFillEmbedderTest,GetFocusedAnnotation)707 TEST_F(FPDFFormFillEmbedderTest, GetFocusedAnnotation) {
708   ASSERT_TRUE(OpenDocument("annotiter.pdf"));
709   std::vector<FPDF_PAGE> pages;
710   for (size_t i = 0; i < 3; ++i) {
711     pages.push_back(LoadPage(i));
712     ASSERT_TRUE(pages.back());
713   }
714 
715   // Ensure that there is no focused annotation.
716   FPDF_ANNOTATION annot = nullptr;
717   int page_index = -2;
718   ASSERT_TRUE(FORM_GetFocusedAnnot(form_handle(), &page_index, &annot));
719   EXPECT_FALSE(annot);
720   EXPECT_EQ(-1, page_index);
721 
722   // Validate that nullptr values are handled properly.
723   EXPECT_FALSE(FORM_GetFocusedAnnot(nullptr, &page_index, &annot));
724   EXPECT_FALSE(FORM_GetFocusedAnnot(form_handle(), &page_index, nullptr));
725   EXPECT_FALSE(FORM_GetFocusedAnnot(form_handle(), nullptr, &annot));
726 
727   const CFX_PointF right_bottom_annot_point(410.0f, 210.0f);
728   constexpr int kExpectedAnnotIndex = 3;
729 
730   for (size_t i = 0; i < pages.size(); ++i) {
731     // Invoke click on the form field to bring it to focus.
732     FORM_OnMouseMove(form_handle(), pages[i], 0, right_bottom_annot_point.x,
733                      right_bottom_annot_point.y);
734     FORM_OnLButtonDown(form_handle(), pages[i], 0, right_bottom_annot_point.x,
735                        right_bottom_annot_point.y);
736     FORM_OnLButtonUp(form_handle(), pages[i], 0, right_bottom_annot_point.x,
737                      right_bottom_annot_point.y);
738 
739     ASSERT_TRUE(FORM_GetFocusedAnnot(form_handle(), &page_index, &annot));
740     ASSERT_TRUE(annot);
741 
742     EXPECT_EQ(kExpectedAnnotIndex, FPDFPage_GetAnnotIndex(pages[i], annot));
743     EXPECT_EQ(static_cast<int>(i), page_index);
744 
745     FPDFPage_CloseAnnot(annot);
746   }
747 
748   for (FPDF_PAGE page : pages)
749     UnloadPage(page);
750 }
751 
TEST_F(FPDFFormFillEmbedderTest,SetFocusedAnnotation)752 TEST_F(FPDFFormFillEmbedderTest, SetFocusedAnnotation) {
753   ASSERT_TRUE(OpenDocument("annotiter.pdf"));
754   std::vector<FPDF_PAGE> pages;
755   for (size_t i = 0; i < 3; ++i) {
756     pages.push_back(LoadPage(i));
757     ASSERT_TRUE(pages.back());
758   }
759 
760   // Ensure that there is no focused annotation.
761   FPDF_ANNOTATION annot = nullptr;
762   int page_index = -2;
763   ASSERT_TRUE(FORM_GetFocusedAnnot(form_handle(), &page_index, &annot));
764   EXPECT_FALSE(annot);
765   EXPECT_EQ(-1, page_index);
766 
767   // Validate that nullptr values are handled properly.
768   EXPECT_FALSE(FORM_SetFocusedAnnot(nullptr, annot));
769   EXPECT_FALSE(FORM_SetFocusedAnnot(form_handle(), nullptr));
770 
771   constexpr int kExpectedAnnotIndex = 2;
772 
773   for (size_t i = 0; i < pages.size(); ++i) {
774     // Setting focus on an annotation on page i.
775     ScopedFPDFAnnotation focused_annot(
776         FPDFPage_GetAnnot(pages[i], kExpectedAnnotIndex));
777     ASSERT_TRUE(focused_annot);
778 
779     ASSERT_TRUE(FORM_SetFocusedAnnot(form_handle(), focused_annot.get()));
780 
781     ASSERT_TRUE(FORM_GetFocusedAnnot(form_handle(), &page_index, &annot));
782     EXPECT_EQ(kExpectedAnnotIndex, FPDFPage_GetAnnotIndex(pages[i], annot));
783     EXPECT_EQ(static_cast<int>(i), page_index);
784 
785     FPDFPage_CloseAnnot(annot);
786   }
787 
788   for (FPDF_PAGE page : pages)
789     UnloadPage(page);
790 }
791 
TEST_F(FPDFFormFillEmbedderTest,FormFillFirstTab)792 TEST_F(FPDFFormFillEmbedderTest, FormFillFirstTab) {
793   ASSERT_TRUE(OpenDocument("annotiter.pdf"));
794   FPDF_PAGE page = LoadPage(0);
795   ASSERT_TRUE(page);
796 
797   // Invoking first tab on the page.
798   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab, 0));
799   int page_index = -2;
800   FPDF_ANNOTATION annot = nullptr;
801   EXPECT_TRUE(FORM_GetFocusedAnnot(form_handle(), &page_index, &annot));
802   EXPECT_EQ(0, page_index);
803   ASSERT_TRUE(annot);
804   EXPECT_EQ(1, FPDFPage_GetAnnotIndex(page, annot));
805   FPDFPage_CloseAnnot(annot);
806 
807   UnloadPage(page);
808 }
809 
TEST_F(FPDFFormFillEmbedderTest,FormFillFirstShiftTab)810 TEST_F(FPDFFormFillEmbedderTest, FormFillFirstShiftTab) {
811   ASSERT_TRUE(OpenDocument("annotiter.pdf"));
812   FPDF_PAGE page = LoadPage(0);
813   ASSERT_TRUE(page);
814 
815   // Invoking first shift-tab on the page.
816   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab,
817                              FWL_EVENTFLAG_ShiftKey));
818   int page_index = -2;
819   FPDF_ANNOTATION annot = nullptr;
820   EXPECT_TRUE(FORM_GetFocusedAnnot(form_handle(), &page_index, &annot));
821   EXPECT_EQ(0, page_index);
822   ASSERT_TRUE(annot);
823   EXPECT_EQ(0, FPDFPage_GetAnnotIndex(page, annot));
824   FPDFPage_CloseAnnot(annot);
825 
826   UnloadPage(page);
827 }
828 
TEST_F(FPDFFormFillEmbedderTest,FormFillContinuousTab)829 TEST_F(FPDFFormFillEmbedderTest, FormFillContinuousTab) {
830   ASSERT_TRUE(OpenDocument("annotiter.pdf"));
831   FPDF_PAGE page = LoadPage(0);
832   ASSERT_TRUE(page);
833 
834   static constexpr int kExpectedAnnotIndex[] = {1, 2, 3, 0};
835   // Tabs should iterate focus over annotations.
836   for (size_t i = 0; i < std::size(kExpectedAnnotIndex); ++i) {
837     ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab, 0));
838     int page_index = -2;
839     FPDF_ANNOTATION annot = nullptr;
840     EXPECT_TRUE(FORM_GetFocusedAnnot(form_handle(), &page_index, &annot));
841     EXPECT_EQ(0, page_index);
842     ASSERT_TRUE(annot);
843     EXPECT_EQ(kExpectedAnnotIndex[i], FPDFPage_GetAnnotIndex(page, annot));
844     FPDFPage_CloseAnnot(annot);
845   }
846 
847   // Tab should not be handled as the last annotation of the page is in focus.
848   ASSERT_FALSE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab, 0));
849 
850   UnloadPage(page);
851 }
852 
TEST_F(FPDFFormFillEmbedderTest,FormFillContinuousShiftTab)853 TEST_F(FPDFFormFillEmbedderTest, FormFillContinuousShiftTab) {
854   ASSERT_TRUE(OpenDocument("annotiter.pdf"));
855   FPDF_PAGE page = LoadPage(0);
856   ASSERT_TRUE(page);
857 
858   static constexpr int kExpectedAnnotIndex[] = {0, 3, 2, 1};
859   // Shift-tabs should iterate focus over annotations.
860   for (size_t i = 0; i < std::size(kExpectedAnnotIndex); ++i) {
861     ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab,
862                                FWL_EVENTFLAG_ShiftKey));
863     int page_index = -2;
864     FPDF_ANNOTATION annot = nullptr;
865     EXPECT_TRUE(FORM_GetFocusedAnnot(form_handle(), &page_index, &annot));
866     EXPECT_EQ(0, page_index);
867     ASSERT_TRUE(annot);
868     EXPECT_EQ(kExpectedAnnotIndex[i], FPDFPage_GetAnnotIndex(page, annot));
869     FPDFPage_CloseAnnot(annot);
870   }
871 
872   // Shift-tab should not be handled as the first annotation of the page is in
873   // focus.
874   ASSERT_FALSE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab,
875                               FWL_EVENTFLAG_ShiftKey));
876 
877   UnloadPage(page);
878 }
879 
TEST_F(FPDFFormFillEmbedderTest,TabWithModifiers)880 TEST_F(FPDFFormFillEmbedderTest, TabWithModifiers) {
881   ASSERT_TRUE(OpenDocument("annotiter.pdf"));
882   FPDF_PAGE page = LoadPage(0);
883   ASSERT_TRUE(page);
884 
885   ASSERT_FALSE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab,
886                               FWL_EVENTFLAG_ControlKey));
887 
888   ASSERT_FALSE(
889       FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab, FWL_EVENTFLAG_AltKey));
890 
891   ASSERT_FALSE(
892       FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab,
893                      (FWL_EVENTFLAG_ControlKey | FWL_EVENTFLAG_ShiftKey)));
894 
895   ASSERT_FALSE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab,
896                               (FWL_EVENTFLAG_AltKey | FWL_EVENTFLAG_ShiftKey)));
897 
898   UnloadPage(page);
899 }
900 
TEST_F(FPDFFormFillEmbedderTest,KeyPressWithNoFocusedAnnot)901 TEST_F(FPDFFormFillEmbedderTest, KeyPressWithNoFocusedAnnot) {
902   ASSERT_TRUE(OpenDocument("annotiter.pdf"));
903   FPDF_PAGE page = LoadPage(0);
904   ASSERT_TRUE(page);
905 
906   // There should be no focused annotation to start with.
907   int page_index = -2;
908   FPDF_ANNOTATION annot = nullptr;
909   EXPECT_TRUE(FORM_GetFocusedAnnot(form_handle(), &page_index, &annot));
910   EXPECT_EQ(-1, page_index);
911   EXPECT_FALSE(annot);
912 
913   static constexpr int kKeysToPress[] = {
914       FWL_VKEY_NewLine, FWL_VKEY_Return, FWL_VKEY_Space,
915       FWL_VKEY_Delete,  FWL_VKEY_0,      FWL_VKEY_9,
916       FWL_VKEY_A,       FWL_VKEY_Z,      FWL_VKEY_F1,
917   };
918   for (int key : kKeysToPress) {
919     // Pressing random keys when there is no focus should not trigger focus.
920     EXPECT_FALSE(FORM_OnKeyDown(form_handle(), page, key, 0));
921     page_index = -2;
922     annot = nullptr;
923     EXPECT_TRUE(FORM_GetFocusedAnnot(form_handle(), &page_index, &annot));
924     EXPECT_EQ(-1, page_index);
925     EXPECT_FALSE(annot);
926   }
927 
928   UnloadPage(page);
929 }
930 
931 #ifdef PDF_ENABLE_XFA
TEST_F(FPDFFormFillEmbedderTest,XFAFormFillFirstTab)932 TEST_F(FPDFFormFillEmbedderTest, XFAFormFillFirstTab) {
933   ASSERT_TRUE(OpenDocument("xfa/email_recommended.pdf"));
934   FPDF_PAGE page = LoadPage(0);
935   ASSERT_TRUE(page);
936 
937   // Invoking first tab on the page.
938   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab, 0));
939 
940   UnloadPage(page);
941 }
942 
TEST_F(FPDFFormFillEmbedderTest,XFAFormFillFirstShiftTab)943 TEST_F(FPDFFormFillEmbedderTest, XFAFormFillFirstShiftTab) {
944   ASSERT_TRUE(OpenDocument("xfa/email_recommended.pdf"));
945   FPDF_PAGE page = LoadPage(0);
946   ASSERT_TRUE(page);
947 
948   // Invoking first shift-tab on the page.
949   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab,
950                              FWL_EVENTFLAG_ShiftKey));
951 
952   UnloadPage(page);
953 }
954 
TEST_F(FPDFFormFillEmbedderTest,XFAFormFillContinuousTab)955 TEST_F(FPDFFormFillEmbedderTest, XFAFormFillContinuousTab) {
956   ASSERT_TRUE(OpenDocument("xfa/email_recommended.pdf"));
957   FPDF_PAGE page = LoadPage(0);
958   ASSERT_TRUE(page);
959 
960   // Invoking first tab on the page.
961   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab, 0));
962 
963   // Subsequent tabs should move focus over annotations.
964   for (size_t i = 0; i < 9; ++i)
965     ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab, 0));
966 
967   // Tab should not be handled as the last annotation of the page is in focus.
968   ASSERT_FALSE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab, 0));
969 
970   UnloadPage(page);
971 }
972 
TEST_F(FPDFFormFillEmbedderTest,XFAFormFillContinuousShiftTab)973 TEST_F(FPDFFormFillEmbedderTest, XFAFormFillContinuousShiftTab) {
974   ASSERT_TRUE(OpenDocument("xfa/email_recommended.pdf"));
975   FPDF_PAGE page = LoadPage(0);
976   ASSERT_TRUE(page);
977 
978   // Invoking first shift-tab on the page.
979   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab,
980                              FWL_EVENTFLAG_ShiftKey));
981 
982   // Subsequent shift-tabs should move focus over annotations.
983   for (size_t i = 0; i < 9; ++i) {
984     ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab,
985                                FWL_EVENTFLAG_ShiftKey));
986   }
987 
988   // Shift-tab should not be handled as the first annotation of the page is in
989   // focus.
990   ASSERT_FALSE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab,
991                               FWL_EVENTFLAG_ShiftKey));
992 
993   UnloadPage(page);
994 }
995 #endif  // PDF_ENABLE_XFA
996 
997 class DoURIActionBlockedDelegate final : public EmbedderTest::Delegate {
998  public:
DoURIAction(FPDF_BYTESTRING uri)999   void DoURIAction(FPDF_BYTESTRING uri) override {
1000     FAIL() << "Navigated to " << uri;
1001   }
1002 };
1003 
TEST_F(FPDFFormFillEmbedderTest,BUG_851821)1004 TEST_F(FPDFFormFillEmbedderTest, BUG_851821) {
1005   DoURIActionBlockedDelegate delegate;
1006   SetDelegate(&delegate);
1007 
1008   ASSERT_TRUE(OpenDocument("redirect.pdf"));
1009   FPDF_PAGE page = LoadPage(0);
1010   EXPECT_TRUE(page);
1011   DoOpenActions();
1012 
1013   UnloadPage(page);
1014 }
1015 
TEST_F(FPDFFormFillEmbedderTest,CheckReadOnlyInCheckbox)1016 TEST_F(FPDFFormFillEmbedderTest, CheckReadOnlyInCheckbox) {
1017   EmbedderTestTimerHandlingDelegate delegate;
1018   SetDelegate(&delegate);
1019 
1020   ASSERT_TRUE(OpenDocument("click_form.pdf"));
1021   FPDF_PAGE page = LoadPage(0);
1022   ASSERT_TRUE(page);
1023 
1024   {
1025     // Check for read-only checkbox.
1026     ScopedFPDFAnnotation focused_annot(FPDFPage_GetAnnot(page, 1));
1027     ASSERT_TRUE(FORM_SetFocusedAnnot(form_handle(), focused_annot.get()));
1028 
1029     // Shift-tab to the previous control.
1030     ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab,
1031                                FWL_EVENTFLAG_ShiftKey));
1032     FPDF_ANNOTATION annot = nullptr;
1033     int page_index = -1;
1034     ASSERT_TRUE(FORM_GetFocusedAnnot(form_handle(), &page_index, &annot));
1035     EXPECT_EQ(0, FPDFPage_GetAnnotIndex(page, annot));
1036 
1037     // The read-only checkbox is initially in checked state.
1038     EXPECT_TRUE(FPDFAnnot_IsChecked(form_handle(), annot));
1039 
1040     EXPECT_TRUE(FORM_OnChar(form_handle(), page, pdfium::ascii::kReturn, 0));
1041     EXPECT_TRUE(FPDFAnnot_IsChecked(form_handle(), annot));
1042 
1043     EXPECT_TRUE(FORM_OnChar(form_handle(), page, pdfium::ascii::kSpace, 0));
1044     EXPECT_TRUE(FPDFAnnot_IsChecked(form_handle(), annot));
1045 
1046     FPDFPage_CloseAnnot(annot);
1047   }
1048   UnloadPage(page);
1049 }
1050 
TEST_F(FPDFFormFillEmbedderTest,CheckReadOnlyInRadiobutton)1051 TEST_F(FPDFFormFillEmbedderTest, CheckReadOnlyInRadiobutton) {
1052   EmbedderTestTimerHandlingDelegate delegate;
1053   SetDelegate(&delegate);
1054 
1055   ASSERT_TRUE(OpenDocument("click_form.pdf"));
1056   FPDF_PAGE page = LoadPage(0);
1057   ASSERT_TRUE(page);
1058 
1059   {
1060     // Check for read-only radio button.
1061     ScopedFPDFAnnotation focused_annot(FPDFPage_GetAnnot(page, 1));
1062     ASSERT_TRUE(FORM_SetFocusedAnnot(form_handle(), focused_annot.get()));
1063 
1064     // Tab to the next control.
1065     ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page, FWL_VKEY_Tab, 0));
1066 
1067     FPDF_ANNOTATION annot = nullptr;
1068     int page_index = -1;
1069     ASSERT_TRUE(FORM_GetFocusedAnnot(form_handle(), &page_index, &annot));
1070     EXPECT_EQ(2, FPDFPage_GetAnnotIndex(page, annot));
1071     // The read-only radio button is initially in checked state.
1072     EXPECT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot));
1073 
1074     EXPECT_TRUE(FORM_OnChar(form_handle(), page, pdfium::ascii::kReturn, 0));
1075     EXPECT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot));
1076 
1077     EXPECT_TRUE(FORM_OnChar(form_handle(), page, pdfium::ascii::kSpace, 0));
1078     EXPECT_FALSE(FPDFAnnot_IsChecked(form_handle(), annot));
1079 
1080     FPDFPage_CloseAnnot(annot);
1081   }
1082   UnloadPage(page);
1083 }
1084 
1085 #ifdef PDF_ENABLE_V8
TEST_F(FPDFFormFillEmbedderTest,DisableJavaScript)1086 TEST_F(FPDFFormFillEmbedderTest, DisableJavaScript) {
1087   // Test that timers and intervals can't fire without JS.
1088   EmbedderTestTimerHandlingDelegate delegate;
1089   SetDelegate(&delegate);
1090 
1091   ASSERT_TRUE(OpenDocumentWithoutJavaScript("bug_551248.pdf"));
1092   FPDF_PAGE page = LoadPage(0);
1093   EXPECT_TRUE(page);
1094   DoOpenActions();
1095 
1096   const auto& alerts = delegate.GetAlerts();
1097   EXPECT_EQ(0U, alerts.size());
1098 
1099   delegate.AdvanceTime(1000);
1100   EXPECT_EQ(0U, alerts.size());  // nothing fired.
1101   delegate.AdvanceTime(1000);
1102   EXPECT_EQ(0U, alerts.size());  // nothing fired.
1103   delegate.AdvanceTime(1000);
1104   EXPECT_EQ(0U, alerts.size());  // nothing fired.
1105   delegate.AdvanceTime(1000);
1106   EXPECT_EQ(0U, alerts.size());  // nothing fired.
1107   delegate.AdvanceTime(1000);
1108   EXPECT_EQ(0U, alerts.size());  // nothing fired.
1109   delegate.AdvanceTime(1000);
1110   EXPECT_EQ(0U, alerts.size());  // nothing fired.
1111   delegate.AdvanceTime(1000);
1112   EXPECT_EQ(0U, alerts.size());  // nothing fired.
1113   UnloadPage(page);
1114 }
1115 
TEST_F(FPDFFormFillEmbedderTest,DocumentAActions)1116 TEST_F(FPDFFormFillEmbedderTest, DocumentAActions) {
1117   EmbedderTestTimerHandlingDelegate delegate;
1118   SetDelegate(&delegate);
1119 
1120   ASSERT_TRUE(OpenDocument("document_aactions.pdf"));
1121   FPDF_PAGE page = LoadPage(0);
1122   EXPECT_TRUE(page);
1123 
1124   const auto& alerts = delegate.GetAlerts();
1125   EXPECT_EQ(0U, alerts.size());
1126 
1127   FORM_DoDocumentAAction(form_handle(), FPDFDOC_AACTION_WS);
1128   FORM_DoDocumentAAction(form_handle(), FPDFDOC_AACTION_DS);
1129   FORM_DoDocumentAAction(form_handle(), FPDFDOC_AACTION_WP);
1130   FORM_DoDocumentAAction(form_handle(), FPDFDOC_AACTION_DP);
1131   UnloadPage(page);
1132 
1133   ASSERT_EQ(4U, alerts.size());
1134   EXPECT_STREQ(L"Will Save", alerts[0].message.c_str());
1135   EXPECT_STREQ(L"Did Save", alerts[1].message.c_str());
1136   EXPECT_STREQ(L"Will Print", alerts[2].message.c_str());
1137   EXPECT_STREQ(L"Did Print", alerts[3].message.c_str());
1138 }
1139 
TEST_F(FPDFFormFillEmbedderTest,DocumentAActionsDisableJavaScript)1140 TEST_F(FPDFFormFillEmbedderTest, DocumentAActionsDisableJavaScript) {
1141   EmbedderTestTimerHandlingDelegate delegate;
1142   SetDelegate(&delegate);
1143 
1144   ASSERT_TRUE(OpenDocumentWithoutJavaScript("document_aactions.pdf"));
1145   FPDF_PAGE page = LoadPage(0);
1146   EXPECT_TRUE(page);
1147 
1148   const auto& alerts = delegate.GetAlerts();
1149   EXPECT_EQ(0U, alerts.size());
1150 
1151   FORM_DoDocumentAAction(form_handle(), FPDFDOC_AACTION_WS);
1152   FORM_DoDocumentAAction(form_handle(), FPDFDOC_AACTION_DS);
1153   FORM_DoDocumentAAction(form_handle(), FPDFDOC_AACTION_WP);
1154   FORM_DoDocumentAAction(form_handle(), FPDFDOC_AACTION_DP);
1155   UnloadPage(page);
1156 
1157   ASSERT_EQ(0U, alerts.size());
1158 }
1159 
TEST_F(FPDFFormFillEmbedderTest,BUG_551248)1160 TEST_F(FPDFFormFillEmbedderTest, BUG_551248) {
1161   // Test that timers fire once and intervals fire repeatedly.
1162   EmbedderTestTimerHandlingDelegate delegate;
1163   SetDelegate(&delegate);
1164 
1165   ASSERT_TRUE(OpenDocument("bug_551248.pdf"));
1166   FPDF_PAGE page = LoadPage(0);
1167   EXPECT_TRUE(page);
1168   DoOpenActions();
1169 
1170   const auto& alerts = delegate.GetAlerts();
1171   EXPECT_EQ(0U, alerts.size());
1172 
1173   delegate.AdvanceTime(1000);
1174   EXPECT_EQ(0U, alerts.size());  // nothing fired.
1175   delegate.AdvanceTime(1000);
1176   EXPECT_EQ(1U, alerts.size());  // interval fired.
1177   delegate.AdvanceTime(1000);
1178   EXPECT_EQ(2U, alerts.size());  // timer fired.
1179   delegate.AdvanceTime(1000);
1180   EXPECT_EQ(3U, alerts.size());  // interval fired again.
1181   delegate.AdvanceTime(1000);
1182   EXPECT_EQ(3U, alerts.size());  // nothing fired.
1183   delegate.AdvanceTime(1000);
1184   EXPECT_EQ(4U, alerts.size());  // interval fired again.
1185   delegate.AdvanceTime(1000);
1186   EXPECT_EQ(4U, alerts.size());  // nothing fired.
1187   UnloadPage(page);
1188 
1189   ASSERT_EQ(4U, alerts.size());  // nothing else fired.
1190 
1191   EXPECT_STREQ(L"interval fired", alerts[0].message.c_str());
1192   EXPECT_STREQ(L"Alert", alerts[0].title.c_str());
1193   EXPECT_EQ(0, alerts[0].type);
1194   EXPECT_EQ(0, alerts[0].icon);
1195 
1196   EXPECT_STREQ(L"timer fired", alerts[1].message.c_str());
1197   EXPECT_STREQ(L"Alert", alerts[1].title.c_str());
1198   EXPECT_EQ(0, alerts[1].type);
1199   EXPECT_EQ(0, alerts[1].icon);
1200 
1201   EXPECT_STREQ(L"interval fired", alerts[2].message.c_str());
1202   EXPECT_STREQ(L"Alert", alerts[2].title.c_str());
1203   EXPECT_EQ(0, alerts[2].type);
1204   EXPECT_EQ(0, alerts[2].icon);
1205 
1206   EXPECT_STREQ(L"interval fired", alerts[3].message.c_str());
1207   EXPECT_STREQ(L"Alert", alerts[3].title.c_str());
1208   EXPECT_EQ(0, alerts[3].type);
1209   EXPECT_EQ(0, alerts[3].icon);
1210 }
1211 
TEST_F(FPDFFormFillEmbedderTest,BUG_620428)1212 TEST_F(FPDFFormFillEmbedderTest, BUG_620428) {
1213   // Test that timers and intervals are cancelable.
1214   EmbedderTestTimerHandlingDelegate delegate;
1215   SetDelegate(&delegate);
1216 
1217   ASSERT_TRUE(OpenDocument("bug_620428.pdf"));
1218   FPDF_PAGE page = LoadPage(0);
1219   EXPECT_TRUE(page);
1220   DoOpenActions();
1221   delegate.AdvanceTime(5000);
1222   UnloadPage(page);
1223 
1224   const auto& alerts = delegate.GetAlerts();
1225   ASSERT_EQ(1U, alerts.size());
1226   EXPECT_STREQ(L"done", alerts[0].message.c_str());
1227 }
1228 
TEST_F(FPDFFormFillEmbedderTest,BUG_634394)1229 TEST_F(FPDFFormFillEmbedderTest, BUG_634394) {
1230   // Cancel timer inside timer callback.
1231   EmbedderTestTimerHandlingDelegate delegate;
1232   SetDelegate(&delegate);
1233 
1234   ASSERT_TRUE(OpenDocument("bug_634394.pdf"));
1235   FPDF_PAGE page = LoadPage(0);
1236   EXPECT_TRUE(page);
1237   DoOpenActions();
1238 
1239   // Timers fire at most once per AdvanceTime(), allow intervals
1240   // to fire several times if possible.
1241   delegate.AdvanceTime(1000);
1242   delegate.AdvanceTime(1000);
1243   delegate.AdvanceTime(1000);
1244   delegate.AdvanceTime(1000);
1245   delegate.AdvanceTime(1000);
1246   UnloadPage(page);
1247 
1248   const auto& alerts = delegate.GetAlerts();
1249   EXPECT_EQ(2U, alerts.size());
1250 }
1251 
TEST_F(FPDFFormFillEmbedderTest,BUG_634716)1252 TEST_F(FPDFFormFillEmbedderTest, BUG_634716) {
1253   EmbedderTestTimerHandlingDelegate delegate;
1254   SetDelegate(&delegate);
1255 
1256   ASSERT_TRUE(OpenDocument("bug_634716.pdf"));
1257   FPDF_PAGE page = LoadPage(0);
1258   EXPECT_TRUE(page);
1259   DoOpenActions();
1260 
1261   // Timers fire at most once per AdvanceTime(), allow intervals
1262   // to fire several times if possible.
1263   delegate.AdvanceTime(1000);
1264   delegate.AdvanceTime(1000);
1265   delegate.AdvanceTime(1000);
1266   delegate.AdvanceTime(1000);
1267   delegate.AdvanceTime(1000);
1268   UnloadPage(page);
1269 
1270   const auto& alerts = delegate.GetAlerts();
1271   EXPECT_EQ(2U, alerts.size());
1272 }
1273 
TEST_F(FPDFFormFillEmbedderTest,BUG_679649)1274 TEST_F(FPDFFormFillEmbedderTest, BUG_679649) {
1275   EmbedderTestTimerHandlingDelegate delegate;
1276   SetDelegate(&delegate);
1277 
1278   ASSERT_TRUE(OpenDocument("bug_679649.pdf"));
1279   FPDF_PAGE page = LoadPage(0);
1280   EXPECT_TRUE(page);
1281 
1282   delegate.SetFailNextTimer();
1283   DoOpenActions();
1284   delegate.AdvanceTime(2000);
1285   UnloadPage(page);
1286 
1287   const auto& alerts = delegate.GetAlerts();
1288   EXPECT_EQ(0u, alerts.size());
1289 }
1290 
TEST_F(FPDFFormFillEmbedderTest,BUG_707673)1291 TEST_F(FPDFFormFillEmbedderTest, BUG_707673) {
1292   EmbedderTestTimerHandlingDelegate delegate;
1293   SetDelegate(&delegate);
1294 
1295   ASSERT_TRUE(OpenDocument("bug_707673.pdf"));
1296   FPDF_PAGE page = LoadPage(0);
1297   EXPECT_TRUE(page);
1298 
1299   DoOpenActions();
1300   FORM_OnLButtonDown(form_handle(), page, 0, 140, 590);
1301   FORM_OnLButtonUp(form_handle(), page, 0, 140, 590);
1302   delegate.AdvanceTime(1000);
1303   UnloadPage(page);
1304 
1305   const auto& alerts = delegate.GetAlerts();
1306   EXPECT_EQ(0u, alerts.size());
1307 }
1308 
TEST_F(FPDFFormFillEmbedderTest,BUG_765384)1309 TEST_F(FPDFFormFillEmbedderTest, BUG_765384) {
1310   ASSERT_TRUE(OpenDocument("bug_765384.pdf"));
1311   FPDF_PAGE page = LoadPage(0);
1312   EXPECT_TRUE(page);
1313 
1314   DoOpenActions();
1315   FORM_OnLButtonDown(form_handle(), page, 0, 140, 590);
1316   FORM_OnLButtonUp(form_handle(), page, 0, 140, 590);
1317   UnloadPage(page);
1318 }
1319 #endif  // PDF_ENABLE_V8
1320 
TEST_F(FPDFFormFillEmbedderTest,FormText)1321 TEST_F(FPDFFormFillEmbedderTest, FormText) {
1322   const char* focused_text_form_with_abc_checksum = []() {
1323     if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
1324       return "b9fb2245a98ac48146da84237a37f8cc";
1325 #if BUILDFLAG(IS_APPLE)
1326     return "9fb14198d75ca0a107060c60ca21b0c7";
1327 #else
1328     return "6e6f790bb14c4fc6107faf8c17d23dbd";
1329 #endif
1330   }();
1331   const char* unfocused_text_form_with_abc_checksum = []() {
1332     if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
1333       return "5f3205f0189d9dde54665f970838f614";
1334 #if BUILDFLAG(IS_APPLE)
1335     return "3c3209357e0c057a0620afa7d83eb784";
1336 #else
1337     return "94b7e10ac8c662b73e33628ca2f5e63b";
1338 #endif
1339   }();
1340   {
1341     ASSERT_TRUE(OpenDocument("text_form.pdf"));
1342     FPDF_PAGE page = LoadPage(0);
1343     ASSERT_TRUE(page);
1344     ScopedFPDFBitmap bitmap1 = RenderLoadedPage(page);
1345     CompareBitmap(bitmap1.get(), 300, 300, TextFormChecksum());
1346 
1347     // Click on the textfield
1348     EXPECT_EQ(FPDF_FORMFIELD_TEXTFIELD,
1349               FPDFPage_HasFormFieldAtPoint(form_handle(), page, 120.0, 120.0));
1350     EXPECT_EQ(
1351         0, FPDFPage_FormFieldZOrderAtPoint(form_handle(), page, 120.0, 120.0));
1352     FORM_OnMouseMove(form_handle(), page, 0, 120.0, 120.0);
1353     FORM_OnLButtonDown(form_handle(), page, 0, 120.0, 120.0);
1354     FORM_OnLButtonUp(form_handle(), page, 0, 120.0, 120.0);
1355 
1356     // Write "ABC"
1357     FORM_OnChar(form_handle(), page, 'A', 0);
1358     FORM_OnChar(form_handle(), page, 'B', 0);
1359     FORM_OnChar(form_handle(), page, 'C', 0);
1360     ScopedFPDFBitmap bitmap2 = RenderLoadedPage(page);
1361     CompareBitmap(bitmap2.get(), 300, 300, focused_text_form_with_abc_checksum);
1362 
1363     // Focus remains despite right clicking out of the textfield
1364     FORM_OnMouseMove(form_handle(), page, 0, 15.0, 15.0);
1365     FORM_OnRButtonDown(form_handle(), page, 0, 15.0, 15.0);
1366     FORM_OnRButtonUp(form_handle(), page, 0, 15.0, 15.0);
1367     ScopedFPDFBitmap bitmap3 = RenderLoadedPage(page);
1368     CompareBitmap(bitmap3.get(), 300, 300, focused_text_form_with_abc_checksum);
1369 
1370     // Take out focus by clicking out of the textfield
1371     FORM_OnMouseMove(form_handle(), page, 0, 15.0, 15.0);
1372     FORM_OnLButtonDown(form_handle(), page, 0, 15.0, 15.0);
1373     FORM_OnLButtonUp(form_handle(), page, 0, 15.0, 15.0);
1374     ScopedFPDFBitmap bitmap4 = RenderLoadedPage(page);
1375     CompareBitmap(bitmap4.get(), 300, 300,
1376                   unfocused_text_form_with_abc_checksum);
1377 
1378     EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
1379 
1380     // Close page
1381     UnloadPage(page);
1382   }
1383   // Check saved document
1384   VerifySavedDocument(300, 300, unfocused_text_form_with_abc_checksum);
1385 }
1386 
1387 // Tests using FPDF_REVERSE_BYTE_ORDER with FPDF_FFLDraw(). The two rendered
1388 // bitmaps should be different.
TEST_F(FPDFFormFillEmbedderTest,BUG_1281)1389 TEST_F(FPDFFormFillEmbedderTest, BUG_1281) {
1390   const char* reverse_byte_order_checksum = []() {
1391     if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
1392       return "8077970bbd10333f18186a9bb459bbe6";
1393     return "24fff03d1e663b7ece5f6e69ad837124";
1394   }();
1395 
1396   ASSERT_TRUE(OpenDocument("bug_890322.pdf"));
1397   FPDF_PAGE page = LoadPage(0);
1398   ASSERT_TRUE(page);
1399 
1400   ScopedFPDFBitmap bitmap_normal = RenderLoadedPage(page);
1401   CompareBitmap(bitmap_normal.get(), 200, 200, pdfium::Bug890322Checksum());
1402 
1403   ScopedFPDFBitmap bitmap_reverse_byte_order =
1404       RenderLoadedPageWithFlags(page, FPDF_REVERSE_BYTE_ORDER);
1405   CompareBitmap(bitmap_reverse_byte_order.get(), 200, 200,
1406                 reverse_byte_order_checksum);
1407 
1408   UnloadPage(page);
1409 }
1410 
TEST_F(FPDFFormFillEmbedderTest,Bug1302455RenderOnly)1411 TEST_F(FPDFFormFillEmbedderTest, Bug1302455RenderOnly) {
1412   const char* checksum = []() {
1413     if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
1414       return "520c4415c9977f40d6b4af5a0a94d764";
1415     return "bbee92af1daec2340c81f482878744d8";
1416   }();
1417   {
1418     ASSERT_TRUE(OpenDocument("bug_1302455.pdf"));
1419     FPDF_PAGE page = LoadPage(0);
1420     ASSERT_TRUE(page);
1421 
1422     ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
1423     CompareBitmap(bitmap.get(), 300, 300, checksum);
1424 
1425     EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
1426 
1427     UnloadPage(page);
1428   }
1429   VerifySavedDocument(300, 300, checksum);
1430 }
1431 
TEST_F(FPDFFormFillEmbedderTest,Bug1302455EditFirstForm)1432 TEST_F(FPDFFormFillEmbedderTest, Bug1302455EditFirstForm) {
1433   const char* checksum = []() {
1434     if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
1435       return "143c2bb79fcaecf24f5aa104dce27beb";
1436 #if BUILDFLAG(IS_APPLE)
1437     return "bf5423874f188427d2500a2bc4abebbe";
1438 #else
1439     return "6a4ac9a15d2c34589616c8f2b05fbedd";
1440 #endif
1441   }();
1442   {
1443     ASSERT_TRUE(OpenDocument("bug_1302455.pdf"));
1444     FPDF_PAGE page = LoadPage(0);
1445     ASSERT_TRUE(page);
1446 
1447     EXPECT_EQ(FPDF_FORMFIELD_TEXTFIELD,
1448               FPDFPage_HasFormFieldAtPoint(form_handle(), page, 110, 110));
1449     FORM_OnMouseMove(form_handle(), page, 0, 110, 110);
1450     FORM_OnLButtonDown(form_handle(), page, 0, 110, 110);
1451     FORM_OnLButtonUp(form_handle(), page, 0, 110, 110);
1452     FORM_OnChar(form_handle(), page, 'A', 0);
1453 
1454     FORM_ForceToKillFocus(form_handle());
1455     ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
1456     CompareBitmap(bitmap.get(), 300, 300, checksum);
1457 
1458     EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
1459 
1460     UnloadPage(page);
1461   }
1462   VerifySavedDocument(300, 300, checksum);
1463 }
1464 
TEST_F(FPDFFormFillEmbedderTest,Bug1302455EditSecondForm)1465 TEST_F(FPDFFormFillEmbedderTest, Bug1302455EditSecondForm) {
1466   const char* checksum = []() {
1467     if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
1468       return "e36726414acb616dc203e8851b510e2c";
1469 #if BUILDFLAG(IS_APPLE)
1470     return "8a0fd8772dba6e1e952e49d159cc64b5";
1471 #else
1472     return "45a7694933c2ba3c5dc8f6cc18b79175";
1473 #endif
1474   }();
1475   {
1476     ASSERT_TRUE(OpenDocument("bug_1302455.pdf"));
1477     FPDF_PAGE page = LoadPage(0);
1478     ASSERT_TRUE(page);
1479 
1480     EXPECT_EQ(FPDF_FORMFIELD_TEXTFIELD,
1481               FPDFPage_HasFormFieldAtPoint(form_handle(), page, 110, 170));
1482     FORM_OnMouseMove(form_handle(), page, 0, 110, 170);
1483     FORM_OnLButtonDown(form_handle(), page, 0, 110, 170);
1484     FORM_OnLButtonUp(form_handle(), page, 0, 110, 170);
1485     FORM_OnChar(form_handle(), page, 'B', 0);
1486 
1487     FORM_ForceToKillFocus(form_handle());
1488     ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
1489     CompareBitmap(bitmap.get(), 300, 300, checksum);
1490 
1491     EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
1492 
1493     UnloadPage(page);
1494   }
1495   VerifySavedDocument(300, 300, checksum);
1496 }
1497 
TEST_F(FPDFFormFillEmbedderTest,Bug1302455EditBothForms)1498 TEST_F(FPDFFormFillEmbedderTest, Bug1302455EditBothForms) {
1499   const char* checksum = []() {
1500     if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
1501       return "f82a807c056e22aa55d3d7228eedfe6f";
1502 #if BUILDFLAG(IS_APPLE)
1503     return "1f422ee1c520ad74b1a993b64bd4dc4a";
1504 #else
1505     return "13984969b1e141079ab5f4aa80185463";
1506 #endif
1507   }();
1508   {
1509     ASSERT_TRUE(OpenDocument("bug_1302455.pdf"));
1510     FPDF_PAGE page = LoadPage(0);
1511     ASSERT_TRUE(page);
1512 
1513     EXPECT_EQ(FPDF_FORMFIELD_TEXTFIELD,
1514               FPDFPage_HasFormFieldAtPoint(form_handle(), page, 110, 110));
1515     FORM_OnMouseMove(form_handle(), page, 0, 110, 110);
1516     FORM_OnLButtonDown(form_handle(), page, 0, 110, 110);
1517     FORM_OnLButtonUp(form_handle(), page, 0, 110, 110);
1518     FORM_OnChar(form_handle(), page, 'A', 0);
1519 
1520     EXPECT_EQ(FPDF_FORMFIELD_TEXTFIELD,
1521               FPDFPage_HasFormFieldAtPoint(form_handle(), page, 110, 170));
1522     FORM_OnMouseMove(form_handle(), page, 0, 110, 170);
1523     FORM_OnLButtonDown(form_handle(), page, 0, 110, 170);
1524     FORM_OnLButtonUp(form_handle(), page, 0, 110, 170);
1525     FORM_OnChar(form_handle(), page, 'B', 0);
1526 
1527     FORM_ForceToKillFocus(form_handle());
1528     ScopedFPDFBitmap bitmap = RenderLoadedPage(page);
1529     CompareBitmap(bitmap.get(), 300, 300, checksum);
1530 
1531     EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
1532 
1533     UnloadPage(page);
1534   }
1535   VerifySavedDocument(300, 300, checksum);
1536 }
1537 
TEST_F(FPDFFormFillEmbedderTest,RemoveFormFieldHighlight)1538 TEST_F(FPDFFormFillEmbedderTest, RemoveFormFieldHighlight) {
1539   const char* no_highlight_checksum = []() {
1540     if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer()) {
1541       return "3bfddb2529085021ad283b7e65f71525";
1542     }
1543 #if BUILDFLAG(IS_APPLE)
1544     return "5c82aa43e3b478aa1e4c94bb9ef1f11f";
1545 #else
1546     return "a6268304f7eedfa9ee98fac3caaf2efb";
1547 #endif
1548   }();
1549 
1550   ASSERT_TRUE(OpenDocument("text_form.pdf"));
1551   FPDF_PAGE page = LoadPage(0);
1552   ASSERT_TRUE(page);
1553   ScopedFPDFBitmap bitmap1 = RenderLoadedPage(page);
1554   CompareBitmap(bitmap1.get(), 300, 300, TextFormChecksum());
1555 
1556   // Removing the highlight changes the rendering.
1557   FPDF_RemoveFormFieldHighlight(form_handle());
1558   ScopedFPDFBitmap bitmap2 = RenderLoadedPage(page);
1559   CompareBitmap(bitmap2.get(), 300, 300, no_highlight_checksum);
1560 
1561   // Restoring it gives the original rendering.
1562   SetInitialFormFieldHighlight(form_handle());
1563   ScopedFPDFBitmap bitmap3 = RenderLoadedPage(page);
1564   CompareBitmap(bitmap3.get(), 300, 300, TextFormChecksum());
1565 
1566   UnloadPage(page);
1567 }
1568 
TEST_F(FPDFFormFillEmbedderTest,HasFormInfoNone)1569 TEST_F(FPDFFormFillEmbedderTest, HasFormInfoNone) {
1570   ASSERT_TRUE(OpenDocument("hello_world.pdf"));
1571   EXPECT_EQ(FORMTYPE_NONE, FPDF_GetFormType(document()));
1572 }
1573 
TEST_F(FPDFFormFillEmbedderTest,HasFormInfoAcroForm)1574 TEST_F(FPDFFormFillEmbedderTest, HasFormInfoAcroForm) {
1575   ASSERT_TRUE(OpenDocument("text_form.pdf"));
1576   EXPECT_EQ(FORMTYPE_ACRO_FORM, FPDF_GetFormType(document()));
1577 }
1578 
TEST_F(FPDFFormFillEmbedderTest,HasFormInfoXFAFull)1579 TEST_F(FPDFFormFillEmbedderTest, HasFormInfoXFAFull) {
1580   ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1581   EXPECT_EQ(FORMTYPE_XFA_FULL, FPDF_GetFormType(document()));
1582 }
1583 
TEST_F(FPDFFormFillEmbedderTest,HasFormInfoXFAForeground)1584 TEST_F(FPDFFormFillEmbedderTest, HasFormInfoXFAForeground) {
1585   ASSERT_TRUE(OpenDocument("bug_216.pdf"));
1586   EXPECT_EQ(FORMTYPE_XFA_FOREGROUND, FPDF_GetFormType(document()));
1587 }
1588 
TEST_F(FPDFFormFillEmbedderTest,BadApiInputsText)1589 TEST_F(FPDFFormFillEmbedderTest, BadApiInputsText) {
1590   ASSERT_TRUE(OpenDocument("text_form.pdf"));
1591   FPDF_PAGE page = LoadPage(0);
1592   ASSERT_TRUE(page);
1593 
1594   EXPECT_FALSE(FORM_SetIndexSelected(nullptr, nullptr, 0, true));
1595   EXPECT_FALSE(FORM_SetIndexSelected(nullptr, page, 0, true));
1596   EXPECT_FALSE(FORM_SetIndexSelected(form_handle(), nullptr, 0, true));
1597   EXPECT_FALSE(FORM_SetIndexSelected(form_handle(), page, -1, true));
1598   EXPECT_FALSE(FORM_IsIndexSelected(nullptr, nullptr, 0));
1599   EXPECT_FALSE(FORM_IsIndexSelected(nullptr, page, 0));
1600   EXPECT_FALSE(FORM_IsIndexSelected(form_handle(), nullptr, 0));
1601   EXPECT_FALSE(FORM_IsIndexSelected(form_handle(), page, -1));
1602 
1603   UnloadPage(page);
1604 }
1605 
TEST_F(FPDFFormFillEmbedderTest,BadApiInputsComboBox)1606 TEST_F(FPDFFormFillEmbedderTest, BadApiInputsComboBox) {
1607   ASSERT_TRUE(OpenDocument("combobox_form.pdf"));
1608   FPDF_PAGE page = LoadPage(0);
1609   ASSERT_TRUE(page);
1610 
1611   EXPECT_FALSE(FORM_SetIndexSelected(form_handle(), page, -1, true));
1612   EXPECT_FALSE(FORM_SetIndexSelected(form_handle(), page, 100, true));
1613   EXPECT_FALSE(FORM_IsIndexSelected(form_handle(), page, -1));
1614   EXPECT_FALSE(FORM_IsIndexSelected(form_handle(), page, 100));
1615 
1616   UnloadPage(page);
1617 }
1618 
TEST_F(FPDFFormFillEmbedderTest,BadApiInputsListBox)1619 TEST_F(FPDFFormFillEmbedderTest, BadApiInputsListBox) {
1620   ASSERT_TRUE(OpenDocument("listbox_form.pdf"));
1621   FPDF_PAGE page = LoadPage(0);
1622   ASSERT_TRUE(page);
1623 
1624   EXPECT_FALSE(FORM_SetIndexSelected(form_handle(), page, -1, true));
1625   EXPECT_FALSE(FORM_SetIndexSelected(form_handle(), page, 100, true));
1626   EXPECT_FALSE(FORM_IsIndexSelected(form_handle(), page, -1));
1627   EXPECT_FALSE(FORM_IsIndexSelected(form_handle(), page, 100));
1628 
1629   UnloadPage(page);
1630 }
1631 
TEST_F(FPDFFormFillEmbedderTest,HasFormFieldAtPointForXFADoc)1632 TEST_F(FPDFFormFillEmbedderTest, HasFormFieldAtPointForXFADoc) {
1633   ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
1634   FPDF_PAGE page = LoadPage(0);
1635   ASSERT_TRUE(page);
1636 
1637   EXPECT_EQ(-1, FPDFPage_HasFormFieldAtPoint(form_handle(), page, 612, 792));
1638 
1639 #ifdef PDF_ENABLE_XFA
1640   constexpr int kExpectedFieldType = FPDF_FORMFIELD_XFA_TEXTFIELD;
1641 #else
1642   constexpr int kExpectedFieldType = -1;
1643 #endif
1644   EXPECT_EQ(kExpectedFieldType,
1645             FPDFPage_HasFormFieldAtPoint(form_handle(), page, 50, 30));
1646 
1647   UnloadPage(page);
1648 }
1649 
TEST_F(FPDFFormFillEmbedderTest,SelectAllText)1650 TEST_F(FPDFFormFillEmbedderTest, SelectAllText) {
1651   ASSERT_TRUE(OpenDocument("text_form.pdf"));
1652   FPDF_PAGE page = LoadPage(0);
1653   ASSERT_TRUE(page);
1654 
1655   // Test bad arguments.
1656   EXPECT_FALSE(FORM_SelectAllText(nullptr, nullptr));
1657   EXPECT_FALSE(FORM_SelectAllText(form_handle(), nullptr));
1658   EXPECT_FALSE(FORM_SelectAllText(nullptr, page));
1659 
1660   // Focus on the text field and add some text.
1661   EXPECT_TRUE(FORM_OnFocus(form_handle(), page, 0, 115, 115));
1662   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
1663   FORM_ReplaceSelection(form_handle(), page, text_to_insert.get());
1664 
1665   // Sanity check text field data.
1666   uint16_t buffer[6];
1667   ASSERT_EQ(12u, FORM_GetFocusedText(form_handle(), page, nullptr, 0));
1668   ASSERT_EQ(12u,
1669             FORM_GetFocusedText(form_handle(), page, buffer, sizeof(buffer)));
1670   EXPECT_EQ("Hello", GetPlatformString(buffer));
1671 
1672   // Check there is no selection.
1673   ASSERT_EQ(2u, FORM_GetSelectedText(form_handle(), page, nullptr, 0));
1674   ASSERT_EQ(2u,
1675             FORM_GetSelectedText(form_handle(), page, buffer, sizeof(buffer)));
1676   EXPECT_EQ("", GetPlatformString(buffer));
1677 
1678   // Check FORM_SelectAllText() works.
1679   EXPECT_TRUE(FORM_SelectAllText(form_handle(), page));
1680   ASSERT_EQ(12u, FORM_GetSelectedText(form_handle(), page, nullptr, 0));
1681   ASSERT_EQ(12u,
1682             FORM_GetSelectedText(form_handle(), page, buffer, sizeof(buffer)));
1683   EXPECT_EQ("Hello", GetPlatformString(buffer));
1684 
1685   UnloadPage(page);
1686 }
1687 
TEST_F(FPDFFormFillTextFormEmbedderTest,GetSelectedTextEmptyAndBasicKeyboard)1688 TEST_F(FPDFFormFillTextFormEmbedderTest, GetSelectedTextEmptyAndBasicKeyboard) {
1689   // Test empty selection.
1690   CheckFocusedFieldText(L"");
1691   CheckSelection(L"");
1692 
1693   // Test basic selection.
1694   TypeTextIntoTextField(3, RegularFormBegin());
1695   CheckFocusedFieldText(L"ABC");
1696   SelectTextWithKeyboard(3, FWL_VKEY_Left, RegularFormAtX(123.0));
1697   CheckSelection(L"ABC");
1698 }
1699 
TEST_F(FPDFFormFillTextFormEmbedderTest,GetSelectedTextEmptyAndBasicMouse)1700 TEST_F(FPDFFormFillTextFormEmbedderTest, GetSelectedTextEmptyAndBasicMouse) {
1701   // Test empty selection.
1702   CheckFocusedFieldText(L"");
1703   CheckSelection(L"");
1704 
1705   // Test basic selection.
1706   TypeTextIntoTextField(3, RegularFormBegin());
1707   CheckFocusedFieldText(L"ABC");
1708   SelectTextWithMouse(RegularFormAtX(125.0), RegularFormBegin());
1709   CheckSelection(L"ABC");
1710 }
1711 
TEST_F(FPDFFormFillTextFormEmbedderTest,GetSelectedTextFragmentsKeyBoard)1712 TEST_F(FPDFFormFillTextFormEmbedderTest, GetSelectedTextFragmentsKeyBoard) {
1713   TypeTextIntoTextField(12, RegularFormBegin());
1714   CheckFocusedFieldText(L"ABCDEFGHIJKL");
1715 
1716   // Test selecting first character in forward direction.
1717   SelectTextWithKeyboard(1, FWL_VKEY_Right, RegularFormBegin());
1718   CheckSelection(L"A");
1719 
1720   // Test selecting entire long string in backwards direction.
1721   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
1722   CheckSelection(L"ABCDEFGHIJKL");
1723 
1724   // Test selecting middle section in backwards direction.
1725   SelectTextWithKeyboard(6, FWL_VKEY_Left, RegularFormAtX(170.0));
1726   CheckSelection(L"DEFGHI");
1727 
1728   // Test selecting middle selection in forward direction.
1729   SelectTextWithKeyboard(6, FWL_VKEY_Right, RegularFormAtX(125.0));
1730   CheckSelection(L"DEFGHI");
1731 
1732   // Test selecting last character in backwards direction.
1733   SelectTextWithKeyboard(1, FWL_VKEY_Left, RegularFormEnd());
1734   CheckSelection(L"L");
1735   CheckFocusedFieldText(L"ABCDEFGHIJKL");
1736 }
1737 
TEST_F(FPDFFormFillTextFormEmbedderTest,GetSelectedTextFragmentsMouse)1738 TEST_F(FPDFFormFillTextFormEmbedderTest, GetSelectedTextFragmentsMouse) {
1739   TypeTextIntoTextField(12, RegularFormBegin());
1740 
1741   // Test selecting first character in forward direction.
1742   SelectTextWithMouse(RegularFormBegin(), RegularFormAtX(106.0));
1743   CheckSelection(L"A");
1744 
1745   // Test selecting entire long string in backwards direction.
1746   SelectAllRegularFormTextWithMouse();
1747   CheckSelection(L"ABCDEFGHIJKL");
1748 
1749   // Test selecting middle section in backwards direction.
1750   SelectTextWithMouse(RegularFormAtX(170.0), RegularFormAtX(125.0));
1751   CheckSelection(L"DEFGHI");
1752 
1753   // Test selecting middle selection in forward direction.
1754   SelectTextWithMouse(RegularFormAtX(125.0), RegularFormAtX(170.0));
1755   CheckSelection(L"DEFGHI");
1756 
1757   // Test selecting last character in backwards direction.
1758   SelectTextWithMouse(RegularFormEnd(), RegularFormAtX(186.0));
1759   CheckSelection(L"L");
1760 }
1761 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,GetSelectedTextEmptyAndBasicNormalComboBox)1762 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
1763        GetSelectedTextEmptyAndBasicNormalComboBox) {
1764   // Test empty selection.
1765   CheckSelection(L"");
1766   CheckFocusedFieldText(L"");
1767 
1768   // Non-editable comboboxes don't allow selection with keyboard.
1769   SelectTextWithMouse(NonEditableFormBegin(), NonEditableFormAtX(142.0));
1770   CheckFocusedFieldText(L"Banana");
1771   CheckSelection(L"Banana");
1772 
1773   // Select other another provided option.
1774   SelectNonEditableFormOption(0);
1775   CheckFocusedFieldText(L"Apple");
1776   CheckSelection(L"Apple");
1777 }
1778 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,GetSelectedTextEmptyAndBasicEditableComboBoxKeyboard)1779 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
1780        GetSelectedTextEmptyAndBasicEditableComboBoxKeyboard) {
1781   // Test empty selection.
1782   CheckSelection(L"");
1783   CheckFocusedFieldText(L"");
1784 
1785   // Test basic selection of text within user editable combobox using keyboard.
1786   TypeTextIntoTextField(3, EditableFormBegin());
1787   CheckFocusedFieldText(L"ABC");
1788   SelectTextWithKeyboard(3, FWL_VKEY_Left, EditableFormAtX(128.0));
1789   CheckSelection(L"ABC");
1790 
1791   // Select a provided option.
1792   SelectEditableFormOption(1);
1793   CheckSelection(L"Bar");
1794   CheckFocusedFieldText(L"Bar");
1795 }
1796 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,GetSelectedTextEmptyAndBasicEditableComboBoxMouse)1797 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
1798        GetSelectedTextEmptyAndBasicEditableComboBoxMouse) {
1799   // Test empty selection.
1800   CheckSelection(L"");
1801 
1802   // Test basic selection of text within user editable combobox using mouse.
1803   TypeTextIntoTextField(3, EditableFormBegin());
1804   SelectTextWithMouse(EditableFormAtX(128.0), EditableFormBegin());
1805   CheckSelection(L"ABC");
1806 
1807   // Select a provided option.
1808   SelectEditableFormOption(2);
1809   CheckFocusedFieldText(L"Qux");
1810   CheckSelection(L"Qux");
1811 }
1812 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,GetSelectedTextFragmentsNormalComboBox)1813 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
1814        GetSelectedTextFragmentsNormalComboBox) {
1815   CheckFocusedFieldText(L"");
1816 
1817   // Test selecting first character in forward direction.
1818   SelectTextWithMouse(NonEditableFormBegin(), NonEditableFormAtX(107.0));
1819   CheckFocusedFieldText(L"Banana");
1820   CheckSelection(L"B");
1821 
1822   // Test selecting entire string in backwards direction.
1823   SelectTextWithMouse(NonEditableFormAtX(142.0), NonEditableFormBegin());
1824   CheckSelection(L"Banana");
1825 
1826   // Test selecting middle section in backwards direction.
1827   SelectTextWithMouse(NonEditableFormAtX(135.0), NonEditableFormAtX(117.0));
1828   CheckSelection(L"nan");
1829 
1830   // Test selecting middle section in forward direction.
1831   SelectTextWithMouse(NonEditableFormAtX(117.0), NonEditableFormAtX(135.0));
1832   CheckSelection(L"nan");
1833 
1834   // Test selecting last character in backwards direction.
1835   SelectTextWithMouse(NonEditableFormAtX(142.0), NonEditableFormAtX(138.0));
1836   CheckSelection(L"a");
1837   CheckFocusedFieldText(L"Banana");
1838 
1839   // Select another option and then reset selection as first three chars.
1840   SelectNonEditableFormOption(2);
1841   CheckFocusedFieldText(L"Cherry");
1842   CheckSelection(L"Cherry");
1843   SelectTextWithMouse(NonEditableFormBegin(), NonEditableFormAtX(122.0));
1844   CheckSelection(L"Che");
1845 }
1846 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,GetSelectedTextFragmentsEditableComboBoxKeyboard)1847 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
1848        GetSelectedTextFragmentsEditableComboBoxKeyboard) {
1849   CheckFocusedFieldText(L"");
1850   TypeTextIntoTextField(10, EditableFormBegin());
1851   CheckFocusedFieldText(L"ABCDEFGHIJ");
1852 
1853   // Test selecting first character in forward direction.
1854   SelectTextWithKeyboard(1, FWL_VKEY_Right, EditableFormBegin());
1855   CheckSelection(L"A");
1856 
1857   // Test selecting entire long string in backwards direction.
1858   SelectTextWithKeyboard(10, FWL_VKEY_Left, EditableFormEnd());
1859   CheckSelection(L"ABCDEFGHIJ");
1860 
1861   // Test selecting middle section in backwards direction.
1862   SelectTextWithKeyboard(5, FWL_VKEY_Left, EditableFormAtX(168.0));
1863   CheckSelection(L"DEFGH");
1864 
1865   // Test selecting middle selection in forward direction.
1866   SelectTextWithKeyboard(5, FWL_VKEY_Right, EditableFormAtX(127.0));
1867   CheckSelection(L"DEFGH");
1868 
1869   // Test selecting last character in backwards direction.
1870   SelectTextWithKeyboard(1, FWL_VKEY_Left, EditableFormEnd());
1871   CheckSelection(L"J");
1872 
1873   // Select a provided option and then reset selection as first two chars.
1874   SelectEditableFormOption(0);
1875   CheckSelection(L"Foo");
1876   SelectTextWithKeyboard(2, FWL_VKEY_Right, EditableFormBegin());
1877   CheckSelection(L"Fo");
1878   CheckFocusedFieldText(L"Foo");
1879 }
1880 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,GetSelectedTextFragmentsEditableComboBoxMouse)1881 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
1882        GetSelectedTextFragmentsEditableComboBoxMouse) {
1883   TypeTextIntoTextField(10, EditableFormBegin());
1884 
1885   // Test selecting first character in forward direction.
1886   SelectTextWithMouse(EditableFormBegin(), EditableFormAtX(107.0));
1887   CheckSelection(L"A");
1888 
1889   // Test selecting entire long string in backwards direction.
1890   SelectAllEditableFormTextWithMouse();
1891   CheckSelection(L"ABCDEFGHIJ");
1892 
1893   // Test selecting middle section in backwards direction.
1894   SelectTextWithMouse(EditableFormAtX(168.0), EditableFormAtX(127.0));
1895   CheckSelection(L"DEFGH");
1896 
1897   // Test selecting middle selection in forward direction.
1898   SelectTextWithMouse(EditableFormAtX(127.0), EditableFormAtX(168.0));
1899   CheckSelection(L"DEFGH");
1900 
1901   // Test selecting last character in backwards direction.
1902   SelectTextWithMouse(EditableFormEnd(), EditableFormAtX(174.0));
1903   CheckSelection(L"J");
1904   CheckFocusedFieldText(L"ABCDEFGHIJ");
1905 }
1906 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,SetSelectionProgrammaticallyNonEditableField)1907 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
1908        SetSelectionProgrammaticallyNonEditableField) {
1909   // Focus on non-editable form field and check that the value is as expected.
1910   // This is the value that is present in the field upon opening, we have not
1911   // changed it by setting focus.
1912   FocusOnNonEditableForm();
1913   CheckFocusedFieldText(L"Banana");
1914 
1915   // Make selections to change the value of the focused annotation
1916   // programmatically.
1917   SetIndexSelectedShouldSucceed(0, true);
1918   CheckFocusedFieldText(L"Apple");
1919 
1920   // Selecting an index that is already selected is success.
1921   SetIndexSelectedShouldSucceed(0, true);
1922   CheckFocusedFieldText(L"Apple");
1923 
1924   SetIndexSelectedShouldSucceed(9, true);
1925   CheckFocusedFieldText(L"Jackfruit");
1926 
1927   // Cannot deselect a combobox field - value unchanged.
1928   SetIndexSelectedShouldFail(9, false);
1929   CheckFocusedFieldText(L"Jackfruit");
1930 
1931   // Cannot select indices that are out of range - value unchanged.
1932   SetIndexSelectedShouldFail(100, true);
1933   SetIndexSelectedShouldFail(-100, true);
1934   CheckFocusedFieldText(L"Jackfruit");
1935 
1936   // Check that above actions are interchangeable with click actions, should be
1937   // able to use a combination of both.
1938   SelectNonEditableFormOption(1);
1939   CheckFocusedFieldText(L"Banana");
1940 }
1941 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,SetSelectionProgrammaticallyEditableField)1942 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
1943        SetSelectionProgrammaticallyEditableField) {
1944   // Focus on editable form field and check that the value is as expected.
1945   // This is the value that is present in the field upon opening, we have not
1946   // changed it by setting focus.
1947   FocusOnEditableForm();
1948   CheckFocusedFieldText(L"");
1949 
1950   // Make selections to change value of the focused annotation
1951   // programmatically.
1952   SetIndexSelectedShouldSucceed(0, true);
1953   CheckFocusedFieldText(L"Foo");
1954 
1955   SetIndexSelectedShouldSucceed(1, true);
1956   CheckFocusedFieldText(L"Bar");
1957 
1958   // Selecting an index that is already selected is success.
1959   SetIndexSelectedShouldSucceed(1, true);
1960   CheckFocusedFieldText(L"Bar");
1961 
1962   // Cannot deselect a combobox field - value unchanged.
1963   SetIndexSelectedShouldFail(0, false);
1964   CheckFocusedFieldText(L"Bar");
1965 
1966   // Cannot select indices that are out of range - value unchanged.
1967   SetIndexSelectedShouldFail(100, true);
1968   SetIndexSelectedShouldFail(-100, true);
1969   CheckFocusedFieldText(L"Bar");
1970 
1971   // Check that above actions are interchangeable with click actions, should be
1972   // able to use a combination of both.
1973   SelectEditableFormOption(0);
1974   CheckFocusedFieldText(L"Foo");
1975 
1976   // Check that above actions are interchangeable with typing actions, should
1977   // be able to use a combination of both. Typing text into a text field after
1978   // selecting indices programmatically should be equivalent to doing so after
1979   // a user selects an index via click on the dropdown.
1980   SetIndexSelectedShouldSucceed(1, true);
1981   CheckFocusedFieldText(L"Bar");
1982   TypeTextIntoTextField(5, EditableFormBegin());
1983   CheckFocusedFieldText(L"ABCDEBar");
1984 }
1985 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,CheckIfIndexSelectedNonEditableField)1986 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
1987        CheckIfIndexSelectedNonEditableField) {
1988   // Non-editable field is set to 'Banana' (index 1) upon opening.
1989   ClickOnFormFieldAtPoint(NonEditableFormBegin());
1990   for (int i = 0; i < 26; i++) {
1991     bool expected = i == 1;
1992     CheckIsIndexSelected(i, expected);
1993   }
1994 
1995   SelectNonEditableFormOption(0);
1996   CheckIsIndexSelected(0, true);
1997   for (int i = 1; i < 26; i++) {
1998     CheckIsIndexSelected(i, false);
1999   }
2000 }
2001 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,CheckIfIndexSelectedEditableField)2002 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2003        CheckIfIndexSelectedEditableField) {
2004   // Editable field has nothing selected upon opening.
2005   ClickOnFormFieldAtPoint(EditableFormBegin());
2006   CheckIsIndexSelected(0, false);
2007   CheckIsIndexSelected(1, false);
2008   CheckIsIndexSelected(2, false);
2009 
2010   SelectEditableFormOption(0);
2011   CheckIsIndexSelected(0, true);
2012   CheckIsIndexSelected(1, false);
2013   CheckIsIndexSelected(2, false);
2014 }
2015 
TEST_F(FPDFFormFillTextFormEmbedderTest,DeleteTextFieldEntireSelection)2016 TEST_F(FPDFFormFillTextFormEmbedderTest, DeleteTextFieldEntireSelection) {
2017   // Select entire contents of text field.
2018   TypeTextIntoTextField(12, RegularFormBegin());
2019   SelectAllRegularFormTextWithMouse();
2020   CheckFocusedFieldText(L"ABCDEFGHIJKL");
2021   CheckSelection(L"ABCDEFGHIJKL");
2022 
2023   // Test deleting current text selection. Select what remains after deletion to
2024   // check that remaining text is as expected.
2025   FORM_ReplaceSelection(form_handle(), page(), nullptr);
2026   CheckFocusedFieldText(L"");
2027 
2028   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
2029   CheckSelection(L"");
2030 }
2031 
TEST_F(FPDFFormFillTextFormEmbedderTest,DeleteTextFieldSelectionMiddle)2032 TEST_F(FPDFFormFillTextFormEmbedderTest, DeleteTextFieldSelectionMiddle) {
2033   // Select middle section of text.
2034   TypeTextIntoTextField(12, RegularFormBegin());
2035   SelectTextWithMouse(RegularFormAtX(170.0), RegularFormAtX(125.0));
2036   CheckFocusedFieldText(L"ABCDEFGHIJKL");
2037   CheckSelection(L"DEFGHI");
2038 
2039   // Test deleting current text selection. Select what remains after deletion to
2040   // check that remaining text is as expected.
2041   FORM_ReplaceSelection(form_handle(), page(), nullptr);
2042   CheckFocusedFieldText(L"ABCJKL");
2043   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
2044   CheckSelection(L"ABCJKL");
2045 }
2046 
TEST_F(FPDFFormFillTextFormEmbedderTest,DeleteTextFieldSelectionLeft)2047 TEST_F(FPDFFormFillTextFormEmbedderTest, DeleteTextFieldSelectionLeft) {
2048   // Select first few characters of text.
2049   TypeTextIntoTextField(12, RegularFormBegin());
2050   SelectTextWithMouse(RegularFormBegin(), RegularFormAtX(132.0));
2051   CheckSelection(L"ABCD");
2052 
2053   // Test deleting current text selection. Select what remains after deletion to
2054   // check that remaining text is as expected.
2055   FORM_ReplaceSelection(form_handle(), page(), nullptr);
2056   CheckFocusedFieldText(L"EFGHIJKL");
2057   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
2058   CheckSelection(L"EFGHIJKL");
2059 }
2060 
TEST_F(FPDFFormFillTextFormEmbedderTest,DeleteTextFieldSelectionRight)2061 TEST_F(FPDFFormFillTextFormEmbedderTest, DeleteTextFieldSelectionRight) {
2062   // Select last few characters of text.
2063   TypeTextIntoTextField(12, RegularFormBegin());
2064   SelectTextWithMouse(RegularFormEnd(), RegularFormAtX(165.0));
2065   CheckSelection(L"IJKL");
2066 
2067   // Test deleting current text selection. Select what remains after deletion to
2068   // check that remaining text is as expected.
2069   FORM_ReplaceSelection(form_handle(), page(), nullptr);
2070   CheckFocusedFieldText(L"ABCDEFGH");
2071   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
2072   CheckSelection(L"ABCDEFGH");
2073 }
2074 
TEST_F(FPDFFormFillTextFormEmbedderTest,DeleteEmptyTextFieldSelection)2075 TEST_F(FPDFFormFillTextFormEmbedderTest, DeleteEmptyTextFieldSelection) {
2076   // Do not select text.
2077   TypeTextIntoTextField(12, RegularFormBegin());
2078   CheckSelection(L"");
2079 
2080   // Test that attempt to delete empty text selection has no effect.
2081   FORM_ReplaceSelection(form_handle(), page(), nullptr);
2082   CheckFocusedFieldText(L"ABCDEFGHIJKL");
2083   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
2084   CheckSelection(L"ABCDEFGHIJKL");
2085 }
2086 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,DeleteEditableComboBoxEntireSelection)2087 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2088        DeleteEditableComboBoxEntireSelection) {
2089   // Select entire contents of user-editable combobox text field.
2090   TypeTextIntoTextField(10, EditableFormBegin());
2091   SelectAllEditableFormTextWithMouse();
2092   CheckSelection(L"ABCDEFGHIJ");
2093 
2094   // Test deleting current text selection. Select what remains after deletion to
2095   // check that remaining text is as expected.
2096   FORM_ReplaceSelection(form_handle(), page(), nullptr);
2097   CheckFocusedFieldText(L"");
2098   SelectAllEditableFormTextWithMouse();
2099   CheckSelection(L"");
2100 }
2101 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,DeleteEditableComboBoxSelectionMiddle)2102 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2103        DeleteEditableComboBoxSelectionMiddle) {
2104   // Select middle section of text.
2105   TypeTextIntoTextField(10, EditableFormBegin());
2106   SelectTextWithMouse(EditableFormAtX(168.0), EditableFormAtX(127.0));
2107   CheckSelection(L"DEFGH");
2108 
2109   // Test deleting current text selection. Select what remains after deletion to
2110   // check that remaining text is as expected.
2111   FORM_ReplaceSelection(form_handle(), page(), nullptr);
2112   CheckFocusedFieldText(L"ABCIJ");
2113   SelectAllEditableFormTextWithMouse();
2114   CheckSelection(L"ABCIJ");
2115 }
2116 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,DeleteEditableComboBoxSelectionLeft)2117 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2118        DeleteEditableComboBoxSelectionLeft) {
2119   // Select first few characters of text.
2120   TypeTextIntoTextField(10, EditableFormBegin());
2121   SelectTextWithMouse(EditableFormBegin(), EditableFormAtX(132.0));
2122   CheckSelection(L"ABCD");
2123 
2124   // Test deleting current text selection. Select what remains after deletion to
2125   // check that remaining text is as expected.
2126   FORM_ReplaceSelection(form_handle(), page(), nullptr);
2127   SelectAllEditableFormTextWithMouse();
2128   CheckSelection(L"EFGHIJ");
2129 }
2130 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,DeleteEditableComboBoxSelectionRight)2131 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2132        DeleteEditableComboBoxSelectionRight) {
2133   // Select last few characters of text.
2134   TypeTextIntoTextField(10, EditableFormBegin());
2135   SelectTextWithMouse(EditableFormEnd(), EditableFormAtX(152.0));
2136   CheckSelection(L"GHIJ");
2137 
2138   // Test deleting current text selection. Select what remains after deletion to
2139   // check that remaining text is as expected.
2140   FORM_ReplaceSelection(form_handle(), page(), nullptr);
2141   SelectAllEditableFormTextWithMouse();
2142   CheckSelection(L"ABCDEF");
2143 }
2144 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,DeleteEmptyEditableComboBoxSelection)2145 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2146        DeleteEmptyEditableComboBoxSelection) {
2147   // Do not select text.
2148   TypeTextIntoTextField(10, EditableFormBegin());
2149   CheckSelection(L"");
2150 
2151   // Test that attempt to delete empty text selection has no effect.
2152   FORM_ReplaceSelection(form_handle(), page(), nullptr);
2153   SelectAllEditableFormTextWithMouse();
2154   CheckSelection(L"ABCDEFGHIJ");
2155 }
2156 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextInEmptyTextField)2157 TEST_F(FPDFFormFillTextFormEmbedderTest, InsertTextInEmptyTextField) {
2158   CheckFocusedFieldText(L"");
2159   ClickOnFormFieldAtPoint(RegularFormBegin());
2160   CheckFocusedFieldText(L"");
2161 
2162   // Test inserting text into empty text field.
2163   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2164   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2165   CheckFocusedFieldText(L"Hello");
2166 
2167   // Select entire contents of text field to check that insertion worked
2168   // as expected.
2169   CheckSelection(L"");
2170   SelectAllRegularFormTextWithMouse();
2171   CheckSelection(L"Hello");
2172 }
2173 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextInPopulatedTextFieldLeft)2174 TEST_F(FPDFFormFillTextFormEmbedderTest, InsertTextInPopulatedTextFieldLeft) {
2175   TypeTextIntoTextField(8, RegularFormBegin());
2176   CheckFocusedFieldText(L"ABCDEFGH");
2177 
2178   // Click on the leftmost part of the text field.
2179   ClickOnFormFieldAtPoint(RegularFormBegin());
2180   CheckFocusedFieldText(L"ABCDEFGH");
2181 
2182   // Test inserting text in front of existing text in text field.
2183   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2184   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2185   CheckFocusedFieldText(L"HelloABCDEFGH");
2186 
2187   // Select entire contents of text field to check that insertion worked
2188   // as expected.
2189   CheckSelection(L"");
2190   SelectAllRegularFormTextWithMouse();
2191   CheckSelection(L"HelloABCDEFGH");
2192 }
2193 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextInPopulatedTextFieldMiddle)2194 TEST_F(FPDFFormFillTextFormEmbedderTest, InsertTextInPopulatedTextFieldMiddle) {
2195   TypeTextIntoTextField(8, RegularFormBegin());
2196 
2197   // Click on the middle of the text field.
2198   ClickOnFormFieldAtPoint(RegularFormAtX(134.0));
2199 
2200   // Test inserting text in the middle of existing text in text field.
2201   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2202   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2203   CheckFocusedFieldText(L"ABCDHelloEFGH");
2204 
2205   // Select entire contents of text field to check that insertion worked
2206   // as expected.
2207   CheckSelection(L"");
2208   SelectAllRegularFormTextWithMouse();
2209   CheckSelection(L"ABCDHelloEFGH");
2210 }
2211 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextInPopulatedTextFieldRight)2212 TEST_F(FPDFFormFillTextFormEmbedderTest, InsertTextInPopulatedTextFieldRight) {
2213   TypeTextIntoTextField(8, RegularFormBegin());
2214 
2215   // Click on the rightmost part of the text field.
2216   ClickOnFormFieldAtPoint(RegularFormAtX(166.0));
2217 
2218   // Test inserting text behind existing text in text field.
2219   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2220   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2221   CheckFocusedFieldText(L"ABCDEFGHHello");
2222 
2223   // Select entire contents of text field to check that insertion worked
2224   // as expected.
2225   CheckSelection(L"");
2226   SelectAllRegularFormTextWithMouse();
2227   CheckSelection(L"ABCDEFGHHello");
2228 }
2229 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextAndReplaceSelectionInPopulatedTextFieldWhole)2230 TEST_F(FPDFFormFillTextFormEmbedderTest,
2231        InsertTextAndReplaceSelectionInPopulatedTextFieldWhole) {
2232   TypeTextIntoTextField(12, RegularFormBegin());
2233 
2234   // Select entire string in text field.
2235   CheckSelection(L"");
2236   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
2237   CheckSelection(L"ABCDEFGHIJKL");
2238 
2239   // Test replacing text selection with text to be inserted.
2240   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2241   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2242   CheckFocusedFieldText(L"Hello");
2243 
2244   // Select entire contents of text field to check that insertion worked
2245   // as expected.
2246   CheckSelection(L"");
2247   SelectAllRegularFormTextWithMouse();
2248   CheckSelection(L"Hello");
2249 }
2250 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextAndReplaceSelectionInPopulatedTextFieldLeft)2251 TEST_F(FPDFFormFillTextFormEmbedderTest,
2252        InsertTextAndReplaceSelectionInPopulatedTextFieldLeft) {
2253   TypeTextIntoTextField(12, RegularFormBegin());
2254 
2255   // Select left portion of string in text field.
2256   CheckSelection(L"");
2257   SelectTextWithKeyboard(6, FWL_VKEY_Left, RegularFormAtX(148.0));
2258   CheckSelection(L"ABCDEF");
2259 
2260   // Test replacing text selection with text to be inserted.
2261   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2262   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2263   CheckFocusedFieldText(L"HelloGHIJKL");
2264 
2265   // Select entire contents of text field to check that insertion worked
2266   // as expected.
2267   CheckSelection(L"");
2268   SelectAllRegularFormTextWithMouse();
2269   CheckSelection(L"HelloGHIJKL");
2270 }
2271 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextAndReplaceSelectionInPopulatedTextFieldMiddle)2272 TEST_F(FPDFFormFillTextFormEmbedderTest,
2273        InsertTextAndReplaceSelectionInPopulatedTextFieldMiddle) {
2274   TypeTextIntoTextField(12, RegularFormBegin());
2275 
2276   // Select middle portion of string in text field.
2277   CheckSelection(L"");
2278   SelectTextWithKeyboard(6, FWL_VKEY_Left, RegularFormAtX(171.0));
2279   CheckSelection(L"DEFGHI");
2280 
2281   // Test replacing text selection with text to be inserted.
2282   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2283   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2284 
2285   // Select entire contents of text field to check that insertion worked
2286   // as expected.
2287   CheckSelection(L"");
2288   SelectAllRegularFormTextWithMouse();
2289   CheckSelection(L"ABCHelloJKL");
2290 }
2291 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextAndReplaceSelectionInPopulatedTextFieldRight)2292 TEST_F(FPDFFormFillTextFormEmbedderTest,
2293        InsertTextAndReplaceSelectionInPopulatedTextFieldRight) {
2294   TypeTextIntoTextField(12, RegularFormBegin());
2295 
2296   // Select right portion of string in text field.
2297   CheckSelection(L"");
2298   SelectTextWithKeyboard(6, FWL_VKEY_Left, RegularFormEnd());
2299   CheckSelection(L"GHIJKL");
2300 
2301   // Test replacing text selection with text to be inserted.
2302   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2303   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2304 
2305   // Select entire contents of text field to check that insertion worked
2306   // as expected.
2307   CheckSelection(L"");
2308   SelectAllRegularFormTextWithMouse();
2309   CheckSelection(L"ABCDEFHello");
2310 }
2311 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,InsertTextInEmptyEditableComboBox)2312 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2313        InsertTextInEmptyEditableComboBox) {
2314   ClickOnFormFieldAtPoint(EditableFormBegin());
2315   CheckFocusedFieldText(L"");
2316 
2317   // Test inserting text into empty user-editable combobox.
2318   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2319   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2320   CheckFocusedFieldText(L"Hello");
2321 
2322   // Select entire contents of user-editable combobox text field to check that
2323   // insertion worked as expected.
2324   CheckSelection(L"");
2325   SelectAllEditableFormTextWithMouse();
2326   CheckSelection(L"Hello");
2327 }
2328 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,InsertTextInPopulatedEditableComboBoxLeft)2329 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2330        InsertTextInPopulatedEditableComboBoxLeft) {
2331   TypeTextIntoTextField(6, EditableFormBegin());
2332 
2333   // Click on the leftmost part of the user-editable combobox.
2334   ClickOnFormFieldAtPoint(EditableFormBegin());
2335 
2336   // Test inserting text in front of existing text in user-editable combobox.
2337   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2338   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2339 
2340   // Select entire contents of user-editable combobox text field to check that
2341   // insertion worked as expected.
2342   CheckSelection(L"");
2343   SelectAllEditableFormTextWithMouse();
2344   CheckSelection(L"HelloABCDEF");
2345 }
2346 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,InsertTextInPopulatedEditableComboBoxMiddle)2347 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2348        InsertTextInPopulatedEditableComboBoxMiddle) {
2349   TypeTextIntoTextField(6, EditableFormBegin());
2350 
2351   // Click on the middle of the user-editable combobox.
2352   ClickOnFormFieldAtPoint(EditableFormAtX(126.0));
2353 
2354   // Test inserting text in the middle of existing text in user-editable
2355   // combobox.
2356   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2357   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2358 
2359   // Select entire contents of user-editable combobox text field to check that
2360   // insertion worked as expected.
2361   CheckSelection(L"");
2362   SelectAllEditableFormTextWithMouse();
2363   CheckSelection(L"ABCHelloDEF");
2364 }
2365 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,InsertTextInPopulatedEditableComboBoxRight)2366 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2367        InsertTextInPopulatedEditableComboBoxRight) {
2368   TypeTextIntoTextField(6, EditableFormBegin());
2369 
2370   // Click on the rightmost part of the user-editable combobox.
2371   ClickOnFormFieldAtPoint(EditableFormEnd());
2372 
2373   // Test inserting text behind existing text in user-editable combobox.
2374   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2375   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2376 
2377   // Select entire contents of user-editable combobox text field to check that
2378   // insertion worked as expected.
2379   CheckSelection(L"");
2380   SelectAllEditableFormTextWithMouse();
2381   CheckSelection(L"ABCDEFHello");
2382 }
2383 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,InsertTextAndReplaceSelectionInPopulatedEditableComboBoxWhole)2384 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2385        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxWhole) {
2386   TypeTextIntoTextField(10, EditableFormBegin());
2387 
2388   // Select entire string in user-editable combobox.
2389   CheckSelection(L"");
2390   SelectTextWithKeyboard(10, FWL_VKEY_Left, EditableFormEnd());
2391   CheckSelection(L"ABCDEFGHIJ");
2392 
2393   // Test replacing text selection with text to be inserted.
2394   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2395   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2396 
2397   // Select entire contents of user-editable combobox text field to check that
2398   // insertion worked as expected.
2399   CheckSelection(L"");
2400   SelectAllEditableFormTextWithMouse();
2401   CheckSelection(L"Hello");
2402 }
2403 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,InsertTextAndReplaceSelectionInPopulatedEditableComboBoxLeft)2404 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2405        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxLeft) {
2406   TypeTextIntoTextField(10, EditableFormBegin());
2407 
2408   // Select left portion of string in user-editable combobox.
2409   CheckSelection(L"");
2410   SelectTextWithKeyboard(5, FWL_VKEY_Left, EditableFormAtX(142.0));
2411   CheckSelection(L"ABCDE");
2412 
2413   // Test replacing text selection with text to be inserted.
2414   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2415   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2416 
2417   // Select entire contents of user-editable combobox text field to check that
2418   // insertion worked as expected.
2419   CheckSelection(L"");
2420   SelectAllEditableFormTextWithMouse();
2421   CheckSelection(L"HelloFGHIJ");
2422 }
2423 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,InsertTextAndReplaceSelectionInPopulatedEditableComboBoxMiddle)2424 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2425        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxMiddle) {
2426   TypeTextIntoTextField(10, EditableFormBegin());
2427 
2428   // Select middle portion of string in user-editable combobox.
2429   CheckSelection(L"");
2430   SelectTextWithKeyboard(5, FWL_VKEY_Left, EditableFormAtX(167.0));
2431   CheckSelection(L"DEFGH");
2432 
2433   // Test replacing text selection with text to be inserted.
2434   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2435   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2436 
2437   // Select entire contents of user-editable combobox text field to check that
2438   // insertion worked as expected.
2439   CheckSelection(L"");
2440   SelectAllEditableFormTextWithMouse();
2441   CheckSelection(L"ABCHelloIJ");
2442 }
2443 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,InsertTextAndReplaceSelectionInPopulatedEditableComboBoxRight)2444 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2445        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxRight) {
2446   TypeTextIntoTextField(10, EditableFormBegin());
2447 
2448   // Select right portion of string in user-editable combobox.
2449   CheckSelection(L"");
2450   SelectTextWithKeyboard(5, FWL_VKEY_Left, EditableFormEnd());
2451   CheckSelection(L"FGHIJ");
2452 
2453   // Test replacing text selection with text to be inserted.
2454   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello");
2455   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2456 
2457   // Select entire contents of user-editable combobox text field to check that
2458   // insertion worked as expected.
2459   CheckSelection(L"");
2460   SelectAllEditableFormTextWithMouse();
2461   CheckSelection(L"ABCDEHello");
2462 }
2463 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,CheckIfEnterAndSpaceKeyAreHandled)2464 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2465        CheckIfEnterAndSpaceKeyAreHandled) {
2466   // Non-editable field is set to 'Banana' (index 1) upon opening.
2467   ClickOnFormFieldAtPoint(NonEditableFormBegin());
2468   CheckIsIndexSelected(0, false);
2469   CheckIsIndexSelected(1, true);
2470 
2471   // Verify that the Return character is handled.
2472   EXPECT_TRUE(FORM_OnChar(form_handle(), page(), pdfium::ascii::kReturn, 0));
2473 
2474   // Change the selection in the combo-box using the arrow down key.
2475   EXPECT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Down, 0));
2476   CheckIsIndexSelected(1, false);
2477   CheckIsIndexSelected(2, true);
2478 
2479   // Tab to the next control.
2480   EXPECT_TRUE(FORM_OnChar(form_handle(), page(), pdfium::ascii::kTab, 0));
2481 
2482   // Shift-tab to the previous control.
2483   EXPECT_TRUE(FORM_OnChar(form_handle(), page(), pdfium::ascii::kTab,
2484                           FWL_EVENTFLAG_ShiftKey));
2485 
2486   // Verify that the selection is unchanged.
2487   CheckIsIndexSelected(2, true);
2488 
2489   // Verify that the Space character is handled.
2490   EXPECT_TRUE(FORM_OnChar(form_handle(), page(), pdfium::ascii::kSpace, 0));
2491 
2492   // Change the selection in the combo-box using the arrow down key.
2493   EXPECT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Down, 0));
2494   CheckIsIndexSelected(3, true);
2495 
2496   // Tab to the next control.
2497   EXPECT_TRUE(FORM_OnChar(form_handle(), page(), pdfium::ascii::kTab, 0));
2498 
2499   // Shift-tab to the previous control.
2500   EXPECT_TRUE(FORM_OnChar(form_handle(), page(), pdfium::ascii::kTab,
2501                           FWL_EVENTFLAG_ShiftKey));
2502 
2503   // Verify that the selection is unchanged.
2504   CheckIsIndexSelected(3, true);
2505 }
2506 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,CheckIfEnterAndSpaceKeyAreHandledOnEditableFormField)2507 TEST_F(FPDFFormFillComboBoxFormEmbedderTest,
2508        CheckIfEnterAndSpaceKeyAreHandledOnEditableFormField) {
2509   // Non-editable field is set to 'Banana' (index 1) upon opening.
2510   ClickOnFormFieldAtPoint(EditableFormBegin());
2511   CheckIsIndexSelected(0, false);
2512   CheckIsIndexSelected(1, false);
2513 
2514   // Verify that the Return character is handled.
2515   EXPECT_TRUE(FORM_OnChar(form_handle(), page(), pdfium::ascii::kReturn, 0));
2516 
2517   // Change the selection in the combo-box using the arrow down key.
2518   EXPECT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Down, 0));
2519   CheckIsIndexSelected(0, true);
2520   CheckIsIndexSelected(1, false);
2521 
2522   // Tab to the next control.
2523   EXPECT_TRUE(FORM_OnChar(form_handle(), page(), pdfium::ascii::kTab, 0));
2524 
2525   // Shift-tab to the previous control.
2526   EXPECT_TRUE(FORM_OnChar(form_handle(), page(), pdfium::ascii::kTab,
2527                           FWL_EVENTFLAG_ShiftKey));
2528 
2529   // Verify that the selection is unchanged.
2530   CheckIsIndexSelected(0, true);
2531 
2532   // Verify that the Space character is handled.
2533   EXPECT_TRUE(FORM_OnChar(form_handle(), page(), pdfium::ascii::kSpace, 0));
2534 
2535   CheckFocusedFieldText(L" ");
2536   CheckIsIndexSelected(0, false);
2537 }
2538 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextInEmptyCharLimitTextFieldOverflow)2539 TEST_F(FPDFFormFillTextFormEmbedderTest,
2540        InsertTextInEmptyCharLimitTextFieldOverflow) {
2541   // Click on the textfield.
2542   CheckFocusedFieldText(L"");
2543   ClickOnFormFieldAtPoint(CharLimitFormEnd());
2544   CheckFocusedFieldText(L"Elephant");
2545 
2546   // Delete pre-filled contents of text field with char limit.
2547   CheckSelection(L"");
2548   SelectAllCharLimitFormTextWithMouse();
2549   CheckSelection(L"Elephant");
2550   FORM_ReplaceSelection(form_handle(), page(), nullptr);
2551   CheckFocusedFieldText(L"");
2552 
2553   // Test inserting text into now empty text field so text to be inserted
2554   // exceeds the char limit and is cut off.
2555   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hippopotamus");
2556   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2557   CheckFocusedFieldText(L"Hippopotam");
2558 
2559   // Select entire contents of text field to check that insertion worked
2560   // as expected.
2561   CheckSelection(L"");
2562   SelectAllCharLimitFormTextWithMouse();
2563   CheckSelection(L"Hippopotam");
2564 }
2565 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextInEmptyCharLimitTextFieldFit)2566 TEST_F(FPDFFormFillTextFormEmbedderTest,
2567        InsertTextInEmptyCharLimitTextFieldFit) {
2568   // Click on the textfield.
2569   ClickOnFormFieldAtPoint(CharLimitFormEnd());
2570   CheckFocusedFieldText(L"Elephant");
2571 
2572   // Delete pre-filled contents of text field with char limit.
2573   CheckSelection(L"");
2574   SelectAllCharLimitFormTextWithMouse();
2575   CheckSelection(L"Elephant");
2576   FORM_ReplaceSelection(form_handle(), page(), nullptr);
2577 
2578   // Test inserting text into now empty text field so text to be inserted
2579   // exceeds the char limit and is cut off.
2580   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Zebra");
2581   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2582   CheckFocusedFieldText(L"Zebra");
2583 
2584   // Select entire contents of text field to check that insertion worked
2585   // as expected.
2586   CheckSelection(L"");
2587   SelectAllCharLimitFormTextWithMouse();
2588   CheckSelection(L"Zebra");
2589 }
2590 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextInPopulatedCharLimitTextFieldLeft)2591 TEST_F(FPDFFormFillTextFormEmbedderTest,
2592        InsertTextInPopulatedCharLimitTextFieldLeft) {
2593   // Click on the leftmost part of the text field.
2594   ClickOnFormFieldAtPoint(CharLimitFormBegin());
2595 
2596   // Test inserting text in front of existing text in text field.
2597   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hippopotamus");
2598   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2599 
2600   // Select entire contents of text field to check that insertion worked
2601   // as expected.
2602   CheckSelection(L"");
2603   SelectAllCharLimitFormTextWithMouse();
2604   CheckSelection(L"HiElephant");
2605 }
2606 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextInPopulatedCharLimitTextFieldMiddle)2607 TEST_F(FPDFFormFillTextFormEmbedderTest,
2608        InsertTextInPopulatedCharLimitTextFieldMiddle) {
2609   CheckFocusedFieldText(L"");
2610   TypeTextIntoTextField(8, RegularFormBegin());
2611   CheckFocusedFieldText(L"ABCDEFGH");
2612 
2613   // Click on the middle of the text field.
2614   ClickOnFormFieldAtPoint(CharLimitFormAtX(134.0));
2615   CheckFocusedFieldText(L"Elephant");
2616 
2617   // Test inserting text in the middle of existing text in text field.
2618   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hippopotamus");
2619   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2620   CheckFocusedFieldText(L"ElephHiant");
2621 
2622   // Select entire contents of text field to check that insertion worked
2623   // as expected.
2624   CheckSelection(L"");
2625   SelectAllCharLimitFormTextWithMouse();
2626   CheckSelection(L"ElephHiant");
2627 }
2628 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextInPopulatedCharLimitTextFieldRight)2629 TEST_F(FPDFFormFillTextFormEmbedderTest,
2630        InsertTextInPopulatedCharLimitTextFieldRight) {
2631   TypeTextIntoTextField(8, RegularFormBegin());
2632 
2633   // Click on the rightmost part of the text field.
2634   ClickOnFormFieldAtPoint(CharLimitFormAtX(166.0));
2635 
2636   // Test inserting text behind existing text in text field.
2637   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hippopotamus");
2638   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2639 
2640   // Select entire contents of text field to check that insertion worked
2641   // as expected.
2642   CheckSelection(L"");
2643   SelectAllCharLimitFormTextWithMouse();
2644   CheckSelection(L"ElephantHi");
2645 }
2646 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldWhole)2647 TEST_F(FPDFFormFillTextFormEmbedderTest,
2648        InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldWhole) {
2649   TypeTextIntoTextField(12, RegularFormBegin());
2650 
2651   // Select entire string in text field.
2652   CheckSelection(L"");
2653   SelectTextWithKeyboard(12, FWL_VKEY_Left, CharLimitFormEnd());
2654   CheckSelection(L"Elephant");
2655 
2656   // Test replacing text selection with text to be inserted.
2657   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hippopotamus");
2658   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2659 
2660   // Select entire contents of text field to check that insertion worked
2661   // as expected.
2662   CheckSelection(L"");
2663   SelectAllCharLimitFormTextWithMouse();
2664   CheckSelection(L"Hippopotam");
2665 }
2666 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldLeft)2667 TEST_F(FPDFFormFillTextFormEmbedderTest,
2668        InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldLeft) {
2669   TypeTextIntoTextField(12, RegularFormBegin());
2670 
2671   // Select left portion of string in text field.
2672   CheckSelection(L"");
2673   SelectTextWithKeyboard(4, FWL_VKEY_Left, CharLimitFormAtX(122.0));
2674   CheckSelection(L"Elep");
2675 
2676   // Test replacing text selection with text to be inserted.
2677   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hippopotamus");
2678   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2679 
2680   // Select entire contents of text field to check that insertion worked
2681   // as expected.
2682   CheckSelection(L"");
2683   SelectAllCharLimitFormTextWithMouse();
2684   CheckSelection(L"Hippophant");
2685 }
2686 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldMiddle)2687 TEST_F(FPDFFormFillTextFormEmbedderTest,
2688        InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldMiddle) {
2689   TypeTextIntoTextField(12, RegularFormBegin());
2690 
2691   // Select middle portion of string in text field.
2692   CheckSelection(L"");
2693   SelectTextWithKeyboard(4, FWL_VKEY_Left, CharLimitFormAtX(136.0));
2694   CheckSelection(L"epha");
2695 
2696   // Test replacing text selection with text to be inserted.
2697   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hippopotamus");
2698   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2699 
2700   // Select entire contents of text field to check that insertion worked
2701   // as expected.
2702   CheckSelection(L"");
2703   SelectAllCharLimitFormTextWithMouse();
2704   CheckSelection(L"ElHippopnt");
2705 }
2706 
TEST_F(FPDFFormFillTextFormEmbedderTest,InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldRight)2707 TEST_F(FPDFFormFillTextFormEmbedderTest,
2708        InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldRight) {
2709   TypeTextIntoTextField(12, RegularFormBegin());
2710 
2711   // Select right portion of string in text field.
2712   CheckSelection(L"");
2713   SelectTextWithKeyboard(4, FWL_VKEY_Left, CharLimitFormAtX(152.0));
2714   CheckSelection(L"hant");
2715 
2716   // Test replacing text selection with text to be inserted.
2717   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hippopotamus");
2718   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2719 
2720   // Select entire contents of text field to check that insertion worked
2721   // as expected.
2722   CheckSelection(L"");
2723   SelectAllCharLimitFormTextWithMouse();
2724   CheckSelection(L"ElepHippop");
2725 }
2726 
TEST_F(FPDFFormFillTextFormEmbedderTest,DoubleClickInTextField)2727 TEST_F(FPDFFormFillTextFormEmbedderTest, DoubleClickInTextField) {
2728   CheckFocusedFieldText(L"");
2729   ClickOnFormFieldAtPoint(RegularFormBegin());
2730   CheckFocusedFieldText(L"");
2731 
2732   // Test inserting text into empty text field.
2733   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"Hello World");
2734   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
2735   CheckFocusedFieldText(L"Hello World");
2736 
2737   // Make sure double clicking selects the entire line.
2738   CheckSelection(L"");
2739   DoubleClickOnFormFieldAtPoint(RegularFormBegin());
2740   CheckSelection(L"Hello World");
2741 }
2742 
TEST_F(FPDFFormFillTextFormEmbedderTest,FocusAnnotationUpdateToEmbedder)2743 TEST_F(FPDFFormFillTextFormEmbedderTest, FocusAnnotationUpdateToEmbedder) {
2744   testing::NiceMock<EmbedderTestMockDelegate> mock;
2745   SetDelegate(&mock);
2746   CheckFocusedFieldText(L"");
2747 
2748 #ifdef PDF_ENABLE_XFA
2749   EXPECT_CALL(mock, OnFocusChange(_, _, 0)).Times(1);
2750 #else   // PDF_ENABLE_XFA
2751   EXPECT_CALL(mock, OnFocusChange(_, _, 0)).Times(0);
2752 #endif  // PDF_ENABLE_XFA
2753 
2754   ClickOnFormFieldAtPoint(RegularFormBegin());
2755 }
2756 
TEST_F(FPDFFormFillTextFormEmbedderTestVersion2,FocusAnnotationUpdateToEmbedder)2757 TEST_F(FPDFFormFillTextFormEmbedderTestVersion2,
2758        FocusAnnotationUpdateToEmbedder) {
2759   testing::NiceMock<EmbedderTestMockDelegate> mock;
2760   SetDelegate(&mock);
2761   CheckFocusedFieldText(L"");
2762 
2763   EXPECT_CALL(mock, OnFocusChange(_, _, 0)).Times(1);
2764   ClickOnFormFieldAtPoint(RegularFormBegin());
2765 }
2766 
TEST_F(FPDFFormFillTextFormEmbedderTest,FocusChanges)2767 TEST_F(FPDFFormFillTextFormEmbedderTest, FocusChanges) {
2768   static const CFX_PointF kNonFormPoint(1, 1);
2769   CheckFocusedFieldText(L"");
2770   ClickOnFormFieldAtPoint(CharLimitFormEnd());
2771   CheckFocusedFieldText(L"Elephant");
2772   ClickOnFormFieldAtPoint(RegularFormBegin());
2773   CheckFocusedFieldText(L"");
2774   TypeTextIntoTextField(3, CharLimitFormBegin());
2775   CheckFocusedFieldText(L"ABElephant");
2776   TypeTextIntoTextField(5, RegularFormBegin());
2777   CheckFocusedFieldText(L"ABCDE");
2778   ClickOnFormFieldAtPoint(CharLimitFormEnd());
2779   CheckFocusedFieldText(L"ABElephant");
2780   ClickOnFormFieldAtPoint(kNonFormPoint);
2781   CheckFocusedFieldText(L"");
2782   ClickOnFormFieldAtPoint(kNonFormPoint);
2783   CheckFocusedFieldText(L"");
2784   ClickOnFormFieldAtPoint(CharLimitFormBegin());
2785   CheckFocusedFieldText(L"ABElephant");
2786   ClickOnFormFieldAtPoint(CharLimitFormEnd());
2787   CheckFocusedFieldText(L"ABElephant");
2788   ClickOnFormFieldAtPoint(RegularFormEnd());
2789   CheckFocusedFieldText(L"ABCDE");
2790   ClickOnFormFieldAtPoint(RegularFormBegin());
2791   CheckFocusedFieldText(L"ABCDE");
2792   ClickOnFormFieldAtPoint(RegularFormBegin());
2793   CheckFocusedFieldText(L"ABCDE");
2794   ClickOnFormFieldAtPoint(CharLimitFormBegin());
2795   CheckFocusedFieldText(L"ABElephant");
2796   FORM_ForceToKillFocus(form_handle());
2797   CheckFocusedFieldText(L"");
2798 }
2799 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,FocusChanges)2800 TEST_F(FPDFFormFillComboBoxFormEmbedderTest, FocusChanges) {
2801   static const CFX_PointF kNonFormPoint(1, 1);
2802   CheckFocusedFieldText(L"");
2803   ClickOnFormFieldAtPoint(NonEditableFormBegin());
2804   CheckFocusedFieldText(L"Banana");
2805   ClickOnFormFieldAtPoint(EditableFormBegin());
2806   CheckFocusedFieldText(L"");
2807   ClickOnFormFieldAtPoint(NonEditableFormEnd());
2808   CheckFocusedFieldText(L"Banana");
2809   ClickOnFormFieldAtPoint(NonEditableFormBegin());
2810   CheckFocusedFieldText(L"Banana");
2811   FORM_ForceToKillFocus(form_handle());
2812   CheckFocusedFieldText(L"");
2813   ClickOnFormFieldAtPoint(EditableFormBegin());
2814   CheckFocusedFieldText(L"");
2815   TypeTextIntoTextField(3, EditableFormBegin());
2816   CheckFocusedFieldText(L"ABC");
2817   ClickOnFormFieldAtPoint(kNonFormPoint);
2818   CheckFocusedFieldText(L"");
2819   TypeTextIntoTextField(3, EditableFormEnd());
2820   CheckFocusedFieldText(L"ABCABC");
2821   ClickOnFormFieldAtPoint(kNonFormPoint);
2822   CheckFocusedFieldText(L"");
2823   ClickOnFormFieldAtPoint(EditableFormDropDown());
2824   CheckFocusedFieldText(L"ABCABC");
2825   FORM_ForceToKillFocus(form_handle());
2826   CheckFocusedFieldText(L"");
2827   ClickOnFormFieldAtPoint(NonEditableFormDropDown());
2828   CheckFocusedFieldText(L"Banana");
2829   ClickOnFormFieldAtPoint(kNonFormPoint);
2830   CheckFocusedFieldText(L"");
2831   ClickOnFormFieldAtPoint(NonEditableFormEnd());
2832   CheckFocusedFieldText(L"Banana");
2833 
2834   // Typing into non-editable field results in selecting a different option.
2835   TypeTextIntoTextField(1, NonEditableFormEnd());
2836   CheckFocusedFieldText(L"Apple");
2837   TypeTextIntoTextField(3, NonEditableFormEnd());
2838   CheckFocusedFieldText(L"Cherry");
2839   TypeTextIntoTextField(2, NonEditableFormEnd());
2840   CheckFocusedFieldText(L"Banana");
2841 
2842   SelectEditableFormOption(0);
2843   CheckFocusedFieldText(L"Foo");
2844   SelectEditableFormOption(1);
2845   CheckFocusedFieldText(L"Bar");
2846   SelectEditableFormOption(2);
2847   CheckFocusedFieldText(L"Qux");
2848   SelectNonEditableFormOption(1);
2849   CheckFocusedFieldText(L"Banana");
2850   SelectNonEditableFormOption(0);
2851   CheckFocusedFieldText(L"Apple");
2852   SelectNonEditableFormOption(2);
2853   CheckFocusedFieldText(L"Cherry");
2854 
2855   // Typing into an editable field changes the text in the option.
2856   SelectEditableFormOption(0);
2857   CheckFocusedFieldText(L"Foo");
2858   TypeTextIntoTextField(5, EditableFormBegin());
2859   CheckFocusedFieldText(L"ABCDEFoo");
2860   SelectEditableFormOption(2);
2861   CheckFocusedFieldText(L"Qux");
2862   TypeTextIntoTextField(2, EditableFormEnd());
2863   CheckFocusedFieldText(L"QuxAB");
2864 
2865   // But a previously edited option is reset when selected again.
2866   SelectEditableFormOption(0);
2867   CheckFocusedFieldText(L"Foo");
2868   TypeTextIntoTextField(1, EditableFormBegin());
2869   CheckFocusedFieldText(L"AFoo");
2870   SelectEditableFormOption(0);
2871   CheckFocusedFieldText(L"Foo");
2872 }
2873 
TEST_F(FPDFFormFillTextFormEmbedderTest,UndoRedo)2874 TEST_F(FPDFFormFillTextFormEmbedderTest, UndoRedo) {
2875   ClickOnFormFieldAtPoint(RegularFormBegin());
2876   CheckFocusedFieldText(L"");
2877   CheckCanUndo(false);
2878   CheckCanRedo(false);
2879 
2880   TypeTextIntoTextField(5, RegularFormBegin());
2881   CheckFocusedFieldText(L"ABCDE");
2882   CheckCanUndo(true);
2883   CheckCanRedo(false);
2884 
2885   PerformUndo();
2886   CheckFocusedFieldText(L"ABCD");
2887   CheckCanUndo(true);
2888   CheckCanRedo(true);
2889   PerformUndo();
2890   CheckFocusedFieldText(L"ABC");
2891   CheckCanUndo(true);
2892   CheckCanRedo(true);
2893 
2894   PerformRedo();
2895   CheckFocusedFieldText(L"ABCD");
2896   CheckCanUndo(true);
2897   CheckCanRedo(true);
2898   PerformRedo();
2899   CheckFocusedFieldText(L"ABCDE");
2900   CheckCanUndo(true);
2901   CheckCanRedo(false);
2902 }
2903 
2904 // This action only applies to Listboxes and Comboboxes so should fail
2905 // gracefully for Textboxes by returning false to all operations.
TEST_F(FPDFFormFillTextFormEmbedderTest,SetIndexSelectedShouldFailGracefully)2906 TEST_F(FPDFFormFillTextFormEmbedderTest, SetIndexSelectedShouldFailGracefully) {
2907   // set focus and read text to confirm we have it
2908   ClickOnFormFieldAtPoint(CharLimitFormEnd());
2909   CheckFocusedFieldText(L"Elephant");
2910 
2911   SetIndexSelectedShouldFail(0, true);
2912   SetIndexSelectedShouldFail(0, false);
2913   SetIndexSelectedShouldFail(1, true);
2914   SetIndexSelectedShouldFail(1, false);
2915   SetIndexSelectedShouldFail(-1, true);
2916   SetIndexSelectedShouldFail(-1, false);
2917 }
2918 
2919 // This action only applies to Listboxes and Comboboxes so should fail
2920 // gracefully for Textboxes by returning false to all operations.
TEST_F(FPDFFormFillTextFormEmbedderTest,IsIndexSelectedShouldFailGracefully)2921 TEST_F(FPDFFormFillTextFormEmbedderTest, IsIndexSelectedShouldFailGracefully) {
2922   // set focus and read text to confirm we have it
2923   ClickOnFormFieldAtPoint(CharLimitFormEnd());
2924   CheckFocusedFieldText(L"Elephant");
2925 
2926   CheckIsIndexSelected(0, false);
2927   CheckIsIndexSelected(1, false);
2928   CheckIsIndexSelected(-1, false);
2929 }
2930 
TEST_F(FPDFFormFillComboBoxFormEmbedderTest,UndoRedo)2931 TEST_F(FPDFFormFillComboBoxFormEmbedderTest, UndoRedo) {
2932   ClickOnFormFieldAtPoint(NonEditableFormBegin());
2933   CheckFocusedFieldText(L"Banana");
2934   CheckCanUndo(false);
2935   CheckCanRedo(false);
2936 
2937   ClickOnFormFieldAtPoint(EditableFormBegin());
2938   CheckFocusedFieldText(L"");
2939   CheckCanUndo(false);
2940   CheckCanRedo(false);
2941 
2942   TypeTextIntoTextField(3, EditableFormBegin());
2943   CheckFocusedFieldText(L"ABC");
2944   CheckCanUndo(true);
2945   CheckCanRedo(false);
2946 
2947   PerformUndo();
2948   CheckFocusedFieldText(L"AB");
2949   CheckCanUndo(true);
2950   CheckCanRedo(true);
2951   PerformUndo();
2952   CheckFocusedFieldText(L"A");
2953   CheckCanUndo(true);
2954   CheckCanRedo(true);
2955   PerformUndo();
2956   CheckFocusedFieldText(L"");
2957   CheckCanUndo(false);
2958   CheckCanRedo(true);
2959 
2960   PerformRedo();
2961   CheckFocusedFieldText(L"A");
2962   CheckCanUndo(true);
2963   CheckCanRedo(true);
2964 }
2965 
TEST_F(FPDFFormFillListBoxFormEmbedderTest,CheckIfIndexSelectedSingleSelectField)2966 TEST_F(FPDFFormFillListBoxFormEmbedderTest,
2967        CheckIfIndexSelectedSingleSelectField) {
2968   // Nothing is selected in single select field upon opening.
2969   FocusOnSingleSelectForm();
2970   CheckIsIndexSelected(0, false);
2971   CheckIsIndexSelected(1, false);
2972   CheckIsIndexSelected(2, false);
2973 
2974   ClickOnSingleSelectFormOption(1);
2975   CheckIsIndexSelected(0, false);
2976   CheckIsIndexSelected(1, true);
2977   CheckIsIndexSelected(2, false);
2978 }
2979 
TEST_F(FPDFFormFillListBoxFormEmbedderTest,CheckIfIndexSelectedMultiSelectField)2980 TEST_F(FPDFFormFillListBoxFormEmbedderTest,
2981        CheckIfIndexSelectedMultiSelectField) {
2982   // Multiselect field set to 'Banana' (index 1) upon opening.
2983   FocusOnMultiSelectForm();
2984   for (int i = 0; i < 26; i++) {
2985     bool expected = i == 1;
2986     CheckIsIndexSelected(i, expected);
2987   }
2988 
2989   // TODO(bug_1377): Behavior should be changed to the one described below.
2990   // Multiselect field set to 'Cherry' (index 2), which is index 1 among the
2991   // visible form options because the listbox is scrolled down to have 'Banana'
2992   // (index 1) at the top.
2993   ClickOnMultiSelectFormOption(1);
2994   for (int i = 0; i < 26; i++) {
2995     bool expected = i == 1;
2996     CheckIsIndexSelected(i, expected);
2997   }
2998 }
2999 
TEST_F(FPDFFormFillListBoxFormEmbedderTest,SetSelectionProgrammaticallySingleSelectField)3000 TEST_F(FPDFFormFillListBoxFormEmbedderTest,
3001        SetSelectionProgrammaticallySingleSelectField) {
3002   // Nothing is selected in single select field upon opening.
3003   FocusOnSingleSelectForm();
3004   CheckFocusedFieldText(L"");
3005   CheckIsIndexSelected(0, false);
3006   CheckIsIndexSelected(1, false);
3007   CheckIsIndexSelected(2, false);
3008 
3009   // Make selections to change the value of the focused annotation
3010   // programmatically showing that only one value remains selected at a time.
3011   SetIndexSelectedShouldSucceed(0, true);
3012   CheckFocusedFieldText(L"Foo");
3013   CheckIsIndexSelected(0, true);
3014   CheckIsIndexSelected(1, false);
3015   CheckIsIndexSelected(2, false);
3016 
3017   SetIndexSelectedShouldSucceed(1, true);
3018   CheckFocusedFieldText(L"Bar");
3019   CheckIsIndexSelected(0, false);
3020   CheckIsIndexSelected(1, true);
3021   CheckIsIndexSelected(2, false);
3022 
3023   // Selecting/deselecting an index that is already selected/deselected is
3024   // success.
3025   SetIndexSelectedShouldSucceed(1, true);
3026   CheckFocusedFieldText(L"Bar");
3027   CheckIsIndexSelected(0, false);
3028   CheckIsIndexSelected(1, true);
3029   CheckIsIndexSelected(2, false);
3030 
3031   SetIndexSelectedShouldSucceed(2, false);
3032   CheckFocusedFieldText(L"Bar");
3033   CheckIsIndexSelected(0, false);
3034   CheckIsIndexSelected(1, true);
3035   CheckIsIndexSelected(2, false);
3036 
3037   // Cannot select indices that are out of range.
3038   SetIndexSelectedShouldFail(100, true);
3039   SetIndexSelectedShouldFail(-100, true);
3040   SetIndexSelectedShouldFail(100, false);
3041   SetIndexSelectedShouldFail(-100, false);
3042   // Confirm that previous values were not changed.
3043   CheckFocusedFieldText(L"Bar");
3044   CheckIsIndexSelected(0, false);
3045   CheckIsIndexSelected(1, true);
3046   CheckIsIndexSelected(2, false);
3047 
3048   // Unlike combobox, should be able to deselect all indices.
3049   SetIndexSelectedShouldSucceed(1, false);
3050   CheckFocusedFieldText(L"");
3051   CheckIsIndexSelected(0, false);
3052   CheckIsIndexSelected(1, false);
3053   CheckIsIndexSelected(2, false);
3054 
3055   // Check that above actions are interchangeable with click actions, should be
3056   // able to use a combination of both.
3057   ClickOnSingleSelectFormOption(1);
3058   CheckFocusedFieldText(L"Bar");
3059   CheckIsIndexSelected(0, false);
3060   CheckIsIndexSelected(1, true);
3061   CheckIsIndexSelected(2, false);
3062 }
3063 
3064 // Re: Focus Field Text - For multiselect listboxes a caret is set on the last
3065 // item to be selected/deselected. The text of that item should be returned.
TEST_F(FPDFFormFillListBoxFormEmbedderTest,SetSelectionProgrammaticallyMultiSelectField)3066 TEST_F(FPDFFormFillListBoxFormEmbedderTest,
3067        SetSelectionProgrammaticallyMultiSelectField) {
3068   // Multiselect field set to 'Banana' (index 1) upon opening.
3069   FocusOnMultiSelectForm();
3070   for (int i = 0; i < 26; i++) {
3071     bool expected = i == 1;
3072     CheckIsIndexSelected(i, expected);
3073   }
3074   CheckFocusedFieldText(L"Banana");
3075 
3076   // Select some more options.
3077   SetIndexSelectedShouldSucceed(5, true);
3078   SetIndexSelectedShouldSucceed(6, true);
3079   SetIndexSelectedShouldSucceed(20, true);
3080   for (int i = 0; i < 26; i++) {
3081     bool expected = (i == 1 || i == 5 || i == 6 || i == 20);
3082     CheckIsIndexSelected(i, expected);
3083   }
3084   CheckFocusedFieldText(L"Ugli Fruit");
3085 
3086   // Selecting indices that are already selected is success - changes nothing.
3087   SetIndexSelectedShouldSucceed(5, true);
3088   SetIndexSelectedShouldSucceed(6, true);
3089   SetIndexSelectedShouldSucceed(20, true);
3090   for (int i = 0; i < 26; i++) {
3091     bool expected = (i == 1 || i == 5 || i == 6 || i == 20);
3092     CheckIsIndexSelected(i, expected);
3093   }
3094   CheckFocusedFieldText(L"Ugli Fruit");
3095 
3096   // Deselect some options.
3097   SetIndexSelectedShouldSucceed(20, false);
3098   SetIndexSelectedShouldSucceed(1, false);
3099   for (int i = 0; i < 26; i++) {
3100     bool expected = (i == 5 || i == 6);
3101     CheckIsIndexSelected(i, expected);
3102   }
3103   CheckFocusedFieldText(L"Banana");
3104 
3105   // Deselecting indices that already aren't selected is success - does not
3106   // change the selected values but moves the focus text caret to last item we
3107   // executed on.
3108   SetIndexSelectedShouldSucceed(1, false);
3109   SetIndexSelectedShouldSucceed(3, false);
3110   for (int i = 0; i < 26; i++) {
3111     bool expected = (i == 5 || i == 6);
3112     CheckIsIndexSelected(i, expected);
3113   }
3114   CheckFocusedFieldText(L"Date");
3115 
3116   // Cannot select indices that are out of range.
3117   SetIndexSelectedShouldFail(100, true);
3118   SetIndexSelectedShouldFail(-100, true);
3119   SetIndexSelectedShouldFail(100, false);
3120   SetIndexSelectedShouldFail(-100, false);
3121   // Confirm that previous values were not changed.
3122   CheckFocusedFieldText(L"Date");
3123   for (int i = 0; i < 26; i++) {
3124     bool expected = (i == 5 || i == 6);
3125     CheckIsIndexSelected(i, expected);
3126   }
3127 
3128   // Check that above actions are interchangeable with click actions, should be
3129   // able to use a combination of both.
3130   // TODO(bug_1377): Change to click on form option 0 instead of form option 1
3131   ClickOnMultiSelectFormOption(1);
3132   for (int i = 0; i < 26; i++) {
3133     bool expected = i == 1;
3134     CheckIsIndexSelected(i, expected);
3135   }
3136   CheckFocusedFieldText(L"Banana");
3137 }
3138 
TEST_F(FPDFFormFillListBoxFormEmbedderTest,CheckIfMultipleSelectedIndices)3139 TEST_F(FPDFFormFillListBoxFormEmbedderTest, CheckIfMultipleSelectedIndices) {
3140   // Multiselect field set to 'Belgium' (index 1) and 'Denmark' (index 3) upon
3141   // opening.
3142   FocusOnMultiSelectMultipleIndicesForm();
3143   for (int i = 0; i < 5; i++) {
3144     bool expected = (i == 1 || i == 3);
3145     CheckIsIndexSelected(i, expected);
3146   }
3147 }
3148 
TEST_F(FPDFFormFillListBoxFormEmbedderTest,CheckIfMultipleSelectedValues)3149 TEST_F(FPDFFormFillListBoxFormEmbedderTest, CheckIfMultipleSelectedValues) {
3150   // Multiselect field set to 'Gamma' (index 2) and 'Epsilon' (index 4) upon
3151   // opening.
3152   FocusOnMultiSelectMultipleValuesForm();
3153   for (int i = 0; i < 5; i++) {
3154     bool expected = (i == 2 || i == 4);
3155     CheckIsIndexSelected(i, expected);
3156   }
3157 }
3158 
TEST_F(FPDFFormFillListBoxFormEmbedderTest,CheckIfMultipleSelectedMismatch)3159 TEST_F(FPDFFormFillListBoxFormEmbedderTest, CheckIfMultipleSelectedMismatch) {
3160   // Multiselect field set to 'Alligator' (index 0) and 'Cougar' (index 2) upon
3161   // opening.
3162   FocusOnMultiSelectMultipleMismatchForm();
3163   for (int i = 0; i < 5; i++) {
3164     bool expected = (i == 0 || i == 2);
3165     CheckIsIndexSelected(i, expected);
3166   }
3167 }
3168 
TEST_F(FPDFFormFillListBoxFormEmbedderTest,CheckIfVerticalScrollIsAtFirstSelected)3169 TEST_F(FPDFFormFillListBoxFormEmbedderTest,
3170        CheckIfVerticalScrollIsAtFirstSelected) {
3171   // Multiselect field set to 'Gamma' (index 2) and 'Epsilon' (index 4) upon
3172   // opening.
3173 
3174   // TODO(bug_1377): Behavior should be changed to the one described below.
3175   // The top visible option is 'Gamma' (index 2), so the first selection should
3176   // not change. The second selection, 'Epsilon,' should be deselected.
3177   ClickOnMultiSelectMultipleValuesFormOption(0);
3178   for (int i = 0; i < 5; i++) {
3179     bool expected = i == 0;
3180     CheckIsIndexSelected(i, expected);
3181   }
3182 }
3183 
TEST_F(FPDFFormFillListBoxFormEmbedderTest,CheckForNoOverscroll)3184 TEST_F(FPDFFormFillListBoxFormEmbedderTest, CheckForNoOverscroll) {
3185   // Only the last option in the list, 'Saskatchewan', is selected.
3186   FocusOnSingleSelectLastSelectedForm();
3187   for (int i = 0; i < 10; i++) {
3188     bool expected = i == 9;
3189     CheckIsIndexSelected(i, expected);
3190   }
3191 
3192   // Even though the top index is specified to be at 'Saskatchewan' (index 9),
3193   // the top visible option will be the one above it, 'Quebec' (index 8), to
3194   // prevent overscrolling. Therefore, clicking on the first visible option of
3195   // the list should select 'Quebec' instead of 'Saskatchewan.'
3196   ClickOnSingleSelectLastSelectedFormOption(0);
3197   for (int i = 0; i < 10; i++) {
3198     bool expected = i == 8;
3199     CheckIsIndexSelected(i, expected);
3200   }
3201 }
3202 
TEST_F(FPDFFormFillTextFormEmbedderTest,ReplaceAndKeepSelection)3203 TEST_F(FPDFFormFillTextFormEmbedderTest, ReplaceAndKeepSelection) {
3204   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"XYZ");
3205   ClickOnFormFieldAtPoint(RegularFormBegin());
3206   CheckCanUndo(false);
3207   CheckCanRedo(false);
3208 
3209   TypeTextIntoTextField(2, RegularFormBegin());
3210   CheckFocusedFieldText(L"AB");
3211   CheckSelection(L"");
3212   SelectTextWithKeyboard(1, FWL_VKEY_Right, RegularFormBegin());
3213   CheckSelection(L"A");
3214 
3215   FORM_ReplaceAndKeepSelection(form_handle(), page(), text_to_insert.get());
3216   CheckFocusedFieldText(L"XYZB");
3217   CheckSelection(L"XYZ");
3218   CheckCanUndo(true);
3219   CheckCanRedo(false);
3220 
3221   PerformUndo();
3222   CheckFocusedFieldText(L"AB");
3223   CheckCanUndo(true);
3224   CheckCanRedo(true);
3225 
3226   SelectTextWithKeyboard(1, FWL_VKEY_Left, RegularFormEnd());
3227   CheckSelection(L"B");
3228 
3229   FORM_ReplaceAndKeepSelection(form_handle(), page(), text_to_insert.get());
3230   CheckFocusedFieldText(L"AXYZ");
3231   CheckSelection(L"XYZ");
3232   CheckCanUndo(true);
3233   CheckCanRedo(false);
3234 }
3235 
TEST_F(FPDFFormFillTextFormEmbedderTest,ReplaceSelection)3236 TEST_F(FPDFFormFillTextFormEmbedderTest, ReplaceSelection) {
3237   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"XYZ");
3238   ClickOnFormFieldAtPoint(RegularFormBegin());
3239   CheckCanUndo(false);
3240   CheckCanRedo(false);
3241 
3242   TypeTextIntoTextField(2, RegularFormBegin());
3243   CheckFocusedFieldText(L"AB");
3244   CheckSelection(L"");
3245   SelectTextWithKeyboard(1, FWL_VKEY_Right, RegularFormBegin());
3246   CheckSelection(L"A");
3247 
3248   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
3249   CheckFocusedFieldText(L"XYZB");
3250   CheckCanUndo(true);
3251   CheckCanRedo(false);
3252 
3253   PerformUndo();
3254   CheckFocusedFieldText(L"AB");
3255   CheckCanUndo(true);
3256   CheckCanRedo(true);
3257 
3258   PerformUndo();
3259   CheckFocusedFieldText(L"A");
3260   CheckCanUndo(true);
3261   CheckCanRedo(true);
3262 
3263   PerformUndo();
3264   CheckFocusedFieldText(L"");
3265   CheckCanUndo(false);
3266   CheckCanRedo(true);
3267 
3268   PerformRedo();
3269   CheckFocusedFieldText(L"A");
3270   CheckCanUndo(true);
3271   CheckCanRedo(true);
3272 
3273   PerformRedo();
3274   CheckFocusedFieldText(L"AB");
3275   CheckCanUndo(true);
3276   CheckCanRedo(true);
3277 
3278   PerformRedo();
3279   CheckFocusedFieldText(L"XYZB");
3280   CheckCanUndo(true);
3281   CheckCanRedo(false);
3282 }
3283 
TEST_F(FPDFFormFillTextFormEmbedderTest,SelectAllWithKeyboardShortcut)3284 TEST_F(FPDFFormFillTextFormEmbedderTest, SelectAllWithKeyboardShortcut) {
3285   // Start with a couple of letters in the text form.
3286   TypeTextIntoTextField(2, RegularFormBegin());
3287   CheckFocusedFieldText(L"AB");
3288   CheckSelection(L"");
3289 
3290   // Select all with the keyboard shortcut.
3291 #if BUILDFLAG(IS_APPLE)
3292   constexpr int kCorrectModifier = FWL_EVENTFLAG_MetaKey;
3293 #else
3294   constexpr int kCorrectModifier = FWL_EVENTFLAG_ControlKey;
3295 #endif
3296   FORM_OnChar(form_handle(), page(), pdfium::ascii::kControlA,
3297               kCorrectModifier);
3298   CheckSelection(L"AB");
3299 
3300   // Reset the selection again.
3301   ClickOnFormFieldAtPoint(RegularFormBegin());
3302   CheckSelection(L"");
3303 
3304   // Select all with the keyboard shortcut using the wrong modifier key.
3305 #if BUILDFLAG(IS_APPLE)
3306   constexpr int kWrongModifier = FWL_EVENTFLAG_ControlKey;
3307 #else
3308   constexpr int kWrongModifier = FWL_EVENTFLAG_MetaKey;
3309 #endif
3310   FORM_OnChar(form_handle(), page(), pdfium::ascii::kControlA, kWrongModifier);
3311   CheckSelection(L"");
3312 }
3313 
3314 class FPDFXFAFormBug1055869EmbedderTest
3315     : public FPDFFormFillInteractiveEmbedderTest {
3316  protected:
3317   FPDFXFAFormBug1055869EmbedderTest() = default;
3318   ~FPDFXFAFormBug1055869EmbedderTest() override = default;
3319 
GetDocumentName() const3320   const char* GetDocumentName() const override { return "bug_1055869.pdf"; }
GetFormType() const3321   int GetFormType() const override { return FORMTYPE_XFA_FULL; }
3322 };
3323 
TEST_F(FPDFXFAFormBug1055869EmbedderTest,Paste)3324 TEST_F(FPDFXFAFormBug1055869EmbedderTest, Paste) {
3325   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"XYZ");
3326   DoubleClickOnFormFieldAtPoint(CFX_PointF(100, 100));
3327   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
3328 }
3329 
3330 class FPDFXFAFormBug1058653EmbedderTest
3331     : public FPDFFormFillInteractiveEmbedderTest {
3332  protected:
3333   FPDFXFAFormBug1058653EmbedderTest() = default;
3334   ~FPDFXFAFormBug1058653EmbedderTest() override = default;
3335 
GetDocumentName() const3336   const char* GetDocumentName() const override { return "bug_1058653.pdf"; }
GetFormType() const3337   int GetFormType() const override { return FORMTYPE_XFA_FULL; }
3338 };
3339 
TEST_F(FPDFXFAFormBug1058653EmbedderTest,Paste)3340 TEST_F(FPDFXFAFormBug1058653EmbedderTest, Paste) {
3341   ScopedFPDFWideString text_to_insert = GetFPDFWideString(L"");
3342   DoubleClickOnFormFieldAtPoint(CFX_PointF(22, 22));
3343   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
3344 }
3345 
3346 class FPDFFormFillActionUriTest : public EmbedderTest {
3347  protected:
3348   FPDFFormFillActionUriTest() = default;
3349   ~FPDFFormFillActionUriTest() override = default;
3350 
SetUp()3351   void SetUp() override {
3352     EmbedderTest::SetUp();
3353     ASSERT_TRUE(OpenDocument("annots_action_handling.pdf"));
3354     page_ = LoadPage(0);
3355     ASSERT_TRUE(page_);
3356 
3357     // Set Widget and Link as supported tabbable annots.
3358     constexpr FPDF_ANNOTATION_SUBTYPE kFocusableSubtypes[] = {FPDF_ANNOT_WIDGET,
3359                                                               FPDF_ANNOT_LINK};
3360     constexpr size_t kSubtypeCount = std::size(kFocusableSubtypes);
3361     ASSERT_TRUE(FPDFAnnot_SetFocusableSubtypes(
3362         form_handle(), kFocusableSubtypes, kSubtypeCount));
3363   }
3364 
TearDown()3365   void TearDown() override {
3366     UnloadPage(page_);
3367     EmbedderTest::TearDown();
3368   }
3369 
SetFocusOnNthAnnot(size_t n)3370   void SetFocusOnNthAnnot(size_t n) {
3371     DCHECK_NE(n, 0u);
3372     // Setting focus on first annot.
3373     FORM_OnMouseMove(form_handle(), page(), /*modifier=*/0, 100, 680);
3374     FORM_OnLButtonDown(form_handle(), page(), /*modifier=*/0, 100, 680);
3375     FORM_OnLButtonUp(form_handle(), page(), /*modifier=*/0, 100, 680);
3376     for (size_t i = 1; i < n; i++)
3377       ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Tab, 0));
3378   }
3379 
page()3380   FPDF_PAGE page() { return page_; }
3381 
3382  private:
3383   FPDF_PAGE page_ = nullptr;
3384 };
3385 
TEST_F(FPDFFormFillActionUriTest,ButtonActionInvokeTest)3386 TEST_F(FPDFFormFillActionUriTest, ButtonActionInvokeTest) {
3387   NiceMock<EmbedderTestMockDelegate> mock;
3388   // TODO(crbug.com/1028991): DoURIAction expect call should be 1.
3389   EXPECT_CALL(mock, DoURIAction(_)).Times(0);
3390   SetDelegate(&mock);
3391 
3392   SetFocusOnNthAnnot(1);
3393 
3394   // Tab once from first form to go to button widget.
3395   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Tab, 0));
3396 
3397   // TODO(crbug.com/1028991): Following should be changed to ASSERT_TRUE after
3398   // handling key press implementation on buttons.
3399   ASSERT_FALSE(FORM_OnChar(form_handle(), page(), pdfium::ascii::kReturn, 0));
3400 }
3401 
TEST_F(FPDFFormFillActionUriTest,LinkActionInvokeTest)3402 TEST_F(FPDFFormFillActionUriTest, LinkActionInvokeTest) {
3403   NiceMock<EmbedderTestMockDelegate> mock;
3404   {
3405     InSequence sequence;
3406     const char kExpectedUri[] = "https://cs.chromium.org/";
3407 #ifdef PDF_ENABLE_XFA
3408     EXPECT_CALL(mock,
3409                 DoURIActionWithKeyboardModifier(_, StrEq(kExpectedUri), _))
3410         .Times(4);
3411 #else   // PDF_ENABLE_XFA
3412     EXPECT_CALL(mock, DoURIAction(StrEq(kExpectedUri))).Times(4);
3413     EXPECT_CALL(mock, DoURIActionWithKeyboardModifier(_, _, _)).Times(0);
3414 #endif  // PDF_ENABLE_XFA
3415   }
3416   SetDelegate(&mock);
3417   SetFocusOnNthAnnot(3);
3418   int modifier = 0;
3419   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3420   modifier = FWL_EVENTFLAG_ControlKey;
3421   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3422   modifier = FWL_EVENTFLAG_ShiftKey;
3423   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3424   modifier |= FWL_EVENTFLAG_ControlKey;
3425   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3426 
3427   ASSERT_FALSE(FORM_OnKeyDown(nullptr, page(), FWL_VKEY_Return, modifier));
3428   ASSERT_FALSE(
3429       FORM_OnKeyDown(form_handle(), nullptr, FWL_VKEY_Return, modifier));
3430   // Following checks should be changed to ASSERT_TRUE if FORM_OnKeyDown starts
3431   // handling for Shift/Space/Control.
3432   ASSERT_FALSE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Shift, modifier));
3433   ASSERT_FALSE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Space, modifier));
3434   ASSERT_FALSE(
3435       FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Control, modifier));
3436 }
3437 
TEST_F(FPDFFormFillActionUriTest,InternalLinkActionInvokeTest)3438 TEST_F(FPDFFormFillActionUriTest, InternalLinkActionInvokeTest) {
3439   NiceMock<EmbedderTestMockDelegate> mock;
3440   EXPECT_CALL(mock, DoGoToAction(_, _, 1, _, _)).Times(12);
3441   SetDelegate(&mock);
3442 
3443   SetFocusOnNthAnnot(4);
3444   int modifier = 0;
3445   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3446   modifier = FWL_EVENTFLAG_ControlKey;
3447   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3448   modifier = FWL_EVENTFLAG_ShiftKey;
3449   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3450   modifier |= FWL_EVENTFLAG_ControlKey;
3451   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3452 
3453   SetFocusOnNthAnnot(5);
3454   modifier = 0;
3455   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3456   modifier = FWL_EVENTFLAG_ControlKey;
3457   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3458   modifier = FWL_EVENTFLAG_ShiftKey;
3459   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3460   modifier |= FWL_EVENTFLAG_ControlKey;
3461   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3462 
3463   SetFocusOnNthAnnot(6);
3464   modifier = 0;
3465   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3466   modifier = FWL_EVENTFLAG_ControlKey;
3467   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3468   modifier = FWL_EVENTFLAG_ShiftKey;
3469   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3470   modifier |= FWL_EVENTFLAG_ControlKey;
3471   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3472 
3473   ASSERT_FALSE(FORM_OnKeyDown(nullptr, page(), FWL_VKEY_Return, modifier));
3474   ASSERT_FALSE(
3475       FORM_OnKeyDown(form_handle(), nullptr, FWL_VKEY_Return, modifier));
3476   // Following checks should be changed to ASSERT_TRUE if FORM_OnKeyDown starts
3477   // handling for Shift/Space/Control.
3478   ASSERT_FALSE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Shift, modifier));
3479   ASSERT_FALSE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Space, modifier));
3480   ASSERT_FALSE(
3481       FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Control, modifier));
3482 }
3483 
3484 class FPDFFormFillActionUriTestVersion2 : public FPDFFormFillActionUriTest {
SetUp()3485   void SetUp() override {
3486     SetFormFillInfoVersion(2);
3487     FPDFFormFillActionUriTest::SetUp();
3488   }
3489 };
3490 
TEST_F(FPDFFormFillActionUriTestVersion2,LinkActionInvokeTest)3491 TEST_F(FPDFFormFillActionUriTestVersion2, LinkActionInvokeTest) {
3492   NiceMock<EmbedderTestMockDelegate> mock;
3493   {
3494     InSequence sequence;
3495     EXPECT_CALL(mock, DoURIAction(_)).Times(0);
3496     const char kExpectedUri[] = "https://cs.chromium.org/";
3497     EXPECT_CALL(mock,
3498                 DoURIActionWithKeyboardModifier(_, StrEq(kExpectedUri), 0));
3499     EXPECT_CALL(mock, DoURIActionWithKeyboardModifier(
3500                           _, StrEq(kExpectedUri), FWL_EVENTFLAG_ControlKey));
3501     EXPECT_CALL(mock, DoURIActionWithKeyboardModifier(_, StrEq(kExpectedUri),
3502                                                       FWL_EVENTFLAG_ShiftKey));
3503     EXPECT_CALL(mock,
3504                 DoURIActionWithKeyboardModifier(_, StrEq(kExpectedUri), 3));
3505   }
3506   SetDelegate(&mock);
3507   SetFocusOnNthAnnot(3);
3508   int modifier = 0;
3509   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3510   modifier = FWL_EVENTFLAG_ControlKey;
3511   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3512   modifier = FWL_EVENTFLAG_ShiftKey;
3513   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3514   modifier |= FWL_EVENTFLAG_ControlKey;
3515   ASSERT_TRUE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Return, modifier));
3516 
3517   ASSERT_FALSE(FORM_OnKeyDown(nullptr, page(), FWL_VKEY_Return, modifier));
3518   ASSERT_FALSE(
3519       FORM_OnKeyDown(form_handle(), nullptr, FWL_VKEY_Return, modifier));
3520   // Following checks should be changed to ASSERT_TRUE if FORM_OnKeyDown starts
3521   // handling for Shift/Space/Control.
3522   ASSERT_FALSE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Shift, modifier));
3523   ASSERT_FALSE(FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Space, modifier));
3524   ASSERT_FALSE(
3525       FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Control, modifier));
3526 }
3527