Home | History | Annotate | Download | only in fpdfsdk
      1 // Copyright 2015 PDFium Authors. All rights reserved.
      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 <memory>
      6 #include <string>
      7 #include <vector>
      8 
      9 #include "core/fxcrt/fx_coordinates.h"
     10 #include "core/fxcrt/fx_string.h"
     11 #include "core/fxcrt/fx_system.h"
     12 #include "public/cpp/fpdf_deleters.h"
     13 #include "public/fpdf_formfill.h"
     14 #include "public/fpdf_fwlevent.h"
     15 #include "testing/embedder_test.h"
     16 #include "testing/embedder_test_mock_delegate.h"
     17 #include "testing/embedder_test_timer_handling_delegate.h"
     18 #include "testing/gmock/include/gmock/gmock.h"
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 
     21 using testing::_;
     22 
     23 using FPDFFormFillEmbeddertest = EmbedderTest;
     24 
     25 // A base class for many related tests that involve clicking and typing into
     26 // form fields.
     27 class FPDFFormFillInteractiveEmbeddertest : public FPDFFormFillEmbeddertest {
     28  protected:
     29   FPDFFormFillInteractiveEmbeddertest() = default;
     30   ~FPDFFormFillInteractiveEmbeddertest() override = default;
     31 
     32   void SetUp() override {
     33     FPDFFormFillEmbeddertest::SetUp();
     34     ASSERT_TRUE(OpenDocument(GetDocumentName()));
     35     page_ = LoadPage(0);
     36     ASSERT_TRUE(page_);
     37     FormSanityChecks();
     38   }
     39 
     40   void TearDown() override {
     41     UnloadPage(page_);
     42     FPDFFormFillEmbeddertest::TearDown();
     43   }
     44 
     45   // Returns the name of the PDF to use.
     46   virtual const char* GetDocumentName() const = 0;
     47 
     48   // Returns the type of field(s) in the PDF.
     49   virtual int GetFormType() const = 0;
     50 
     51   // Optionally do some sanity check on the document after loading.
     52   virtual void FormSanityChecks() {}
     53 
     54   FPDF_PAGE page() { return page_; }
     55 
     56   int GetFormTypeAtPoint(const CFX_PointF& point) {
     57     return FPDFPage_HasFormFieldAtPoint(form_handle(), page_, point.x, point.y);
     58   }
     59 
     60   void ClickOnFormFieldAtPoint(const CFX_PointF& point) {
     61     // Click on the text field or combobox as specified by coordinates.
     62     FORM_OnMouseMove(form_handle(), page_, 0, point.x, point.y);
     63     FORM_OnLButtonDown(form_handle(), page_, 0, point.x, point.y);
     64     FORM_OnLButtonUp(form_handle(), page_, 0, point.x, point.y);
     65   }
     66 
     67   void TypeTextIntoTextField(int num_chars, const CFX_PointF& point) {
     68     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(point));
     69     ClickOnFormFieldAtPoint(point);
     70 
     71     // Type text starting with 'A' to as many chars as specified by |num_chars|.
     72     for (int i = 0; i < num_chars; ++i) {
     73       FORM_OnChar(form_handle(), page_, 'A' + i, 0);
     74     }
     75   }
     76 
     77   // Navigates to text field using the mouse and then selects text via the
     78   // shift and specfied left or right arrow key.
     79   void SelectTextWithKeyboard(int num_chars,
     80                               int arrow_key,
     81                               const CFX_PointF& point) {
     82     // Navigate to starting position for selection.
     83     ClickOnFormFieldAtPoint(point);
     84 
     85     // Hold down shift (and don't release until entire text is selected).
     86     FORM_OnKeyDown(form_handle(), page_, FWL_VKEY_Shift, 0);
     87 
     88     // Select text char by char via left or right arrow key.
     89     for (int i = 0; i < num_chars; ++i) {
     90       FORM_OnKeyDown(form_handle(), page_, arrow_key, FWL_EVENTFLAG_ShiftKey);
     91       FORM_OnKeyUp(form_handle(), page_, arrow_key, FWL_EVENTFLAG_ShiftKey);
     92     }
     93     FORM_OnKeyUp(form_handle(), page_, FWL_VKEY_Shift, 0);
     94   }
     95 
     96   // Uses the mouse to navigate to text field and select text.
     97   void SelectTextWithMouse(const CFX_PointF& start, const CFX_PointF& end) {
     98     ASSERT(start.y == end.y);
     99 
    100     // Navigate to starting position and click mouse.
    101     FORM_OnMouseMove(form_handle(), page_, 0, start.x, start.y);
    102     FORM_OnLButtonDown(form_handle(), page_, 0, start.x, start.y);
    103 
    104     // Hold down mouse until reach end of desired selection.
    105     FORM_OnMouseMove(form_handle(), page_, 0, end.x, end.y);
    106     FORM_OnLButtonUp(form_handle(), page_, 0, end.x, end.y);
    107   }
    108 
    109   void CheckSelection(const WideStringView& expected_string) {
    110     // Calculate expected length for selected text.
    111     int num_chars = expected_string.GetLength();
    112 
    113     // Check actual selection against expected selection.
    114     const unsigned long expected_length =
    115         sizeof(unsigned short) * (num_chars + 1);
    116     unsigned long sel_text_len =
    117         FORM_GetSelectedText(form_handle(), page_, nullptr, 0);
    118     ASSERT_EQ(expected_length, sel_text_len);
    119 
    120     std::vector<unsigned short> buf(sel_text_len);
    121     EXPECT_EQ(expected_length, FORM_GetSelectedText(form_handle(), page_,
    122                                                     buf.data(), sel_text_len));
    123 
    124     EXPECT_EQ(expected_string, WideString::FromUTF16LE(buf.data(), num_chars));
    125   }
    126 
    127  private:
    128   FPDF_PAGE page_ = nullptr;
    129 };
    130 
    131 class FPDFFormFillTextFormEmbeddertest
    132     : public FPDFFormFillInteractiveEmbeddertest {
    133  protected:
    134   FPDFFormFillTextFormEmbeddertest() = default;
    135   ~FPDFFormFillTextFormEmbeddertest() override = default;
    136 
    137   const char* GetDocumentName() const override {
    138     // PDF with several form text fields:
    139     // - "Text Box" - Regular text box with no special attributes.
    140     // - "ReadOnly" - Ff: 1.
    141     // - "CharLimit" - MaxLen: 10, V: Elephant.
    142     return "text_form_multiple.pdf";
    143   }
    144 
    145   int GetFormType() const override { return FPDF_FORMFIELD_TEXTFIELD; }
    146 
    147   void FormSanityChecks() override {
    148     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(CharLimitFormBegin()));
    149     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(CharLimitFormEnd()));
    150     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(RegularFormBegin()));
    151     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(RegularFormEnd()));
    152   }
    153 
    154   void SelectAllCharLimitFormTextWithMouse() {
    155     SelectTextWithMouse(CharLimitFormEnd(), CharLimitFormBegin());
    156   }
    157 
    158   void SelectAllRegularFormTextWithMouse() {
    159     SelectTextWithMouse(RegularFormEnd(), RegularFormBegin());
    160   }
    161 
    162   const CFX_PointF& CharLimitFormBegin() const {
    163     static const CFX_PointF point = CharLimitFormAtX(kFormBeginX);
    164     return point;
    165   }
    166 
    167   const CFX_PointF& CharLimitFormEnd() const {
    168     static const CFX_PointF point = CharLimitFormAtX(kFormEndX);
    169     return point;
    170   }
    171 
    172   const CFX_PointF& RegularFormBegin() const {
    173     static const CFX_PointF point = RegularFormAtX(kFormBeginX);
    174     return point;
    175   }
    176 
    177   const CFX_PointF& RegularFormEnd() const {
    178     static const CFX_PointF point = RegularFormAtX(kFormEndX);
    179     return point;
    180   }
    181 
    182   static CFX_PointF CharLimitFormAtX(float x) {
    183     ASSERT(x >= kFormBeginX);
    184     ASSERT(x <= kFormEndX);
    185     return CFX_PointF(x, kCharLimitFormY);
    186   }
    187 
    188   static CFX_PointF RegularFormAtX(float x) {
    189     ASSERT(x >= kFormBeginX);
    190     ASSERT(x <= kFormEndX);
    191     return CFX_PointF(x, kRegularFormY);
    192   }
    193 
    194  private:
    195   static constexpr float kFormBeginX = 102.0;
    196   static constexpr float kFormEndX = 195.0;
    197   static constexpr float kCharLimitFormY = 60.0;
    198   static constexpr float kRegularFormY = 115.0;
    199 };
    200 
    201 class FPDFFormFillComboBoxFormEmbeddertest
    202     : public FPDFFormFillInteractiveEmbeddertest {
    203  protected:
    204   FPDFFormFillComboBoxFormEmbeddertest() = default;
    205   ~FPDFFormFillComboBoxFormEmbeddertest() override = default;
    206 
    207   const char* GetDocumentName() const override {
    208     // PDF with form comboboxes:
    209     // - "Combo_Editable" - Ff: 393216, 3 options with pair values.
    210     // - "Combo1" - Ff: 131072, 3 options with single values.
    211     // - "Combo_ReadOnly" - Ff: 131073, 3 options with single values.
    212     return "combobox_form.pdf";
    213   }
    214 
    215   int GetFormType() const override { return FPDF_FORMFIELD_COMBOBOX; }
    216 
    217   void FormSanityChecks() override {
    218     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(EditableFormBegin()));
    219     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(EditableFormEnd()));
    220     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(EditableFormDropDown()));
    221     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(NonEditableFormBegin()));
    222     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(NonEditableFormEnd()));
    223     EXPECT_EQ(GetFormType(), GetFormTypeAtPoint(NonEditableFormDropDown()));
    224   }
    225 
    226   void SelectEditableFormOption(int item_index) {
    227     SelectOption(item_index, EditableFormDropDown());
    228   }
    229 
    230   void SelectNonEditableFormOption(int item_index) {
    231     SelectOption(item_index, NonEditableFormDropDown());
    232   }
    233 
    234   void SelectAllEditableFormTextWithMouse() {
    235     SelectTextWithMouse(EditableFormEnd(), EditableFormBegin());
    236   }
    237 
    238   const CFX_PointF& EditableFormBegin() const {
    239     static const CFX_PointF point = EditableFormAtX(kFormBeginX);
    240     return point;
    241   }
    242 
    243   const CFX_PointF& EditableFormEnd() const {
    244     static const CFX_PointF point = EditableFormAtX(kFormEndX);
    245     return point;
    246   }
    247 
    248   const CFX_PointF& EditableFormDropDown() const {
    249     static const CFX_PointF point(kFormDropDownX, kEditableFormY);
    250     return point;
    251   }
    252 
    253   const CFX_PointF& NonEditableFormBegin() const {
    254     static const CFX_PointF point = NonEditableFormAtX(kFormBeginX);
    255     return point;
    256   }
    257 
    258   const CFX_PointF& NonEditableFormEnd() const {
    259     static const CFX_PointF point = NonEditableFormAtX(kFormEndX);
    260     return point;
    261   }
    262 
    263   const CFX_PointF& NonEditableFormDropDown() const {
    264     static const CFX_PointF point(kFormDropDownX, kNonEditableFormY);
    265     return point;
    266   }
    267 
    268   static CFX_PointF EditableFormAtX(float x) {
    269     ASSERT(x >= kFormBeginX);
    270     ASSERT(x <= kFormEndX);
    271     return CFX_PointF(x, kEditableFormY);
    272   }
    273 
    274   static CFX_PointF NonEditableFormAtX(float x) {
    275     ASSERT(x >= kFormBeginX);
    276     ASSERT(x <= kFormEndX);
    277     return CFX_PointF(x, kNonEditableFormY);
    278   }
    279 
    280  private:
    281   // Selects one of the pre-selected values from a combobox with three options.
    282   // Options are specified by |item_index|, which is 0-based.
    283   void SelectOption(int item_index, const CFX_PointF& point) {
    284     // Only relevant for comboboxes with three choices and the same dimensions
    285     // as those in combobox_form.pdf.
    286     ASSERT(item_index >= 0);
    287     ASSERT(item_index < 3);
    288 
    289     // Navigate to button for drop down and click mouse to reveal options.
    290     ClickOnFormFieldAtPoint(point);
    291 
    292     // Calculate to Y-coordinate of dropdown option to be selected.
    293     constexpr double kChoiceHeight = 15;
    294     CFX_PointF option_point = point;
    295     option_point.y -= kChoiceHeight * (item_index + 1);
    296 
    297     // Navigate to option and click mouse to select it.
    298     ClickOnFormFieldAtPoint(option_point);
    299   }
    300 
    301   static constexpr float kFormBeginX = 102.0;
    302   static constexpr float kFormEndX = 183.0;
    303   static constexpr float kFormDropDownX = 192.0;
    304   static constexpr float kEditableFormY = 60.0;
    305   static constexpr float kNonEditableFormY = 110.0;
    306 };
    307 
    308 TEST_F(FPDFFormFillEmbeddertest, FirstTest) {
    309   EmbedderTestMockDelegate mock;
    310   EXPECT_CALL(mock, Alert(_, _, _, _)).Times(0);
    311   EXPECT_CALL(mock, UnsupportedHandler(_)).Times(0);
    312   EXPECT_CALL(mock, SetTimer(_, _)).Times(0);
    313   EXPECT_CALL(mock, KillTimer(_)).Times(0);
    314   SetDelegate(&mock);
    315 
    316   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
    317   FPDF_PAGE page = LoadPage(0);
    318   EXPECT_TRUE(page);
    319   UnloadPage(page);
    320 }
    321 
    322 TEST_F(FPDFFormFillEmbeddertest, BUG_487928) {
    323   EmbedderTestTimerHandlingDelegate delegate;
    324   SetDelegate(&delegate);
    325 
    326   EXPECT_TRUE(OpenDocument("bug_487928.pdf"));
    327   FPDF_PAGE page = LoadPage(0);
    328   EXPECT_TRUE(page);
    329   DoOpenActions();
    330   delegate.AdvanceTime(5000);
    331   UnloadPage(page);
    332 }
    333 
    334 TEST_F(FPDFFormFillEmbeddertest, BUG_507316) {
    335   EmbedderTestTimerHandlingDelegate delegate;
    336   SetDelegate(&delegate);
    337 
    338   EXPECT_TRUE(OpenDocument("bug_507316.pdf"));
    339   FPDF_PAGE page = LoadPage(2);
    340   EXPECT_TRUE(page);
    341   DoOpenActions();
    342   delegate.AdvanceTime(4000);
    343   UnloadPage(page);
    344 }
    345 
    346 TEST_F(FPDFFormFillEmbeddertest, BUG_514690) {
    347   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
    348   FPDF_PAGE page = LoadPage(0);
    349   EXPECT_TRUE(page);
    350 
    351   // Test that FORM_OnMouseMove() etc. permit null HANDLES and PAGES.
    352   FORM_OnMouseMove(nullptr, page, 0, 10.0, 10.0);
    353   FORM_OnMouseMove(form_handle(), nullptr, 0, 10.0, 10.0);
    354 
    355   UnloadPage(page);
    356 }
    357 
    358 #ifdef PDF_ENABLE_V8
    359 TEST_F(FPDFFormFillEmbeddertest, BUG_551248) {
    360   // Test that timers fire once and intervals fire repeatedly.
    361   EmbedderTestTimerHandlingDelegate delegate;
    362   SetDelegate(&delegate);
    363 
    364   EXPECT_TRUE(OpenDocument("bug_551248.pdf"));
    365   FPDF_PAGE page = LoadPage(0);
    366   EXPECT_TRUE(page);
    367   DoOpenActions();
    368 
    369   const auto& alerts = delegate.GetAlerts();
    370   EXPECT_EQ(0U, alerts.size());
    371 
    372   delegate.AdvanceTime(1000);
    373   EXPECT_EQ(0U, alerts.size());  // nothing fired.
    374   delegate.AdvanceTime(1000);
    375   EXPECT_EQ(1U, alerts.size());  // interval fired.
    376   delegate.AdvanceTime(1000);
    377   EXPECT_EQ(2U, alerts.size());  // timer fired.
    378   delegate.AdvanceTime(1000);
    379   EXPECT_EQ(3U, alerts.size());  // interval fired again.
    380   delegate.AdvanceTime(1000);
    381   EXPECT_EQ(3U, alerts.size());  // nothing fired.
    382   delegate.AdvanceTime(1000);
    383   EXPECT_EQ(4U, alerts.size());  // interval fired again.
    384   delegate.AdvanceTime(1000);
    385   EXPECT_EQ(4U, alerts.size());  // nothing fired.
    386   UnloadPage(page);
    387 
    388   ASSERT_EQ(4U, alerts.size());  // nothing else fired.
    389 
    390   EXPECT_STREQ(L"interval fired", alerts[0].message.c_str());
    391   EXPECT_STREQ(L"Alert", alerts[0].title.c_str());
    392   EXPECT_EQ(0, alerts[0].type);
    393   EXPECT_EQ(0, alerts[0].icon);
    394 
    395   EXPECT_STREQ(L"timer fired", alerts[1].message.c_str());
    396   EXPECT_STREQ(L"Alert", alerts[1].title.c_str());
    397   EXPECT_EQ(0, alerts[1].type);
    398   EXPECT_EQ(0, alerts[1].icon);
    399 
    400   EXPECT_STREQ(L"interval fired", alerts[2].message.c_str());
    401   EXPECT_STREQ(L"Alert", alerts[2].title.c_str());
    402   EXPECT_EQ(0, alerts[2].type);
    403   EXPECT_EQ(0, alerts[2].icon);
    404 
    405   EXPECT_STREQ(L"interval fired", alerts[3].message.c_str());
    406   EXPECT_STREQ(L"Alert", alerts[3].title.c_str());
    407   EXPECT_EQ(0, alerts[3].type);
    408   EXPECT_EQ(0, alerts[3].icon);
    409 }
    410 
    411 TEST_F(FPDFFormFillEmbeddertest, BUG_620428) {
    412   // Test that timers and intervals are cancelable.
    413   EmbedderTestTimerHandlingDelegate delegate;
    414   SetDelegate(&delegate);
    415 
    416   EXPECT_TRUE(OpenDocument("bug_620428.pdf"));
    417   FPDF_PAGE page = LoadPage(0);
    418   EXPECT_TRUE(page);
    419   DoOpenActions();
    420   delegate.AdvanceTime(5000);
    421   UnloadPage(page);
    422 
    423   const auto& alerts = delegate.GetAlerts();
    424   ASSERT_EQ(1U, alerts.size());
    425   EXPECT_STREQ(L"done", alerts[0].message.c_str());
    426 }
    427 
    428 TEST_F(FPDFFormFillEmbeddertest, BUG_634394) {
    429   // Cancel timer inside timer callback.
    430   EmbedderTestTimerHandlingDelegate delegate;
    431   SetDelegate(&delegate);
    432 
    433   EXPECT_TRUE(OpenDocument("bug_634394.pdf"));
    434   FPDF_PAGE page = LoadPage(0);
    435   EXPECT_TRUE(page);
    436   DoOpenActions();
    437 
    438   // Timers fire at most once per AdvanceTime(), allow intervals
    439   // to fire several times if possible.
    440   delegate.AdvanceTime(1000);
    441   delegate.AdvanceTime(1000);
    442   delegate.AdvanceTime(1000);
    443   delegate.AdvanceTime(1000);
    444   delegate.AdvanceTime(1000);
    445   UnloadPage(page);
    446 
    447   const auto& alerts = delegate.GetAlerts();
    448   EXPECT_EQ(2U, alerts.size());
    449 }
    450 
    451 TEST_F(FPDFFormFillEmbeddertest, BUG_634716) {
    452   EmbedderTestTimerHandlingDelegate delegate;
    453   SetDelegate(&delegate);
    454 
    455   EXPECT_TRUE(OpenDocument("bug_634716.pdf"));
    456   FPDF_PAGE page = LoadPage(0);
    457   EXPECT_TRUE(page);
    458   DoOpenActions();
    459 
    460   // Timers fire at most once per AdvanceTime(), allow intervals
    461   // to fire several times if possible.
    462   delegate.AdvanceTime(1000);
    463   delegate.AdvanceTime(1000);
    464   delegate.AdvanceTime(1000);
    465   delegate.AdvanceTime(1000);
    466   delegate.AdvanceTime(1000);
    467   UnloadPage(page);
    468 
    469   const auto& alerts = delegate.GetAlerts();
    470   EXPECT_EQ(2U, alerts.size());
    471 }
    472 
    473 TEST_F(FPDFFormFillEmbeddertest, BUG_679649) {
    474   EmbedderTestTimerHandlingDelegate delegate;
    475   SetDelegate(&delegate);
    476 
    477   EXPECT_TRUE(OpenDocument("bug_679649.pdf"));
    478   FPDF_PAGE page = LoadPage(0);
    479   EXPECT_TRUE(page);
    480 
    481   delegate.SetFailNextTimer();
    482   DoOpenActions();
    483   delegate.AdvanceTime(2000);
    484   UnloadPage(page);
    485 
    486   const auto& alerts = delegate.GetAlerts();
    487   EXPECT_EQ(0u, alerts.size());
    488 }
    489 
    490 TEST_F(FPDFFormFillEmbeddertest, BUG_707673) {
    491   EmbedderTestTimerHandlingDelegate delegate;
    492   SetDelegate(&delegate);
    493 
    494   EXPECT_TRUE(OpenDocument("bug_707673.pdf"));
    495   FPDF_PAGE page = LoadPage(0);
    496   EXPECT_TRUE(page);
    497 
    498   DoOpenActions();
    499   FORM_OnLButtonDown(form_handle(), page, 0, 140, 590);
    500   FORM_OnLButtonUp(form_handle(), page, 0, 140, 590);
    501   delegate.AdvanceTime(1000);
    502   UnloadPage(page);
    503 
    504   const auto& alerts = delegate.GetAlerts();
    505   EXPECT_EQ(0u, alerts.size());
    506 }
    507 
    508 TEST_F(FPDFFormFillEmbeddertest, BUG_765384) {
    509   EXPECT_TRUE(OpenDocument("bug_765384.pdf"));
    510   FPDF_PAGE page = LoadPage(0);
    511   EXPECT_TRUE(page);
    512 
    513   DoOpenActions();
    514   FORM_OnLButtonDown(form_handle(), page, 0, 140, 590);
    515   FORM_OnLButtonUp(form_handle(), page, 0, 140, 590);
    516   UnloadPage(page);
    517 }
    518 
    519 #endif  // PDF_ENABLE_V8
    520 
    521 TEST_F(FPDFFormFillEmbeddertest, FormText) {
    522 #if _FX_PLATFORM_ == _FX_PLATFORM_APPLE_
    523   const char md5_1[] = "5f11dbe575fe197a37c3fb422559f8ff";
    524   const char md5_2[] = "35b1a4b679eafc749a0b6fda750c0e8d";
    525   const char md5_3[] = "65c64a7c355388f719a752aa1e23f6fe";
    526 #else
    527   const char md5_1[] = "b890950d4b9bc163b1a96797f3004b53";
    528   const char md5_2[] = "11487d5597599a26e8912b9c1d9422cb";
    529   const char md5_3[] = "bffe0ecea9a533f217047ee41d6be466";
    530 #endif
    531   {
    532     EXPECT_TRUE(OpenDocument("text_form.pdf"));
    533     FPDF_PAGE page = LoadPage(0);
    534     ASSERT_TRUE(page);
    535     std::unique_ptr<void, FPDFBitmapDeleter> bitmap1(RenderPage(page));
    536     CompareBitmap(bitmap1.get(), 300, 300, md5_1);
    537 
    538     // Click on the textfield
    539     EXPECT_EQ(FPDF_FORMFIELD_TEXTFIELD,
    540               FPDFPage_HasFormFieldAtPoint(form_handle(), page, 120.0, 120.0));
    541     FORM_OnMouseMove(form_handle(), page, 0, 120.0, 120.0);
    542     FORM_OnLButtonDown(form_handle(), page, 0, 120.0, 120.0);
    543     FORM_OnLButtonUp(form_handle(), page, 0, 120.0, 120.0);
    544 
    545     // Write "ABC"
    546     FORM_OnChar(form_handle(), page, 65, 0);
    547     FORM_OnChar(form_handle(), page, 66, 0);
    548     FORM_OnChar(form_handle(), page, 67, 0);
    549     std::unique_ptr<void, FPDFBitmapDeleter> bitmap2(RenderPage(page));
    550     CompareBitmap(bitmap2.get(), 300, 300, md5_2);
    551 
    552     // Take out focus by clicking out of the textfield
    553     FORM_OnMouseMove(form_handle(), page, 0, 15.0, 15.0);
    554     FORM_OnLButtonDown(form_handle(), page, 0, 15.0, 15.0);
    555     FORM_OnLButtonUp(form_handle(), page, 0, 15.0, 15.0);
    556     std::unique_ptr<void, FPDFBitmapDeleter> bitmap3(RenderPage(page));
    557     CompareBitmap(bitmap3.get(), 300, 300, md5_3);
    558 
    559     EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
    560 
    561     // Close page
    562     UnloadPage(page);
    563   }
    564   // Check saved document
    565   VerifySavedDocument(300, 300, md5_3);
    566 }
    567 
    568 TEST_F(FPDFFormFillEmbeddertest, HasFormInfoNone) {
    569   EXPECT_TRUE(OpenDocument("hello_world.pdf"));
    570   EXPECT_EQ(FORMTYPE_NONE, FPDF_GetFormType(document_));
    571 }
    572 
    573 TEST_F(FPDFFormFillEmbeddertest, HasFormInfoAcroForm) {
    574   EXPECT_TRUE(OpenDocument("text_form.pdf"));
    575   EXPECT_EQ(FORMTYPE_ACRO_FORM, FPDF_GetFormType(document_));
    576 }
    577 
    578 TEST_F(FPDFFormFillEmbeddertest, HasFormInfoXFAFull) {
    579   EXPECT_TRUE(OpenDocument("simple_xfa.pdf"));
    580   EXPECT_EQ(FORMTYPE_XFA_FULL, FPDF_GetFormType(document_));
    581 }
    582 
    583 TEST_F(FPDFFormFillEmbeddertest, HasFormInfoXFAForeground) {
    584   EXPECT_TRUE(OpenDocument("bug_216.pdf"));
    585   EXPECT_EQ(FORMTYPE_XFA_FOREGROUND, FPDF_GetFormType(document_));
    586 }
    587 
    588 TEST_F(FPDFFormFillTextFormEmbeddertest, GetSelectedTextEmptyAndBasicKeyboard) {
    589   // Test empty selection.
    590   CheckSelection(L"");
    591 
    592   // Test basic selection.
    593   TypeTextIntoTextField(3, RegularFormBegin());
    594   SelectTextWithKeyboard(3, FWL_VKEY_Left, RegularFormAtX(123.0));
    595   CheckSelection(L"ABC");
    596 }
    597 
    598 TEST_F(FPDFFormFillTextFormEmbeddertest, GetSelectedTextEmptyAndBasicMouse) {
    599   // Test empty selection.
    600   CheckSelection(L"");
    601 
    602   // Test basic selection.
    603   TypeTextIntoTextField(3, RegularFormBegin());
    604   SelectTextWithMouse(RegularFormAtX(125.0), RegularFormBegin());
    605   CheckSelection(L"ABC");
    606 }
    607 
    608 TEST_F(FPDFFormFillTextFormEmbeddertest, GetSelectedTextFragmentsKeyBoard) {
    609   TypeTextIntoTextField(12, RegularFormBegin());
    610 
    611   // Test selecting first character in forward direction.
    612   SelectTextWithKeyboard(1, FWL_VKEY_Right, RegularFormBegin());
    613   CheckSelection(L"A");
    614 
    615   // Test selecting entire long string in backwards direction.
    616   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
    617   CheckSelection(L"ABCDEFGHIJKL");
    618 
    619   // Test selecting middle section in backwards direction.
    620   SelectTextWithKeyboard(6, FWL_VKEY_Left, RegularFormAtX(170.0));
    621   CheckSelection(L"DEFGHI");
    622 
    623   // Test selecting middle selection in forward direction.
    624   SelectTextWithKeyboard(6, FWL_VKEY_Right, RegularFormAtX(125.0));
    625   CheckSelection(L"DEFGHI");
    626 
    627   // Test selecting last character in backwards direction.
    628   SelectTextWithKeyboard(1, FWL_VKEY_Left, RegularFormEnd());
    629   CheckSelection(L"L");
    630 }
    631 
    632 TEST_F(FPDFFormFillTextFormEmbeddertest, GetSelectedTextFragmentsMouse) {
    633   TypeTextIntoTextField(12, RegularFormBegin());
    634 
    635   // Test selecting first character in forward direction.
    636   SelectTextWithMouse(RegularFormBegin(), RegularFormAtX(106.0));
    637   CheckSelection(L"A");
    638 
    639   // Test selecting entire long string in backwards direction.
    640   SelectAllRegularFormTextWithMouse();
    641   CheckSelection(L"ABCDEFGHIJKL");
    642 
    643   // Test selecting middle section in backwards direction.
    644   SelectTextWithMouse(RegularFormAtX(170.0), RegularFormAtX(125.0));
    645   CheckSelection(L"DEFGHI");
    646 
    647   // Test selecting middle selection in forward direction.
    648   SelectTextWithMouse(RegularFormAtX(125.0), RegularFormAtX(170.0));
    649   CheckSelection(L"DEFGHI");
    650 
    651   // Test selecting last character in backwards direction.
    652   SelectTextWithMouse(RegularFormEnd(), RegularFormAtX(186.0));
    653   CheckSelection(L"L");
    654 }
    655 
    656 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
    657        GetSelectedTextEmptyAndBasicNormalComboBox) {
    658   // Test empty selection.
    659   CheckSelection(L"");
    660 
    661   // Non-editable comboboxes don't allow selection with keyboard.
    662   SelectTextWithMouse(NonEditableFormBegin(), NonEditableFormAtX(142.0));
    663   CheckSelection(L"Banana");
    664 
    665   // Select other another provided option.
    666   SelectNonEditableFormOption(0);
    667   CheckSelection(L"Apple");
    668 }
    669 
    670 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
    671        GetSelectedTextEmptyAndBasicEditableComboBoxKeyboard) {
    672   // Test empty selection.
    673   CheckSelection(L"");
    674 
    675   // Test basic selection of text within user editable combobox using keyboard.
    676   TypeTextIntoTextField(3, EditableFormBegin());
    677   SelectTextWithKeyboard(3, FWL_VKEY_Left, EditableFormAtX(128.0));
    678   CheckSelection(L"ABC");
    679 
    680   // Select a provided option.
    681   SelectEditableFormOption(1);
    682   CheckSelection(L"Bar");
    683 }
    684 
    685 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
    686        GetSelectedTextEmptyAndBasicEditableComboBoxMouse) {
    687   // Test empty selection.
    688   CheckSelection(L"");
    689 
    690   // Test basic selection of text within user editable combobox using mouse.
    691   TypeTextIntoTextField(3, EditableFormBegin());
    692   SelectTextWithMouse(EditableFormAtX(128.0), EditableFormBegin());
    693   CheckSelection(L"ABC");
    694 
    695   // Select a provided option.
    696   SelectEditableFormOption(2);
    697   CheckSelection(L"Qux");
    698 }
    699 
    700 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
    701        GetSelectedTextFragmentsNormalComboBox) {
    702   // Test selecting first character in forward direction.
    703   SelectTextWithMouse(NonEditableFormBegin(), NonEditableFormAtX(107.0));
    704   CheckSelection(L"B");
    705 
    706   // Test selecting entire string in backwards direction.
    707   SelectTextWithMouse(NonEditableFormAtX(142.0), NonEditableFormBegin());
    708   CheckSelection(L"Banana");
    709 
    710   // Test selecting middle section in backwards direction.
    711   SelectTextWithMouse(NonEditableFormAtX(135.0), NonEditableFormAtX(117.0));
    712   CheckSelection(L"nan");
    713 
    714   // Test selecting middle section in forward direction.
    715   SelectTextWithMouse(NonEditableFormAtX(117.0), NonEditableFormAtX(135.0));
    716   CheckSelection(L"nan");
    717 
    718   // Test selecting last character in backwards direction.
    719   SelectTextWithMouse(NonEditableFormAtX(142.0), NonEditableFormAtX(138.0));
    720   CheckSelection(L"a");
    721 
    722   // Select another option and then reset selection as first three chars.
    723   SelectNonEditableFormOption(2);
    724   CheckSelection(L"Cherry");
    725   SelectTextWithMouse(NonEditableFormBegin(), NonEditableFormAtX(122.0));
    726   CheckSelection(L"Che");
    727 }
    728 
    729 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
    730        GetSelectedTextFragmentsEditableComboBoxKeyboard) {
    731   TypeTextIntoTextField(10, EditableFormBegin());
    732 
    733   // Test selecting first character in forward direction.
    734   SelectTextWithKeyboard(1, FWL_VKEY_Right, EditableFormBegin());
    735   CheckSelection(L"A");
    736 
    737   // Test selecting entire long string in backwards direction.
    738   SelectTextWithKeyboard(10, FWL_VKEY_Left, EditableFormEnd());
    739   CheckSelection(L"ABCDEFGHIJ");
    740 
    741   // Test selecting middle section in backwards direction.
    742   SelectTextWithKeyboard(5, FWL_VKEY_Left, EditableFormAtX(168.0));
    743   CheckSelection(L"DEFGH");
    744 
    745   // Test selecting middle selection in forward direction.
    746   SelectTextWithKeyboard(5, FWL_VKEY_Right, EditableFormAtX(127.0));
    747   CheckSelection(L"DEFGH");
    748 
    749   // Test selecting last character in backwards direction.
    750   SelectTextWithKeyboard(1, FWL_VKEY_Left, EditableFormEnd());
    751   CheckSelection(L"J");
    752 
    753   // Select a provided option and then reset selection as first two chars.
    754   SelectEditableFormOption(0);
    755   CheckSelection(L"Foo");
    756   SelectTextWithKeyboard(2, FWL_VKEY_Right, EditableFormBegin());
    757   CheckSelection(L"Fo");
    758 }
    759 
    760 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
    761        GetSelectedTextFragmentsEditableComboBoxMouse) {
    762   TypeTextIntoTextField(10, EditableFormBegin());
    763 
    764   // Test selecting first character in forward direction.
    765   SelectTextWithMouse(EditableFormBegin(), EditableFormAtX(107.0));
    766   CheckSelection(L"A");
    767 
    768   // Test selecting entire long string in backwards direction.
    769   SelectAllEditableFormTextWithMouse();
    770   CheckSelection(L"ABCDEFGHIJ");
    771 
    772   // Test selecting middle section in backwards direction.
    773   SelectTextWithMouse(EditableFormAtX(168.0), EditableFormAtX(127.0));
    774   CheckSelection(L"DEFGH");
    775 
    776   // Test selecting middle selection in forward direction.
    777   SelectTextWithMouse(EditableFormAtX(127.0), EditableFormAtX(168.0));
    778   CheckSelection(L"DEFGH");
    779 
    780   // Test selecting last character in backwards direction.
    781   SelectTextWithMouse(EditableFormEnd(), EditableFormAtX(174.0));
    782   CheckSelection(L"J");
    783 }
    784 
    785 TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteTextFieldEntireSelection) {
    786   // Select entire contents of text field.
    787   TypeTextIntoTextField(12, RegularFormBegin());
    788   SelectAllRegularFormTextWithMouse();
    789   CheckSelection(L"ABCDEFGHIJKL");
    790 
    791   // Test deleting current text selection. Select what remains after deletion to
    792   // check that remaining text is as expected.
    793   FORM_ReplaceSelection(form_handle(), page(), nullptr);
    794 
    795   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
    796   CheckSelection(L"");
    797 }
    798 
    799 TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteTextFieldSelectionMiddle) {
    800   // Select middle section of text.
    801   TypeTextIntoTextField(12, RegularFormBegin());
    802   SelectTextWithMouse(RegularFormAtX(170.0), RegularFormAtX(125.0));
    803   CheckSelection(L"DEFGHI");
    804 
    805   // Test deleting current text selection. Select what remains after deletion to
    806   // check that remaining text is as expected.
    807   FORM_ReplaceSelection(form_handle(), page(), nullptr);
    808   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
    809   CheckSelection(L"ABCJKL");
    810 }
    811 
    812 TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteTextFieldSelectionLeft) {
    813   // Select first few characters of text.
    814   TypeTextIntoTextField(12, RegularFormBegin());
    815   SelectTextWithMouse(RegularFormBegin(), RegularFormAtX(132.0));
    816   CheckSelection(L"ABCD");
    817 
    818   // Test deleting current text selection. Select what remains after deletion to
    819   // check that remaining text is as expected.
    820   FORM_ReplaceSelection(form_handle(), page(), nullptr);
    821   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
    822   CheckSelection(L"EFGHIJKL");
    823 }
    824 
    825 TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteTextFieldSelectionRight) {
    826   // Select last few characters of text.
    827   TypeTextIntoTextField(12, RegularFormBegin());
    828   SelectTextWithMouse(RegularFormEnd(), RegularFormAtX(165.0));
    829   CheckSelection(L"IJKL");
    830 
    831   // Test deleting current text selection. Select what remains after deletion to
    832   // check that remaining text is as expected.
    833   FORM_ReplaceSelection(form_handle(), page(), nullptr);
    834   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
    835   CheckSelection(L"ABCDEFGH");
    836 }
    837 
    838 TEST_F(FPDFFormFillTextFormEmbeddertest, DeleteEmptyTextFieldSelection) {
    839   // Do not select text.
    840   TypeTextIntoTextField(12, RegularFormBegin());
    841   CheckSelection(L"");
    842 
    843   // Test that attempt to delete empty text selection has no effect.
    844   FORM_ReplaceSelection(form_handle(), page(), nullptr);
    845   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
    846   CheckSelection(L"ABCDEFGHIJKL");
    847 }
    848 
    849 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
    850        DeleteEditableComboBoxEntireSelection) {
    851   // Select entire contents of user-editable combobox text field.
    852   TypeTextIntoTextField(10, EditableFormBegin());
    853   SelectAllEditableFormTextWithMouse();
    854   CheckSelection(L"ABCDEFGHIJ");
    855 
    856   // Test deleting current text selection. Select what remains after deletion to
    857   // check that remaining text is as expected.
    858   FORM_ReplaceSelection(form_handle(), page(), nullptr);
    859   SelectAllEditableFormTextWithMouse();
    860   CheckSelection(L"");
    861 }
    862 
    863 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
    864        DeleteEditableComboBoxSelectionMiddle) {
    865   // Select middle section of text.
    866   TypeTextIntoTextField(10, EditableFormBegin());
    867   SelectTextWithMouse(EditableFormAtX(168.0), EditableFormAtX(127.0));
    868   CheckSelection(L"DEFGH");
    869 
    870   // Test deleting current text selection. Select what remains after deletion to
    871   // check that remaining text is as expected.
    872   FORM_ReplaceSelection(form_handle(), page(), nullptr);
    873   SelectAllEditableFormTextWithMouse();
    874   CheckSelection(L"ABCIJ");
    875 }
    876 
    877 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
    878        DeleteEditableComboBoxSelectionLeft) {
    879   // Select first few characters of text.
    880   TypeTextIntoTextField(10, EditableFormBegin());
    881   SelectTextWithMouse(EditableFormBegin(), EditableFormAtX(132.0));
    882   CheckSelection(L"ABCD");
    883 
    884   // Test deleting current text selection. Select what remains after deletion to
    885   // check that remaining text is as expected.
    886   FORM_ReplaceSelection(form_handle(), page(), nullptr);
    887   SelectAllEditableFormTextWithMouse();
    888   CheckSelection(L"EFGHIJ");
    889 }
    890 
    891 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
    892        DeleteEditableComboBoxSelectionRight) {
    893   // Select last few characters of text.
    894   TypeTextIntoTextField(10, EditableFormBegin());
    895   SelectTextWithMouse(EditableFormEnd(), EditableFormAtX(152.0));
    896   CheckSelection(L"GHIJ");
    897 
    898   // Test deleting current text selection. Select what remains after deletion to
    899   // check that remaining text is as expected.
    900   FORM_ReplaceSelection(form_handle(), page(), nullptr);
    901   SelectAllEditableFormTextWithMouse();
    902   CheckSelection(L"ABCDEF");
    903 }
    904 
    905 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
    906        DeleteEmptyEditableComboBoxSelection) {
    907   // Do not select text.
    908   TypeTextIntoTextField(10, EditableFormBegin());
    909   CheckSelection(L"");
    910 
    911   // Test that attempt to delete empty text selection has no effect.
    912   FORM_ReplaceSelection(form_handle(), page(), nullptr);
    913   SelectAllEditableFormTextWithMouse();
    914   CheckSelection(L"ABCDEFGHIJ");
    915 }
    916 
    917 TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInEmptyTextField) {
    918   ClickOnFormFieldAtPoint(RegularFormBegin());
    919 
    920   // Test inserting text into empty text field.
    921   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
    922       GetFPDFWideString(L"Hello");
    923   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
    924 
    925   // Select entire contents of text field to check that insertion worked
    926   // as expected.
    927   SelectAllRegularFormTextWithMouse();
    928   CheckSelection(L"Hello");
    929 }
    930 
    931 TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInPopulatedTextFieldLeft) {
    932   TypeTextIntoTextField(8, RegularFormBegin());
    933 
    934   // Click on the leftmost part of the text field.
    935   ClickOnFormFieldAtPoint(RegularFormBegin());
    936 
    937   // Test inserting text in front of existing text in text field.
    938   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
    939       GetFPDFWideString(L"Hello");
    940   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
    941 
    942   // Select entire contents of text field to check that insertion worked
    943   // as expected.
    944   SelectAllRegularFormTextWithMouse();
    945   CheckSelection(L"HelloABCDEFGH");
    946 }
    947 
    948 TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInPopulatedTextFieldMiddle) {
    949   TypeTextIntoTextField(8, RegularFormBegin());
    950 
    951   // Click on the middle of the text field.
    952   ClickOnFormFieldAtPoint(RegularFormAtX(134.0));
    953 
    954   // Test inserting text in the middle of existing text in text field.
    955   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
    956       GetFPDFWideString(L"Hello");
    957   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
    958 
    959   // Select entire contents of text field to check that insertion worked
    960   // as expected.
    961   SelectAllRegularFormTextWithMouse();
    962   CheckSelection(L"ABCDHelloEFGH");
    963 }
    964 
    965 TEST_F(FPDFFormFillTextFormEmbeddertest, InsertTextInPopulatedTextFieldRight) {
    966   TypeTextIntoTextField(8, RegularFormBegin());
    967 
    968   // Click on the rightmost part of the text field.
    969   ClickOnFormFieldAtPoint(RegularFormAtX(166.0));
    970 
    971   // Test inserting text behind existing text in text field.
    972   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
    973       GetFPDFWideString(L"Hello");
    974   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
    975 
    976   // Select entire contents of text field to check that insertion worked
    977   // as expected.
    978   SelectAllRegularFormTextWithMouse();
    979   CheckSelection(L"ABCDEFGHHello");
    980 }
    981 
    982 TEST_F(FPDFFormFillTextFormEmbeddertest,
    983        InsertTextAndReplaceSelectionInPopulatedTextFieldWhole) {
    984   TypeTextIntoTextField(12, RegularFormBegin());
    985 
    986   // Select entire string in text field.
    987   SelectTextWithKeyboard(12, FWL_VKEY_Left, RegularFormEnd());
    988   CheckSelection(L"ABCDEFGHIJKL");
    989 
    990   // Test replacing text selection with text to be inserted.
    991   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
    992       GetFPDFWideString(L"Hello");
    993   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
    994 
    995   // Select entire contents of text field to check that insertion worked
    996   // as expected.
    997   SelectAllRegularFormTextWithMouse();
    998   CheckSelection(L"Hello");
    999 }
   1000 
   1001 TEST_F(FPDFFormFillTextFormEmbeddertest,
   1002        InsertTextAndReplaceSelectionInPopulatedTextFieldLeft) {
   1003   TypeTextIntoTextField(12, RegularFormBegin());
   1004 
   1005   // Select left portion of string in text field.
   1006   SelectTextWithKeyboard(6, FWL_VKEY_Left, RegularFormAtX(148.0));
   1007   CheckSelection(L"ABCDEF");
   1008 
   1009   // Test replacing text selection with text to be inserted.
   1010   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1011       GetFPDFWideString(L"Hello");
   1012   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1013 
   1014   // Select entire contents of text field to check that insertion worked
   1015   // as expected.
   1016   SelectAllRegularFormTextWithMouse();
   1017   CheckSelection(L"HelloGHIJKL");
   1018 }
   1019 
   1020 TEST_F(FPDFFormFillTextFormEmbeddertest,
   1021        InsertTextAndReplaceSelectionInPopulatedTextFieldMiddle) {
   1022   TypeTextIntoTextField(12, RegularFormBegin());
   1023 
   1024   // Select middle portion of string in text field.
   1025   SelectTextWithKeyboard(6, FWL_VKEY_Left, RegularFormAtX(171.0));
   1026   CheckSelection(L"DEFGHI");
   1027 
   1028   // Test replacing text selection with text to be inserted.
   1029   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1030       GetFPDFWideString(L"Hello");
   1031   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1032 
   1033   // Select entire contents of text field to check that insertion worked
   1034   // as expected.
   1035   SelectAllRegularFormTextWithMouse();
   1036   CheckSelection(L"ABCHelloJKL");
   1037 }
   1038 
   1039 TEST_F(FPDFFormFillTextFormEmbeddertest,
   1040        InsertTextAndReplaceSelectionInPopulatedTextFieldRight) {
   1041   TypeTextIntoTextField(12, RegularFormBegin());
   1042 
   1043   // Select right portion of string in text field.
   1044   SelectTextWithKeyboard(6, FWL_VKEY_Left, RegularFormEnd());
   1045   CheckSelection(L"GHIJKL");
   1046 
   1047   // Test replacing text selection with text to be inserted.
   1048   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1049       GetFPDFWideString(L"Hello");
   1050   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1051 
   1052   // Select entire contents of text field to check that insertion worked
   1053   // as expected.
   1054   SelectAllRegularFormTextWithMouse();
   1055   CheckSelection(L"ABCDEFHello");
   1056 }
   1057 
   1058 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
   1059        InsertTextInEmptyEditableComboBox) {
   1060   ClickOnFormFieldAtPoint(EditableFormBegin());
   1061 
   1062   // Test inserting text into empty user-editable combobox.
   1063   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1064       GetFPDFWideString(L"Hello");
   1065   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1066 
   1067   // Select entire contents of user-editable combobox text field to check that
   1068   // insertion worked as expected.
   1069   SelectAllEditableFormTextWithMouse();
   1070   CheckSelection(L"Hello");
   1071 }
   1072 
   1073 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
   1074        InsertTextInPopulatedEditableComboBoxLeft) {
   1075   TypeTextIntoTextField(6, EditableFormBegin());
   1076 
   1077   // Click on the leftmost part of the user-editable combobox.
   1078   ClickOnFormFieldAtPoint(EditableFormBegin());
   1079 
   1080   // Test inserting text in front of existing text in user-editable combobox.
   1081   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1082       GetFPDFWideString(L"Hello");
   1083   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1084 
   1085   // Select entire contents of user-editable combobox text field to check that
   1086   // insertion worked as expected.
   1087   SelectAllEditableFormTextWithMouse();
   1088   CheckSelection(L"HelloABCDEF");
   1089 }
   1090 
   1091 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
   1092        InsertTextInPopulatedEditableComboBoxMiddle) {
   1093   TypeTextIntoTextField(6, EditableFormBegin());
   1094 
   1095   // Click on the middle of the user-editable combobox.
   1096   ClickOnFormFieldAtPoint(EditableFormAtX(126.0));
   1097 
   1098   // Test inserting text in the middle of existing text in user-editable
   1099   // combobox.
   1100   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1101       GetFPDFWideString(L"Hello");
   1102   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1103 
   1104   // Select entire contents of user-editable combobox text field to check that
   1105   // insertion worked as expected.
   1106   SelectAllEditableFormTextWithMouse();
   1107   CheckSelection(L"ABCHelloDEF");
   1108 }
   1109 
   1110 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
   1111        InsertTextInPopulatedEditableComboBoxRight) {
   1112   TypeTextIntoTextField(6, EditableFormBegin());
   1113 
   1114   // Click on the rightmost part of the user-editable combobox.
   1115   ClickOnFormFieldAtPoint(EditableFormEnd());
   1116 
   1117   // Test inserting text behind existing text in user-editable combobox.
   1118   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1119       GetFPDFWideString(L"Hello");
   1120   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1121 
   1122   // Select entire contents of user-editable combobox text field to check that
   1123   // insertion worked as expected.
   1124   SelectAllEditableFormTextWithMouse();
   1125   CheckSelection(L"ABCDEFHello");
   1126 }
   1127 
   1128 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
   1129        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxWhole) {
   1130   TypeTextIntoTextField(10, EditableFormBegin());
   1131 
   1132   // Select entire string in user-editable combobox.
   1133   SelectTextWithKeyboard(10, FWL_VKEY_Left, EditableFormEnd());
   1134   CheckSelection(L"ABCDEFGHIJ");
   1135 
   1136   // Test replacing text selection with text to be inserted.
   1137   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1138       GetFPDFWideString(L"Hello");
   1139   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1140 
   1141   // Select entire contents of user-editable combobox text field to check that
   1142   // insertion worked as expected.
   1143   SelectAllEditableFormTextWithMouse();
   1144   CheckSelection(L"Hello");
   1145 }
   1146 
   1147 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
   1148        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxLeft) {
   1149   TypeTextIntoTextField(10, EditableFormBegin());
   1150 
   1151   // Select left portion of string in user-editable combobox.
   1152   SelectTextWithKeyboard(5, FWL_VKEY_Left, EditableFormAtX(142.0));
   1153   CheckSelection(L"ABCDE");
   1154 
   1155   // Test replacing text selection with text to be inserted.
   1156   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1157       GetFPDFWideString(L"Hello");
   1158   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1159 
   1160   // Select entire contents of user-editable combobox text field to check that
   1161   // insertion worked as expected.
   1162   SelectAllEditableFormTextWithMouse();
   1163   CheckSelection(L"HelloFGHIJ");
   1164 }
   1165 
   1166 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
   1167        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxMiddle) {
   1168   TypeTextIntoTextField(10, EditableFormBegin());
   1169 
   1170   // Select middle portion of string in user-editable combobox.
   1171   SelectTextWithKeyboard(5, FWL_VKEY_Left, EditableFormAtX(167.0));
   1172   CheckSelection(L"DEFGH");
   1173 
   1174   // Test replacing text selection with text to be inserted.
   1175   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1176       GetFPDFWideString(L"Hello");
   1177   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1178 
   1179   // Select entire contents of user-editable combobox text field to check that
   1180   // insertion worked as expected.
   1181   SelectAllEditableFormTextWithMouse();
   1182   CheckSelection(L"ABCHelloIJ");
   1183 }
   1184 
   1185 TEST_F(FPDFFormFillComboBoxFormEmbeddertest,
   1186        InsertTextAndReplaceSelectionInPopulatedEditableComboBoxRight) {
   1187   TypeTextIntoTextField(10, EditableFormBegin());
   1188 
   1189   // Select right portion of string in user-editable combobox.
   1190   SelectTextWithKeyboard(5, FWL_VKEY_Left, EditableFormEnd());
   1191   CheckSelection(L"FGHIJ");
   1192 
   1193   // Test replacing text selection with text to be inserted.
   1194   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1195       GetFPDFWideString(L"Hello");
   1196   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1197 
   1198   // Select entire contents of user-editable combobox text field to check that
   1199   // insertion worked as expected.
   1200   SelectAllEditableFormTextWithMouse();
   1201   CheckSelection(L"ABCDEHello");
   1202 }
   1203 
   1204 TEST_F(FPDFFormFillTextFormEmbeddertest,
   1205        InsertTextInEmptyCharLimitTextFieldOverflow) {
   1206   // Click on the textfield.
   1207   ClickOnFormFieldAtPoint(CharLimitFormEnd());
   1208 
   1209   // Delete pre-filled contents of text field with char limit.
   1210   SelectAllCharLimitFormTextWithMouse();
   1211   CheckSelection(L"Elephant");
   1212   FORM_ReplaceSelection(form_handle(), page(), nullptr);
   1213 
   1214   // Test inserting text into now empty text field so text to be inserted
   1215   // exceeds the char limit and is cut off.
   1216   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1217       GetFPDFWideString(L"Hippopotamus");
   1218   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1219 
   1220   // Select entire contents of text field to check that insertion worked
   1221   // as expected.
   1222   SelectAllCharLimitFormTextWithMouse();
   1223   CheckSelection(L"Hippopotam");
   1224 }
   1225 
   1226 TEST_F(FPDFFormFillTextFormEmbeddertest,
   1227        InsertTextInEmptyCharLimitTextFieldFit) {
   1228   // Click on the textfield.
   1229   ClickOnFormFieldAtPoint(CharLimitFormEnd());
   1230 
   1231   // Delete pre-filled contents of text field with char limit.
   1232   SelectAllCharLimitFormTextWithMouse();
   1233   CheckSelection(L"Elephant");
   1234   FORM_ReplaceSelection(form_handle(), page(), nullptr);
   1235 
   1236   // Test inserting text into now empty text field so text to be inserted
   1237   // exceeds the char limit and is cut off.
   1238   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1239       GetFPDFWideString(L"Zebra");
   1240   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1241 
   1242   // Select entire contents of text field to check that insertion worked
   1243   // as expected.
   1244   SelectAllCharLimitFormTextWithMouse();
   1245   CheckSelection(L"Zebra");
   1246 }
   1247 
   1248 TEST_F(FPDFFormFillTextFormEmbeddertest,
   1249        InsertTextInPopulatedCharLimitTextFieldLeft) {
   1250   // Click on the leftmost part of the text field.
   1251   ClickOnFormFieldAtPoint(CharLimitFormBegin());
   1252 
   1253   // Test inserting text in front of existing text in text field.
   1254   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1255       GetFPDFWideString(L"Hippopotamus");
   1256   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1257 
   1258   // Select entire contents of text field to check that insertion worked
   1259   // as expected.
   1260   SelectAllCharLimitFormTextWithMouse();
   1261   CheckSelection(L"HiElephant");
   1262 }
   1263 
   1264 TEST_F(FPDFFormFillTextFormEmbeddertest,
   1265        InsertTextInPopulatedCharLimitTextFieldMiddle) {
   1266   TypeTextIntoTextField(8, RegularFormBegin());
   1267 
   1268   // Click on the middle of the text field.
   1269   ClickOnFormFieldAtPoint(CharLimitFormAtX(134.0));
   1270 
   1271   // Test inserting text in the middle of existing text in text field.
   1272   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1273       GetFPDFWideString(L"Hippopotamus");
   1274   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1275 
   1276   // Select entire contents of text field to check that insertion worked
   1277   // as expected.
   1278   SelectAllCharLimitFormTextWithMouse();
   1279   CheckSelection(L"ElephHiant");
   1280 }
   1281 
   1282 TEST_F(FPDFFormFillTextFormEmbeddertest,
   1283        InsertTextInPopulatedCharLimitTextFieldRight) {
   1284   TypeTextIntoTextField(8, RegularFormBegin());
   1285 
   1286   // Click on the rightmost part of the text field.
   1287   ClickOnFormFieldAtPoint(CharLimitFormAtX(166.0));
   1288 
   1289   // Test inserting text behind existing text in text field.
   1290   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1291       GetFPDFWideString(L"Hippopotamus");
   1292   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1293 
   1294   // Select entire contents of text field to check that insertion worked
   1295   // as expected.
   1296   SelectAllCharLimitFormTextWithMouse();
   1297   CheckSelection(L"ElephantHi");
   1298 }
   1299 
   1300 TEST_F(FPDFFormFillTextFormEmbeddertest,
   1301        InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldWhole) {
   1302   TypeTextIntoTextField(12, RegularFormBegin());
   1303 
   1304   // Select entire string in text field.
   1305   SelectTextWithKeyboard(12, FWL_VKEY_Left, CharLimitFormEnd());
   1306   CheckSelection(L"Elephant");
   1307 
   1308   // Test replacing text selection with text to be inserted.
   1309   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1310       GetFPDFWideString(L"Hippopotamus");
   1311   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1312 
   1313   // Select entire contents of text field to check that insertion worked
   1314   // as expected.
   1315   SelectAllCharLimitFormTextWithMouse();
   1316   CheckSelection(L"Hippopotam");
   1317 }
   1318 
   1319 TEST_F(FPDFFormFillTextFormEmbeddertest,
   1320        InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldLeft) {
   1321   TypeTextIntoTextField(12, RegularFormBegin());
   1322 
   1323   // Select left portion of string in text field.
   1324   SelectTextWithKeyboard(4, FWL_VKEY_Left, CharLimitFormAtX(122.0));
   1325   CheckSelection(L"Elep");
   1326 
   1327   // Test replacing text selection with text to be inserted.
   1328   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1329       GetFPDFWideString(L"Hippopotamus");
   1330   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1331 
   1332   // Select entire contents of text field to check that insertion worked
   1333   // as expected.
   1334   SelectAllCharLimitFormTextWithMouse();
   1335   CheckSelection(L"Hippophant");
   1336 }
   1337 
   1338 TEST_F(FPDFFormFillTextFormEmbeddertest,
   1339        InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldMiddle) {
   1340   TypeTextIntoTextField(12, RegularFormBegin());
   1341 
   1342   // Select middle portion of string in text field.
   1343   SelectTextWithKeyboard(4, FWL_VKEY_Left, CharLimitFormAtX(136.0));
   1344   CheckSelection(L"epha");
   1345 
   1346   // Test replacing text selection with text to be inserted.
   1347   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1348       GetFPDFWideString(L"Hippopotamus");
   1349   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1350 
   1351   // Select entire contents of text field to check that insertion worked
   1352   // as expected.
   1353   SelectAllCharLimitFormTextWithMouse();
   1354   CheckSelection(L"ElHippopnt");
   1355 }
   1356 
   1357 TEST_F(FPDFFormFillTextFormEmbeddertest,
   1358        InsertTextAndReplaceSelectionInPopulatedCharLimitTextFieldRight) {
   1359   TypeTextIntoTextField(12, RegularFormBegin());
   1360 
   1361   // Select right portion of string in text field.
   1362   SelectTextWithKeyboard(4, FWL_VKEY_Left, CharLimitFormAtX(152.0));
   1363   CheckSelection(L"hant");
   1364 
   1365   // Test replacing text selection with text to be inserted.
   1366   std::unique_ptr<unsigned short, pdfium::FreeDeleter> text_to_insert =
   1367       GetFPDFWideString(L"Hippopotamus");
   1368   FORM_ReplaceSelection(form_handle(), page(), text_to_insert.get());
   1369 
   1370   // Select entire contents of text field to check that insertion worked
   1371   // as expected.
   1372   SelectAllCharLimitFormTextWithMouse();
   1373   CheckSelection(L"ElepHippop");
   1374 }
   1375