Adding test cases for enter key press on buttons
Adding embedder test cases and pixel test for enter key press on check
box and radio buttons.
Bug: pdfium:1431
Change-Id: Ia8fb9658fa0770407fc9b044733aeb335814240f
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/66410
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/pwl/BUILD.gn b/fpdfsdk/pwl/BUILD.gn
index ea26c13..ea2ce94 100644
--- a/fpdfsdk/pwl/BUILD.gn
+++ b/fpdfsdk/pwl/BUILD.gn
@@ -50,6 +50,7 @@
sources = [
"cpwl_combo_box_embeddertest.cpp",
"cpwl_edit_embeddertest.cpp",
+ "cpwl_special_button_embeddertest.cpp",
]
deps = [
":pwl",
diff --git a/fpdfsdk/pwl/cpwl_special_button_embeddertest.cpp b/fpdfsdk/pwl/cpwl_special_button_embeddertest.cpp
new file mode 100644
index 0000000..bd6eea0
--- /dev/null
+++ b/fpdfsdk/pwl/cpwl_special_button_embeddertest.cpp
@@ -0,0 +1,147 @@
+// Copyright 2020 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/cpdfsdk_annot.h"
+#include "fpdfsdk/cpdfsdk_annotiterator.h"
+#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
+#include "fpdfsdk/cpdfsdk_helpers.h"
+#include "fpdfsdk/formfiller/cffl_formfiller.h"
+#include "fpdfsdk/pwl/cpwl_special_button.h"
+#include "fpdfsdk/pwl/cpwl_wnd.h"
+#include "testing/embedder_test.h"
+
+class CPWLSpecialButtonEmbedderTest : public EmbedderTest {
+ protected:
+ void SetUp() override {
+ EmbedderTest::SetUp();
+ CreateAndInitializeFormPDF();
+ }
+
+ void TearDown() override {
+ UnloadPage(page_);
+ EmbedderTest::TearDown();
+ }
+
+ void CreateAndInitializeFormPDF() {
+ ASSERT_TRUE(OpenDocument("click_form.pdf"));
+
+ page_ = LoadPage(0);
+ ASSERT_TRUE(page_);
+
+ formfill_env_ = CPDFSDKFormFillEnvironmentFromFPDFFormHandle(form_handle());
+ CPDFSDK_AnnotIterator it(formfill_env_->GetPageView(0),
+ CPDF_Annot::Subtype::WIDGET);
+
+ // Read only check box.
+ annot_readonly_checkbox_ = it.GetFirstAnnot();
+ ASSERT_TRUE(annot_readonly_checkbox_);
+ ASSERT_EQ(CPDF_Annot::Subtype::WIDGET,
+ annot_readonly_checkbox_->GetAnnotSubtype());
+
+ // Check box.
+ annot_checkbox_ = it.GetNextAnnot(annot_readonly_checkbox_);
+ ASSERT_TRUE(annot_checkbox_);
+ ASSERT_EQ(CPDF_Annot::Subtype::WIDGET, annot_checkbox_->GetAnnotSubtype());
+
+ // Read only radio button.
+ annot_readonly_radiobutton_ = it.GetNextAnnot(annot_checkbox_);
+ ASSERT_TRUE(annot_readonly_radiobutton_);
+ ASSERT_EQ(CPDF_Annot::Subtype::WIDGET,
+ annot_readonly_radiobutton_->GetAnnotSubtype());
+
+ // Tabbing three times from read only radio button to unselected normal
+ // radio button.
+ annot_radiobutton_ = annot_readonly_radiobutton_;
+ ASSERT_TRUE(annot_radiobutton_);
+ for (int i = 0; i < 3; i++) {
+ annot_radiobutton_ = it.GetNextAnnot(annot_radiobutton_);
+ ASSERT_TRUE(annot_radiobutton_);
+ }
+
+ ASSERT_EQ(CPDF_Annot::Subtype::WIDGET,
+ annot_radiobutton_->GetAnnotSubtype());
+ }
+
+ void FormFillerAndWindowSetup(CPDFSDK_Annot* annot) {
+ CFFL_InteractiveFormFiller* interactive_formfiller =
+ formfill_env_->GetInteractiveFormFiller();
+ {
+ ObservedPtr<CPDFSDK_Annot> observed(annot);
+ EXPECT_TRUE(interactive_formfiller->OnSetFocus(&observed, 0));
+ }
+
+ form_filler_ = interactive_formfiller->GetFormFillerForTesting(annot);
+ ASSERT_TRUE(form_filler_);
+
+ window_ = form_filler_->GetPWLWindow(formfill_env_->GetPageView(0), true);
+ ASSERT_TRUE(window_);
+ }
+
+ CPDFSDK_Annot* GetCPDFSDKAnnotCheckBox() const { return annot_checkbox_; }
+ CPDFSDK_Annot* GetCPDFSDKAnnotReadOnlyCheckBox() const {
+ return annot_readonly_checkbox_;
+ }
+ CPDFSDK_Annot* GetCPDFSDKAnnotRadioButton() const {
+ return annot_radiobutton_;
+ }
+ CPDFSDK_Annot* GetCPDFSDKAnnotReadOnlyRadioButton() const {
+ return annot_readonly_radiobutton_;
+ }
+ CPDFSDK_FormFillEnvironment* GetCPDFSDKFormFillEnv() const {
+ return formfill_env_;
+ }
+ CPWL_Wnd* GetWindow() const { return window_; }
+
+ private:
+ FPDF_PAGE page_;
+ CFFL_FormFiller* form_filler_;
+ CPDFSDK_Annot* annot_checkbox_;
+ CPDFSDK_Annot* annot_readonly_checkbox_;
+ CPDFSDK_Annot* annot_radiobutton_;
+ CPDFSDK_Annot* annot_readonly_radiobutton_;
+ CPDFSDK_FormFillEnvironment* formfill_env_;
+ CPWL_Wnd* window_;
+};
+
+TEST_F(CPWLSpecialButtonEmbedderTest, EnterOnReadOnlyCheckBox) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotReadOnlyCheckBox());
+ CPWL_CheckBox* check_box = static_cast<CPWL_CheckBox*>(GetWindow());
+ EXPECT_TRUE(GetCPDFSDKFormFillEnv()->GetInteractiveFormFiller()->OnChar(
+ GetCPDFSDKAnnotReadOnlyCheckBox(), '\r', 0));
+ // The check box is checked by default. Since it is a read only checkbox,
+ // clicking Enter shouldn't change its state.
+ // TODO(http://crbug.com/pdfium/1431) : Change this to EXPECT_TRUE
+ // as part of the fix.
+ EXPECT_FALSE(check_box->IsChecked());
+}
+
+TEST_F(CPWLSpecialButtonEmbedderTest, EnterOnCheckBox) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotCheckBox());
+ CPWL_CheckBox* check_box = static_cast<CPWL_CheckBox*>(GetWindow());
+ EXPECT_TRUE(GetCPDFSDKFormFillEnv()->GetInteractiveFormFiller()->OnChar(
+ GetCPDFSDKAnnotCheckBox(), '\r', 0));
+ EXPECT_TRUE(check_box->IsChecked());
+
+ EXPECT_TRUE(GetCPDFSDKFormFillEnv()->GetInteractiveFormFiller()->OnChar(
+ GetCPDFSDKAnnotCheckBox(), '\r', 0));
+ EXPECT_FALSE(check_box->IsChecked());
+}
+
+TEST_F(CPWLSpecialButtonEmbedderTest, EnterOnReadOnlyRadioButton) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotReadOnlyRadioButton());
+ CPWL_RadioButton* radio_button = static_cast<CPWL_RadioButton*>(GetWindow());
+ EXPECT_TRUE(GetCPDFSDKFormFillEnv()->GetInteractiveFormFiller()->OnChar(
+ GetCPDFSDKAnnotReadOnlyRadioButton(), '\r', 0));
+ // TODO(http://crbug.com/pdfium/1431) : Change this to EXPECT_FALSE
+ // as part of the fix.
+ EXPECT_TRUE(radio_button->IsChecked());
+}
+
+TEST_F(CPWLSpecialButtonEmbedderTest, EnterOnRadioButton) {
+ FormFillerAndWindowSetup(GetCPDFSDKAnnotRadioButton());
+ CPWL_RadioButton* radio_button = static_cast<CPWL_RadioButton*>(GetWindow());
+ EXPECT_TRUE(GetCPDFSDKFormFillEnv()->GetInteractiveFormFiller()->OnChar(
+ GetCPDFSDKAnnotRadioButton(), '\r', 0));
+ EXPECT_TRUE(radio_button->IsChecked());
+}
diff --git a/testing/resources/pixel/checkbox_radiobutton.evt b/testing/resources/pixel/checkbox_radiobutton.evt
new file mode 100644
index 0000000..6742beb
--- /dev/null
+++ b/testing/resources/pixel/checkbox_radiobutton.evt
@@ -0,0 +1,11 @@
+# Check the checkbox
+mousemove,145,220
+mousedown,left,145,220
+mouseup,left,145,220
+
+# Tab to radio button from checkbox
+keycode,9
+keycode,9
+
+# Press Enter to select radio button
+charcode,13
\ No newline at end of file
diff --git a/testing/resources/pixel/checkbox_radiobutton.in b/testing/resources/pixel/checkbox_radiobutton.in
new file mode 100644
index 0000000..59d73a2
--- /dev/null
+++ b/testing/resources/pixel/checkbox_radiobutton.in
@@ -0,0 +1,199 @@
+{{header}}
+{{object 1 0}} <<
+ /Type /Catalog
+ /Pages 2 0 R
+ /AcroForm <<
+ /Fields [5 0 R 6 0 R 7 0 R 9 0 R]
+ >>
+>>
+endobj
+{{object 2 0}} <<
+ /Type /Pages
+ /Count 1
+ /Kids [3 0 R]
+>>
+endobj
+{{object 3 0}} <<
+ /Type /Page
+ /Parent 2 0 R
+ /MediaBox [0 0 300 300]
+ /Contents 4 0 R
+ /Annots [5 0 R 6 0 R 8 0 R 10 0 R]
+>>
+endobj
+{{object 4 0}} <<
+ {{streamlen}}
+>>
+stream
+q
+q
+1 w
+1 0 1 RG
+1 .752941 .796078 rg
+n 135.5 250.5 19 19 re B*
+Q
+q
+2 w
+.1 .1 .1 RG
+.8 .843 1 rg
+n 136 211 18 18 re B*
+Q
+q
+2 w
+0 .501961 0 RG
+0 0 1 rg
+n
+104 110 m
+104 114.9706 99.97056 119 95 119 c
+90.02944 119 86 114.9706 86 110 c
+86 105.0294 90.02944 101 95 101 c
+99.97056 101 104 105.0294 104 110 c
+B*
+Q
+q
+2 w
+0 .501961 0 RG
+0 0 1 rg
+n
+104 60 m
+104 64.97056 99.97056 69 95 69 c
+90.02944 69 86 64.97056 86 60 c
+86 55.02944 90.02944 51 95 51 c
+99.97056 51 104 55.02944 104 60 c
+B*
+Q
+Q
+endstream
+endobj
+{{object 5 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /FT /Btn
+ /Ff 1
+ /Rect [135 250 155 270]
+ /T (readOnlyCheckbox)
+ /AP <<
+ /N <<
+ /Yes 11 0 R
+ >>
+ >>
+ /AS /Off
+>>
+endobj
+{{object 6 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /FT /Btn
+ /Ff 2
+ /Rect [135 210 155 230]
+ /T (checkbox)
+ /AP <<
+ /N <<
+ /Yes 11 0 R
+ >>
+ >>
+ /AS /Off
+>>
+endobj
+{{object 7 0}} <<
+ /FT /Btn
+ /Ff 49153
+ /T (readOnlyRadioButton)
+ /Kids [8 0 R]
+>>
+endobj
+{{object 8 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /FT /Btn
+ /Parent 7 0 R
+ /Rect [85 100 105 120]
+ /AP <<
+ /N <<
+ /value1 12 0 R
+ >>
+ >>
+ /AS /Off
+>>
+endobj
+{{object 9 0}} <<
+ /FT /Btn
+ /Ff 49154
+ /T (radioButton)
+ /Kids [10 0 R]
+>>
+endobj
+{{object 10 0}} <<
+ /Type /Annot
+ /Subtype /Widget
+ /FT /Btn
+ /Parent 9 0 R
+ /Rect [85 50 105 70]
+ /AP <<
+ /N <<
+ /value1 12 0 R
+ >>
+ >>
+ /AS /Off
+>>
+endobj
+{{object 11 0}} <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ /BBox [0 0 20 20]
+ {{streamlen}}
+>>
+stream
+q
+.1 .1 .1 rg .1 .1 .1 RG
+17.2 15.95145 m
+11.20694 10 l
+17.2 4.027746 l
+15.97225 2.8 l
+10 8.793064 l
+4.027746 2.8 l
+2.8 4.027746 l
+8.813873 10 l
+2.8 15.97225 l
+4.027746 17.2 l
+10 11.20694 l
+15.97225 17.2 l
+17.2 15.95145 l
+h
+f
+Q
+endstream
+endobj
+{{object 12 0}} <<
+ /Type /XObject
+ /Subtype /Form
+ /FormType 1
+ /BBox [0 0 20 20]
+ {{streamlen}}
+>>
+stream
+q
+1 .752941 .796078 rg 1 .752941 .796078 RG
+17.2 15.95145 m
+11.20694 10 l
+17.2 4.027746 l
+15.97225 2.8 l
+10 8.793064 l
+4.027746 2.8 l
+2.8 4.027746 l
+8.813873 10 l
+2.8 15.97225 l
+4.027746 17.2 l
+10 11.20694 l
+15.97225 17.2 l
+17.2 15.95145 l
+h
+f
+Q
+endstream
+endobj
+{{xref}}
+{{trailer}}
+{{startxref}}
+%%EOF
diff --git a/testing/resources/pixel/checkbox_radiobutton_expected.pdf.0.png b/testing/resources/pixel/checkbox_radiobutton_expected.pdf.0.png
new file mode 100644
index 0000000..8baabb7
--- /dev/null
+++ b/testing/resources/pixel/checkbox_radiobutton_expected.pdf.0.png
Binary files differ