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