Add embedder tests for form combobox text selection.

These tests verify that CPWL_ComboBox::GetSelectedText() and
FORM_GetSelectedText() behave as expected when selecting text in form
combobox textfields. Text can be selected in both regular comboboxes and
user-editable comboboxes.

BUG=chromium:59266

Change-Id: I1a5e48baf8aa767283dc478b0872877a52c5b869
Reviewed-on: https://pdfium-review.googlesource.com/6971
Commit-Queue: Diana Gage <drgage@google.com>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: dsinclair <dsinclair@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 34b032f..83bad1b 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -2014,6 +2014,7 @@
     "fpdfsdk/fpdfview_c_api_test.h",
     "fpdfsdk/fpdfview_embeddertest.cpp",
     "fpdfsdk/fsdk_baseform_embeddertest.cpp",
+    "fpdfsdk/pdfwindow/cpwl_combo_box_embeddertest.cpp",
     "fpdfsdk/pdfwindow/cpwl_edit_embeddertest.cpp",
     "testing/embedder_test.cpp",
     "testing/embedder_test.h",
diff --git a/fpdfsdk/fpdfformfill_embeddertest.cpp b/fpdfsdk/fpdfformfill_embeddertest.cpp
index f3043983..7779ed2 100644
--- a/fpdfsdk/fpdfformfill_embeddertest.cpp
+++ b/fpdfsdk/fpdfformfill_embeddertest.cpp
@@ -22,13 +22,21 @@
 
 class FPDFFormFillEmbeddertest : public EmbedderTest, public TestSaver {
  protected:
-  void TypeTextIntoTextfield(FPDF_PAGE page, int num_chars) {
-    // Click on the textfield in text_form.pdf.
-    EXPECT_EQ(FPDF_FORMFIELD_TEXTFIELD,
-              FPDFPage_HasFormFieldAtPoint(form_handle(), page, 120.0, 120.0));
-    FORM_OnMouseMove(form_handle(), page, 0, 120.0, 120.0);
-    FORM_OnLButtonDown(form_handle(), page, 0, 120.0, 120.0);
-    FORM_OnLButtonUp(form_handle(), page, 0, 120.0, 120.0);
+  void TypeTextIntoTextfield(FPDF_PAGE page,
+                             int num_chars,
+                             int form_type,
+                             double x,
+                             double y) {
+    ASSERT(form_type == FPDF_FORMFIELD_COMBOBOX ||
+           form_type == FPDF_FORMFIELD_TEXTFIELD);
+    EXPECT_EQ(form_type,
+              FPDFPage_HasFormFieldAtPoint(form_handle(), page, x, y));
+
+    // Click on the textfield or combobox text field as specified by
+    // coordinates.
+    FORM_OnMouseMove(form_handle(), page, 0, x, y);
+    FORM_OnLButtonDown(form_handle(), page, 0, x, y);
+    FORM_OnLButtonUp(form_handle(), page, 0, x, y);
 
     // Type text starting with 'A' to as many chars as specified by |num_chars|.
     for (int i = 0; i < num_chars; ++i) {
@@ -36,7 +44,7 @@
     }
   }
 
-  // Navigates to form text field using the mouse and then selects text via the
+  // Navigates to text field using the mouse and then selects text via the
   // shift and specfied left or right arrow key.
   void SelectTextWithKeyboard(FPDF_PAGE page,
                               int num_chars,
@@ -59,7 +67,7 @@
     FORM_OnKeyUp(form_handle(), page, FWL_VKEY_Shift, 0);
   }
 
-  // Uses the mouse to navigate to form text field and select text.
+  // Uses the mouse to navigate to text field and select text.
   void SelectTextWithMouse(FPDF_PAGE page,
                            double start_x,
                            double end_x,
@@ -91,6 +99,29 @@
     EXPECT_EQ(expected_string,
               CFX_WideString::FromUTF16LE(buf.data(), num_chars));
   }
+
+  // Selects one of the pre-selected values from a combobox with three options.
+  // Options are specified by |item_index|, which is 0-based.
+  void SelectOption(FPDF_PAGE page, int32_t item_index, double x, double y) {
+    // Only relevant for comboboxes with three choices and the same dimensions
+    // as those in combobox_form.pdf.
+    ASSERT(item_index >= 0);
+    ASSERT(item_index < 3);
+
+    // Navigate to button for drop down and click mouse to reveal options.
+    FORM_OnMouseMove(form_handle(), page, 0, x, y);
+    FORM_OnLButtonDown(form_handle(), page, 0, x, y);
+    FORM_OnLButtonUp(form_handle(), page, 0, x, y);
+
+    // Y coordinate of dropdown option to be selected.
+    constexpr double kChoiceHeight = 15;
+    double option_y = y - kChoiceHeight * (item_index + 1);
+
+    // Navigate to option and click mouse to select it.
+    FORM_OnMouseMove(form_handle(), page, 0, x, option_y);
+    FORM_OnLButtonDown(form_handle(), page, 0, x, option_y);
+    FORM_OnLButtonUp(form_handle(), page, 0, x, option_y);
+  }
 };
 
 TEST_F(FPDFFormFillEmbeddertest, FirstTest) {
@@ -367,7 +398,7 @@
   CheckSelection(page, CFX_WideString(L""));
 
   // Test basic selection.
-  TypeTextIntoTextfield(page, 3);
+  TypeTextIntoTextfield(page, 3, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
   SelectTextWithKeyboard(page, 3, FWL_VKEY_Left, 123.0, 115.5);
   CheckSelection(page, CFX_WideString(L"ABC"));
 
@@ -384,7 +415,7 @@
   CheckSelection(page, CFX_WideString(L""));
 
   // Test basic selection.
-  TypeTextIntoTextfield(page, 3);
+  TypeTextIntoTextfield(page, 3, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
   SelectTextWithMouse(page, 125.0, 102.0, 115.5);
   CheckSelection(page, CFX_WideString(L"ABC"));
 
@@ -397,10 +428,9 @@
   FPDF_PAGE page = LoadPage(0);
   ASSERT_TRUE(page);
 
-  TypeTextIntoTextfield(page, 12);
+  TypeTextIntoTextfield(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
 
   // Test selecting first character in forward direction.
-  // Navigate to starting position and click mouse.
   SelectTextWithKeyboard(page, 1, FWL_VKEY_Right, 102.0, 115.5);
   CheckSelection(page, CFX_WideString(L"A"));
 
@@ -429,7 +459,7 @@
   FPDF_PAGE page = LoadPage(0);
   ASSERT_TRUE(page);
 
-  TypeTextIntoTextfield(page, 12);
+  TypeTextIntoTextfield(page, 12, FPDF_FORMFIELD_TEXTFIELD, 120.0, 120.0);
 
   // Test selecting first character in forward direction.
   SelectTextWithMouse(page, 102.0, 106.0, 115.5);
@@ -453,3 +483,181 @@
 
   UnloadPage(page);
 }
+
+TEST_F(FPDFFormFillEmbeddertest, GetSelectedTextEmptyAndBasicNormalComboBox) {
+  // Open file with form comboboxes.
+  EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  ASSERT_TRUE(page);
+
+  // Test empty selection.
+  CheckSelection(page, CFX_WideString(L""));
+
+  // Test basic selection of text within normal, non-editable combobox.
+  // Click on normal combobox text field.
+  EXPECT_EQ(FPDF_FORMFIELD_COMBOBOX,
+            FPDFPage_HasFormFieldAtPoint(form_handle(), page, 102.0, 113.0));
+
+  // Non-editable comboboxes don't allow selection with keyboard.
+  SelectTextWithMouse(page, 102.0, 142.0, 113.0);
+  CheckSelection(page, CFX_WideString(L"Banana"));
+
+  // Select other another provided option.
+  SelectOption(page, 0, 192.0, 110.0);
+  CheckSelection(page, CFX_WideString(L"Apple"));
+
+  UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+       GetSelectedTextEmptyAndBasicEditableComboBoxKeyboard) {
+  // Open file with form comboboxes.
+  EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  ASSERT_TRUE(page);
+
+  // Test empty selection.
+  CheckSelection(page, CFX_WideString(L""));
+
+  // Test basic selection of text within user editable combobox using keyboard.
+  TypeTextIntoTextfield(page, 3, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+  SelectTextWithKeyboard(page, 3, FWL_VKEY_Left, 128.0, 63.0);
+  CheckSelection(page, CFX_WideString(L"ABC"));
+
+  // Select a provided option.
+  SelectOption(page, 1, 192.0, 60.0);
+  CheckSelection(page, CFX_WideString(L"Bar"));
+
+  UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+       GetSelectedTextEmptyAndBasicEditableComboBoxMouse) {
+  // Open file with form comboboxes.
+  EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  ASSERT_TRUE(page);
+
+  // Test empty selection.
+  CheckSelection(page, CFX_WideString(L""));
+
+  // Test basic selection of text within user editable combobox using mouse.
+  TypeTextIntoTextfield(page, 3, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+  SelectTextWithMouse(page, 128.0, 103.0, 63.0);
+  CheckSelection(page, CFX_WideString(L"ABC"));
+
+  // Select a provided option.
+  SelectOption(page, 2, 192.0, 60.0);
+  CheckSelection(page, CFX_WideString(L"Qux"));
+
+  UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest, GetSelectedTextFragmentsNormalComboBox) {
+  // Open file with form comboboxes.
+  EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  ASSERT_TRUE(page);
+
+  // Click on normal combobox text field.
+  EXPECT_EQ(FPDF_FORMFIELD_COMBOBOX,
+            FPDFPage_HasFormFieldAtPoint(form_handle(), page, 102.0, 113.0));
+
+  // Test selecting first character in forward direction.
+  SelectTextWithMouse(page, 102.0, 107.0, 113.0);
+  CheckSelection(page, CFX_WideString(L"B"));
+
+  // Test selecting entire string in backwards direction.
+  SelectTextWithMouse(page, 142.0, 102.0, 113.0);
+  CheckSelection(page, CFX_WideString(L"Banana"));
+
+  // Test selecting middle section in backwards direction.
+  SelectTextWithMouse(page, 135.0, 117.0, 113.0);
+  CheckSelection(page, CFX_WideString(L"nan"));
+
+  // Test selecting middle section in forward direction.
+  SelectTextWithMouse(page, 117.0, 135.0, 113.0);
+  CheckSelection(page, CFX_WideString(L"nan"));
+
+  // Test selecting last character in backwards direction.
+  SelectTextWithMouse(page, 142.0, 138.0, 113.0);
+  CheckSelection(page, CFX_WideString(L"a"));
+
+  // Select another option and then reset selection as first three chars.
+  SelectOption(page, 2, 192.0, 110.0);
+  CheckSelection(page, CFX_WideString(L"Cherry"));
+  SelectTextWithMouse(page, 102.0, 122.0, 113.0);
+  CheckSelection(page, CFX_WideString(L"Che"));
+
+  UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+       GetSelectedTextFragmentsEditableComboBoxKeyboard) {
+  // Open file with form comboboxes.
+  EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  ASSERT_TRUE(page);
+
+  TypeTextIntoTextfield(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+
+  // Test selecting first character in forward direction.
+  SelectTextWithKeyboard(page, 1, FWL_VKEY_Right, 102.0, 63.0);
+  CheckSelection(page, CFX_WideString(L"A"));
+
+  // Test selecting entire long string in backwards direction.
+  SelectTextWithKeyboard(page, 10, FWL_VKEY_Left, 178.0, 63.0);
+  CheckSelection(page, CFX_WideString(L"ABCDEFGHIJ"));
+
+  // Test selecting middle section in backwards direction.
+  SelectTextWithKeyboard(page, 5, FWL_VKEY_Left, 168.0, 63.0);
+  CheckSelection(page, CFX_WideString(L"DEFGH"));
+
+  // Test selecting middle selection in forward direction.
+  SelectTextWithKeyboard(page, 5, FWL_VKEY_Right, 127.0, 63.0);
+  CheckSelection(page, CFX_WideString(L"DEFGH"));
+
+  // Test selecting last character in backwards direction.
+  SelectTextWithKeyboard(page, 1, FWL_VKEY_Left, 178.0, 63.0);
+  CheckSelection(page, CFX_WideString(L"J"));
+
+  // Select a provided option and then reset selection as first two chars.
+  SelectOption(page, 0, 192.0, 60.0);
+  CheckSelection(page, CFX_WideString(L"Foo"));
+  SelectTextWithKeyboard(page, 2, FWL_VKEY_Right, 102.0, 63.0);
+  CheckSelection(page, CFX_WideString(L"Fo"));
+
+  UnloadPage(page);
+}
+
+TEST_F(FPDFFormFillEmbeddertest,
+       GetSelectedTextFragmentsEditableComboBoxMouse) {
+  // Open file with form comboboxes.
+  EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+  FPDF_PAGE page = LoadPage(0);
+  ASSERT_TRUE(page);
+
+  TypeTextIntoTextfield(page, 10, FPDF_FORMFIELD_COMBOBOX, 102.0, 62.0);
+
+  // Test selecting first character in forward direction.
+  SelectTextWithMouse(page, 102.0, 107.0, 63.0);
+  CheckSelection(page, CFX_WideString(L"A"));
+
+  // Test selecting entire long string in backwards direction.
+  SelectTextWithMouse(page, 178.0, 102.0, 63.0);
+  CheckSelection(page, CFX_WideString(L"ABCDEFGHIJ"));
+
+  // Test selecting middle section in backwards direction.
+  SelectTextWithMouse(page, 168.0, 127.0, 63.0);
+  CheckSelection(page, CFX_WideString(L"DEFGH"));
+
+  // Test selecting middle selection in forward direction.
+  SelectTextWithMouse(page, 127.0, 168.0, 63.0);
+  CheckSelection(page, CFX_WideString(L"DEFGH"));
+
+  // Test selecting last character in backwards direction.
+  SelectTextWithMouse(page, 178.0, 174.0, 63.0);
+  CheckSelection(page, CFX_WideString(L"J"));
+
+  UnloadPage(page);
+}
diff --git a/fpdfsdk/pdfwindow/cpwl_combo_box_embeddertest.cpp b/fpdfsdk/pdfwindow/cpwl_combo_box_embeddertest.cpp
new file mode 100644
index 0000000..35c7b22
--- /dev/null
+++ b/fpdfsdk/pdfwindow/cpwl_combo_box_embeddertest.cpp
@@ -0,0 +1,196 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "fpdfsdk/cba_annotiterator.h"
+#include "fpdfsdk/cpdfsdk_annot.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+#include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
+#include "fpdfsdk/pdfwindow/cpwl_combo_box.h"
+#include "fpdfsdk/pdfwindow/cpwl_wnd.h"
+#include "testing/embedder_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class CPWLComboBoxEditEmbeddertest : public EmbedderTest {
+ protected:
+  void SetUp() override {
+    EmbedderTest::SetUp();
+    CreateAndInitializeFormComboboxPDF();
+  }
+
+  void TearDown() override {
+    UnloadPage(GetPage());
+    EmbedderTest::TearDown();
+  }
+
+  void CreateAndInitializeFormComboboxPDF() {
+    EXPECT_TRUE(OpenDocument("combobox_form.pdf"));
+    m_page = LoadPage(0);
+    ASSERT_TRUE(m_page);
+
+    m_pFormFillEnv = static_cast<CPDFSDK_FormFillEnvironment*>(form_handle());
+    CBA_AnnotIterator iter(m_pFormFillEnv->GetPageView(0),
+                           CPDF_Annot::Subtype::WIDGET);
+
+    // User editable combobox.
+    m_pAnnotEditable = iter.GetFirstAnnot();
+    ASSERT_TRUE(m_pAnnotEditable);
+    ASSERT_EQ(CPDF_Annot::Subtype::WIDGET, m_pAnnotEditable->GetAnnotSubtype());
+
+    // Normal combobox with pre-selected value.
+    m_pAnnotNormal = iter.GetNextAnnot(m_pAnnotEditable);
+    ASSERT_TRUE(m_pAnnotNormal);
+    ASSERT_EQ(CPDF_Annot::Subtype::WIDGET, m_pAnnotNormal->GetAnnotSubtype());
+
+    // Read-only combobox.
+    CPDFSDK_Annot* pAnnotReadOnly = iter.GetNextAnnot(m_pAnnotNormal);
+    CPDFSDK_Annot* pLastAnnot = iter.GetLastAnnot();
+    ASSERT_EQ(pAnnotReadOnly, pLastAnnot);
+  }
+
+  void FormFillerAndWindowSetup(CPDFSDK_Annot* pAnnotCombobox) {
+    CFFL_InteractiveFormFiller* pInteractiveFormFiller =
+        m_pFormFillEnv->GetInteractiveFormFiller();
+    {
+      CPDFSDK_Annot::ObservedPtr pObserved(pAnnotCombobox);
+      EXPECT_TRUE(pInteractiveFormFiller->OnSetFocus(&pObserved, 0));
+    }
+
+    m_pFormFiller =
+        pInteractiveFormFiller->GetFormFiller(pAnnotCombobox, false);
+    ASSERT_TRUE(m_pFormFiller);
+
+    CPWL_Wnd* pWindow =
+        m_pFormFiller->GetPDFWindow(m_pFormFillEnv->GetPageView(0), false);
+    ASSERT_TRUE(pWindow);
+    ASSERT_EQ("CPWL_ComboBox", pWindow->GetClassName());
+    m_pComboBox = static_cast<CPWL_ComboBox*>(pWindow);
+  }
+
+  FPDF_PAGE GetPage() const { return m_page; }
+  CPWL_ComboBox* GetCPWLComboBox() const { return m_pComboBox; }
+  CFFL_FormFiller* GetCFFLFormFiller() const { return m_pFormFiller; }
+  CPDFSDK_Annot* GetCPDFSDKAnnotNormal() const { return m_pAnnotNormal; }
+  CPDFSDK_Annot* GetCPDFSDKAnnotUserEditable() const {
+    return m_pAnnotEditable;
+  }
+  CPDFSDK_FormFillEnvironment* GetCPDFSDKFormFillEnv() const {
+    return m_pFormFillEnv;
+  }
+
+ private:
+  FPDF_PAGE m_page;
+  CPWL_ComboBox* m_pComboBox;
+  CFFL_FormFiller* m_pFormFiller;
+  CPDFSDK_Annot* m_pAnnotNormal;
+  CPDFSDK_Annot* m_pAnnotEditable;
+  CPDFSDK_FormFillEnvironment* m_pFormFillEnv;
+};
+
+TEST_F(CPWLComboBoxEditEmbeddertest, GetSelectedTextEmptyAndBasicNormal) {
+  FormFillerAndWindowSetup(GetCPDFSDKAnnotNormal());
+
+  // Automatically pre-filled with "Banana".
+  EXPECT_FALSE(GetCPWLComboBox()->GetText().IsEmpty());
+  EXPECT_STREQ(L"Banana", GetCPWLComboBox()->GetText().c_str());
+
+  // Check that selection is intially empty, then select entire word.
+  EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
+  GetCPWLComboBox()->SetSelectText();
+  EXPECT_STREQ(L"Banana", GetCPWLComboBox()->GetSelectedText().c_str());
+
+  // Select other options.
+  GetCPWLComboBox()->SetSelect(0);
+  EXPECT_STREQ(L"Apple", GetCPWLComboBox()->GetSelectedText().c_str());
+  GetCPWLComboBox()->SetSelect(2);
+  EXPECT_STREQ(L"Cherry", GetCPWLComboBox()->GetSelectedText().c_str());
+
+  // Verify that combobox text cannot be edited.
+  EXPECT_FALSE(GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotNormal(), 'a', 0));
+}
+
+TEST_F(CPWLComboBoxEditEmbeddertest, GetSelectedTextFragmentsNormal) {
+  FormFillerAndWindowSetup(GetCPDFSDKAnnotNormal());
+  EXPECT_STREQ(L"Banana", GetCPWLComboBox()->GetText().c_str());
+
+  GetCPWLComboBox()->SetEditSel(0, 0);
+  EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
+
+  GetCPWLComboBox()->SetEditSel(0, 1);
+  EXPECT_STREQ(L"B", GetCPWLComboBox()->GetSelectedText().c_str());
+
+  GetCPWLComboBox()->SetEditSel(0, -1);
+  EXPECT_STREQ(L"Banana", GetCPWLComboBox()->GetSelectedText().c_str());
+
+  GetCPWLComboBox()->SetEditSel(-8, -1);
+  EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
+
+  GetCPWLComboBox()->SetEditSel(4, 1);
+  EXPECT_STREQ(L"ana", GetCPWLComboBox()->GetSelectedText().c_str());
+
+  GetCPWLComboBox()->SetEditSel(1, 4);
+  EXPECT_STREQ(L"ana", GetCPWLComboBox()->GetSelectedText().c_str());
+
+  GetCPWLComboBox()->SetEditSel(5, 6);
+  EXPECT_STREQ(L"a", GetCPWLComboBox()->GetSelectedText().c_str());
+}
+
+TEST_F(CPWLComboBoxEditEmbeddertest, GetSelectedTextEmptyAndBasicEditable) {
+  FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+  EXPECT_TRUE(GetCPWLComboBox()->GetText().IsEmpty());
+
+  // Check selection is intially empty, then select a provided option.
+  EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
+  GetCPWLComboBox()->SetSelect(0);
+  GetCPWLComboBox()->SetSelectText();
+  EXPECT_STREQ(L"Foo", GetCPWLComboBox()->GetSelectedText().c_str());
+
+  // Select another option and then select last char of that option.
+  GetCPWLComboBox()->SetSelect(1);
+  EXPECT_STREQ(L"Bar", GetCPWLComboBox()->GetSelectedText().c_str());
+  GetCPWLComboBox()->SetEditSel(2, 3);
+  EXPECT_STREQ(L"r", GetCPWLComboBox()->GetSelectedText().c_str());
+
+  // Type into editable combobox text field and select new text.
+  EXPECT_TRUE(
+      GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), 'a', 0));
+  EXPECT_TRUE(
+      GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), 'b', 0));
+  EXPECT_TRUE(
+      GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), 'c', 0));
+
+  EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
+  GetCPWLComboBox()->SetEditSel(0, 5);
+  EXPECT_STREQ(L"Baabc", GetCPWLComboBox()->GetSelectedText().c_str());
+}
+
+TEST_F(CPWLComboBoxEditEmbeddertest, GetSelectedTextFragmentsEditable) {
+  FormFillerAndWindowSetup(GetCPDFSDKAnnotUserEditable());
+  for (int i = 0; i < 50; ++i) {
+    EXPECT_TRUE(
+        GetCFFLFormFiller()->OnChar(GetCPDFSDKAnnotUserEditable(), i + 'A', 0));
+  }
+
+  GetCPWLComboBox()->SetEditSel(0, 0);
+  EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
+
+  GetCPWLComboBox()->SetEditSel(0, 1);
+  EXPECT_STREQ(L"A", GetCPWLComboBox()->GetSelectedText().c_str());
+
+  GetCPWLComboBox()->SetEditSel(0, -1);
+  EXPECT_STREQ(L"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqr",
+               GetCPWLComboBox()->GetSelectedText().c_str());
+
+  GetCPWLComboBox()->SetEditSel(-8, -1);
+  EXPECT_TRUE(GetCPWLComboBox()->GetSelectedText().IsEmpty());
+
+  GetCPWLComboBox()->SetEditSel(23, 12);
+  EXPECT_STREQ(L"MNOPQRSTUVW", GetCPWLComboBox()->GetSelectedText().c_str());
+
+  GetCPWLComboBox()->SetEditSel(12, 23);
+  EXPECT_STREQ(L"MNOPQRSTUVW", GetCPWLComboBox()->GetSelectedText().c_str());
+
+  GetCPWLComboBox()->SetEditSel(49, 50);
+  EXPECT_STREQ(L"r", GetCPWLComboBox()->GetSelectedText().c_str());
+}