xref: /aosp_15_r20/external/pdfium/xfa/fwl/cfwl_edit_embeddertest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1 // Copyright 2017 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 "xfa/fwl/cfwl_edit.h"
6 
7 #include <memory>
8 
9 #include "core/fxcrt/widestring.h"
10 #include "core/fxge/cfx_defaultrenderdevice.h"
11 #include "public/fpdf_ext.h"
12 #include "public/fpdf_formfill.h"
13 #include "public/fpdf_fwlevent.h"
14 #include "testing/embedder_test.h"
15 #include "testing/embedder_test_environment.h"
16 #include "testing/embedder_test_timer_handling_delegate.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "testing/xfa_js_embedder_test.h"
19 
20 namespace {
21 
22 const char kEmailRecommendedFilledChecksum[] =
23     "211e4e46eb347aa2bc7c425556d600b0";
24 
25 }  // namespace
26 
27 class CFWLEditEmbedderTest : public XFAJSEmbedderTest {
28  protected:
SetUp()29   void SetUp() override {
30     EmbedderTest::SetUp();
31     SetDelegate(&delegate_);
32 
33     // Arbitrary, picked nice even number, 2020-09-13 12:26:40.
34     FSDK_SetTimeFunction([]() -> time_t { return 1600000000; });
35     FSDK_SetLocaltimeFunction([](const time_t* t) { return gmtime(t); });
36   }
37 
TearDown()38   void TearDown() override {
39     FSDK_SetTimeFunction(nullptr);
40     FSDK_SetLocaltimeFunction(nullptr);
41     // TODO(crbug.com/pdfium/11): A page might not have been loaded if a test
42     // is skipped at runtime. This check for a non-null page should be able to
43     // removed once none of the tests are being skipped for Skia.
44     if (page())
45       UnloadPage(page());
46     EmbedderTest::TearDown();
47   }
48 
CreateAndInitializeFormPDF(const char * filename)49   void CreateAndInitializeFormPDF(const char* filename) {
50     ASSERT_TRUE(OpenDocument(filename));
51     page_ = LoadPage(0);
52     ASSERT_TRUE(page_);
53   }
54 
page() const55   FPDF_PAGE page() const { return page_; }
delegate() const56   EmbedderTestTimerHandlingDelegate delegate() const { return delegate_; }
57 
58  private:
59   FPDF_PAGE page_ = nullptr;
60   EmbedderTestTimerHandlingDelegate delegate_;
61 };
62 
TEST_F(CFWLEditEmbedderTest,Trivial)63 TEST_F(CFWLEditEmbedderTest, Trivial) {
64   CreateAndInitializeFormPDF("xfa/email_recommended.pdf");
65   ASSERT_EQ(0u, delegate().GetAlerts().size());
66 }
67 
TEST_F(CFWLEditEmbedderTest,LeftClickMouseSelection)68 TEST_F(CFWLEditEmbedderTest, LeftClickMouseSelection) {
69   CreateAndInitializeFormPDF("xfa/email_recommended.pdf");
70   FORM_OnLButtonDown(form_handle(), page(), 0, 115, 58);
71   for (size_t i = 0; i < 10; ++i)
72     FORM_OnChar(form_handle(), page(), 'a' + i, 0);
73 
74   // Mouse selection
75   FORM_OnLButtonDown(form_handle(), page(), 0, 128, 58);
76   FORM_OnLButtonDown(form_handle(), page(), FWL_EVENTFLAG_ShiftKey, 152, 58);
77 
78   // 12 == (2 * strlen(defgh)) + 2 (for \0\0)
79   EXPECT_EQ(12UL, FORM_GetSelectedText(form_handle(), page(), nullptr, 0));
80 
81   unsigned short buf[128];
82   unsigned long len = FORM_GetSelectedText(form_handle(), page(), &buf, 128);
83   EXPECT_STREQ(L"defgh", WideString::FromUTF16LE(buf, len).c_str());
84 }
85 
TEST_F(CFWLEditEmbedderTest,DragMouseSelection)86 TEST_F(CFWLEditEmbedderTest, DragMouseSelection) {
87   // TODO(crbug.com/pdfium/11): Fix this test and enable for Skia variants.
88   if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
89     return;
90 
91   CreateAndInitializeFormPDF("xfa/email_recommended.pdf");
92   FORM_OnLButtonDown(form_handle(), page(), 0, 115, 58);
93   for (size_t i = 0; i < 10; ++i)
94     FORM_OnChar(form_handle(), page(), 'a' + i, 0);
95 
96   // Mouse selection
97   FORM_OnLButtonDown(form_handle(), page(), 0, 128, 58);
98   FORM_OnMouseMove(form_handle(), page(), FWL_EVENTFLAG_ShiftKey, 152, 58);
99 
100   // 12 == (2 * strlen(defgh)) + 2 (for \0\0)
101   EXPECT_EQ(12UL, FORM_GetSelectedText(form_handle(), page(), nullptr, 0));
102 
103   unsigned short buf[128];
104   unsigned long len = FORM_GetSelectedText(form_handle(), page(), &buf, 128);
105   EXPECT_STREQ(L"defgh", WideString::FromUTF16LE(buf, len).c_str());
106 
107   // TODO(hnakashima): This is incorrect. Visually 'abcdefgh' are selected.
108   const char kDraggedMD5[] = "f131526c8edd04e44de17b2647ec54c8";
109   {
110     ScopedFPDFBitmap page_bitmap =
111         RenderLoadedPageWithFlags(page(), FPDF_ANNOT);
112     CompareBitmap(page_bitmap.get(), 612, 792, kDraggedMD5);
113   }
114 }
115 
TEST_F(CFWLEditEmbedderTest,SimpleFill)116 TEST_F(CFWLEditEmbedderTest, SimpleFill) {
117   // TODO(crbug.com/pdfium/11): Fix this test and enable for Skia variants.
118   if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
119     return;
120 
121   CreateAndInitializeFormPDF("xfa/email_recommended.pdf");
122   const char kBlankMD5[] = "8dda78a3afaf9f7b5210eb81cacc4600";
123   {
124     ScopedFPDFBitmap page_bitmap =
125         RenderLoadedPageWithFlags(page(), FPDF_ANNOT);
126     CompareBitmap(page_bitmap.get(), 612, 792, kBlankMD5);
127   }
128 
129   FORM_OnLButtonDown(form_handle(), page(), 0, 115, 58);
130   for (size_t i = 0; i < 10; ++i)
131     FORM_OnChar(form_handle(), page(), 'a' + i, 0);
132 
133   {
134     ScopedFPDFBitmap page_bitmap =
135         RenderLoadedPageWithFlags(page(), FPDF_ANNOT);
136     CompareBitmap(page_bitmap.get(), 612, 792, kEmailRecommendedFilledChecksum);
137   }
138 }
139 
TEST_F(CFWLEditEmbedderTest,FillWithNewLineWithoutMultiline)140 TEST_F(CFWLEditEmbedderTest, FillWithNewLineWithoutMultiline) {
141   // TODO(crbug.com/pdfium/11): Fix this test and enable for Skia variants.
142   if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
143     return;
144 
145   CreateAndInitializeFormPDF("xfa/email_recommended.pdf");
146   FORM_OnLButtonDown(form_handle(), page(), 0, 115, 58);
147   for (size_t i = 0; i < 5; ++i)
148     FORM_OnChar(form_handle(), page(), 'a' + i, 0);
149   FORM_OnChar(form_handle(), page(), '\r', 0);
150   for (size_t i = 5; i < 10; ++i)
151     FORM_OnChar(form_handle(), page(), 'a' + i, 0);
152 
153   {
154     ScopedFPDFBitmap page_bitmap =
155         RenderLoadedPageWithFlags(page(), FPDF_ANNOT);
156     CompareBitmap(page_bitmap.get(), 612, 792, kEmailRecommendedFilledChecksum);
157   }
158 }
159 
160 // Disabled due to flakiness.
TEST_F(CFWLEditEmbedderTest,DISABLED_FillWithNewLineWithMultiline)161 TEST_F(CFWLEditEmbedderTest, DISABLED_FillWithNewLineWithMultiline) {
162   CreateAndInitializeFormPDF("xfa/xfa_multiline_textfield.pdf");
163   FORM_OnLButtonDown(form_handle(), page(), 0, 115, 58);
164 
165   for (size_t i = 0; i < 5; ++i)
166     FORM_OnChar(form_handle(), page(), 'a' + i, 0);
167   FORM_OnChar(form_handle(), page(), '\r', 0);
168   for (size_t i = 5; i < 10; ++i)
169     FORM_OnChar(form_handle(), page(), 'a' + i, 0);
170 
171   // Should look like:
172   // abcde
173   // fghij|
174   {
175 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
176     const char kFilledMultilineMD5[] = "fc1f4d5fdb2c5755005fc525b0a60ec9";
177 #else
178     const char kFilledMultilineMD5[] = "a5654e027d8b1667c20f3b86d1918003";
179 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
180     ScopedFPDFBitmap page_bitmap =
181         RenderLoadedPageWithFlags(page(), FPDF_ANNOT);
182     CompareBitmap(page_bitmap.get(), 612, 792, kFilledMultilineMD5);
183   }
184 
185   for (size_t i = 0; i < 4; ++i)
186     FORM_OnKeyDown(form_handle(), page(), FWL_VKEY_Left, 0);
187 
188   // Should look like:
189   // abcde
190   // f|ghij
191 
192   // Two backspaces is a workaround because left arrow does not behave well
193   // in the first character of a line. It skips back to the previous line.
194   for (size_t i = 0; i < 2; ++i)
195     FORM_OnChar(form_handle(), page(), '\b', 0);
196 
197   // Should look like:
198   // abcde|ghij
199   {
200 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
201     const char kMultilineBackspaceMD5[] = "8bb62a8100ff1e1cc113d4033e0d824e";
202 #else
203     const char kMultilineBackspaceMD5[] = "a2f1dcab92bb1fb7c2f9ccc70100c989";
204 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
205     ScopedFPDFBitmap page_bitmap =
206         RenderLoadedPageWithFlags(page(), FPDF_ANNOT);
207     CompareBitmap(page_bitmap.get(), 612, 792, kMultilineBackspaceMD5);
208   }
209 }
210 
TEST_F(CFWLEditEmbedderTest,DateTimePickerTest)211 TEST_F(CFWLEditEmbedderTest, DateTimePickerTest) {
212   // TODO(crbug.com/pdfium/11): Fix this test and enable for Skia variants.
213   if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
214     return;
215 
216   CreateAndInitializeFormPDF("xfa/xfa_date_time_edit.pdf");
217 
218   // Give focus to date time widget, creating down-arrow button.
219   FORM_OnLButtonDown(form_handle(), page(), 0, 115, 58);
220   FORM_OnLButtonUp(form_handle(), page(), 0, 115, 58);
221   const char kSelectedMD5[] = "1036b8837a9dba75c6bd8f9347ae2eb2";
222   {
223     ScopedFPDFBitmap page_bitmap =
224         RenderLoadedPageWithFlags(page(), FPDF_ANNOT);
225     CompareBitmap(page_bitmap.get(), 612, 792, kSelectedMD5);
226   }
227 
228   // Click down-arrow button, bringing up calendar widget.
229   FORM_OnLButtonDown(form_handle(), page(), 0, 446, 54);
230   FORM_OnLButtonUp(form_handle(), page(), 0, 446, 54);
231   {
232     ScopedFPDFBitmap page_bitmap =
233         RenderLoadedPageWithFlags(page(), FPDF_ANNOT);
234 
235     // TODO(tsepez): hermetic fonts.
236     // const char kCalendarOpenMD5[] = "02de64e7e83c82c1ef0ae484d671a51d";
237     // CompareBitmap(page_bitmap.get(), 612, 792, kCalendarOpenMD5);
238   }
239 
240   // Click on date on calendar, putting result into field as text.
241   FORM_OnLButtonDown(form_handle(), page(), 0, 100, 162);
242   FORM_OnLButtonUp(form_handle(), page(), 0, 100, 162);
243   {
244     ScopedFPDFBitmap page_bitmap =
245         RenderLoadedPageWithFlags(page(), FPDF_ANNOT);
246 
247     // TODO(tsepez): hermetic fonts.
248     // const char kFilledMD5[] = "1bce66c11f1c87b8d639ce0076ac36d3";
249     // CompareBitmap(page_bitmap.get(), 612, 792, kFilledMD5);
250   }
251 }
252 
TEST_F(CFWLEditEmbedderTest,ImageEditTest)253 TEST_F(CFWLEditEmbedderTest, ImageEditTest) {
254   CreateAndInitializeFormPDF("xfa/xfa_image_edit.pdf");
255   FORM_OnLButtonDown(form_handle(), page(), 0, 115, 58);
256   const char* filled_checksum = []() {
257     if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
258       return "23658ed124114f05518372d41c80e41b";
259     return "101cf6223fa2403fba4c413a8310ab02";
260   }();
261   ScopedFPDFBitmap page_bitmap = RenderLoadedPageWithFlags(page(), FPDF_ANNOT);
262   CompareBitmap(page_bitmap.get(), 612, 792, filled_checksum);
263 }
264 
TEST_F(CFWLEditEmbedderTest,ComboBoxTest)265 TEST_F(CFWLEditEmbedderTest, ComboBoxTest) {
266   CreateAndInitializeFormPDF("xfa/xfa_combobox.pdf");
267 
268   // Give focus to widget.
269   FORM_OnLButtonDown(form_handle(), page(), 0, 115, 58);
270   FORM_OnLButtonUp(form_handle(), page(), 0, 115, 58);
271   {
272     const char* filled_checksum = []() {
273       if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer())
274         return "8c555487e09ee4acf3ace77db5929bdc";
275       return "dad642ae8a5afce2591ffbcabbfc58dd";
276     }();
277     ScopedFPDFBitmap page_bitmap =
278         RenderLoadedPageWithFlags(page(), FPDF_ANNOT);
279     CompareBitmap(page_bitmap.get(), 612, 792, filled_checksum);
280   }
281 
282   // Click on down-arrow button, dropdown list appears.
283   FORM_OnLButtonDown(form_handle(), page(), 0, 438, 53);
284   FORM_OnLButtonUp(form_handle(), page(), 0, 438, 53);
285   {
286     ScopedFPDFBitmap page_bitmap =
287         RenderLoadedPageWithFlags(page(), FPDF_ANNOT);
288     // TODO(tsepez): hermetic fonts.
289     // const char kFilledMD5[] = "dad642ae8a5afce2591ffbcabbfc58dd";
290     // CompareBitmap(page_bitmap.get(), 612, 792, kFilledMD5);
291   }
292 
293   // Enter drop-down list, selection highlighted.
294   FORM_OnMouseMove(form_handle(), page(), 0, 253, 107);
295   {
296     ScopedFPDFBitmap page_bitmap =
297         RenderLoadedPageWithFlags(page(), FPDF_ANNOT);
298     // TODO(tsepez): hermetic fonts.
299     // const char kFilledMD5[] = "dad642ae8a5afce2591ffbcabbfc58dd";
300     // CompareBitmap(page_bitmap.get(), 612, 792, kFilledMD5);
301   }
302 
303   // Click on selection, putting result into field.
304   FORM_OnLButtonDown(form_handle(), page(), 0, 253, 107);
305   FORM_OnLButtonUp(form_handle(), page(), 0, 253, 107);
306   {
307     ScopedFPDFBitmap page_bitmap =
308         RenderLoadedPageWithFlags(page(), FPDF_ANNOT);
309     // TODO(tsepez): hermetic fonts.
310     // const char kFilledMD5[] = "dad642ae8a5afce2591ffbcabbfc58dd";
311     // CompareBitmap(page_bitmap.get(), 612, 792, kFilledMD5);
312   }
313 }
314