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