• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4 
5 #include "include/base/cef_callback.h"
6 #include "include/wrapper/cef_closure_task.h"
7 #include "tests/ceftests/test_handler.h"
8 #include "tests/gtest/include/gtest/gtest.h"
9 
10 namespace {
11 
12 const char kTestHTMLWithRegions[] =
13     "<html>"
14     "  <body>"
15     "    <div style=\"position: absolute; top: 50px; left: 50px; width: 200px; "
16     "height: 200px; background-color: red; -webkit-app-region: drag;\">"
17     "      <div style=\"position: absolute; top: 50%; left: 50%; "
18     "transform: translate(-50%, -50%); width: 50px; height: 50px; "
19     "background-color: blue; -webkit-app-region: no-drag;\">"
20     "      </div>"
21     "    </div>"
22     "  </body>"
23     "</html>";
24 
25 const char kTestHTMLWithoutRegions[] = "<html><body>Hello World!</body></html>";
26 
27 const char kTestHTMLWithChangingRegions[] =
28     "<html>"
29     "  <body>"
30     "    <div id=\"layer\" style=\"position: absolute; top: 50px; left: 50px; "
31     "width: 200px; height: 200px; background-color: red; "
32     "-webkit-app-region: drag;\">"
33     "      <div style=\"position: absolute; top: 50%; left: 50%; "
34     "transform: translate(-50%, -50%); width: 50px; height: 50px; "
35     "background-color: blue; -webkit-app-region: no-drag;\">"
36     "      </div>"
37     "    </div>"
38     "    <script>"
39     "      window.setTimeout(function() {"
40     "        var layer = document.getElementById('layer');"
41     "        layer.style.top = '0px';"
42     "        layer.style.left = '0px';"
43     "      }, 500);"
44     "    </script>"
45     "  </body>"
46     "</html>";
47 
48 class DraggableRegionsTestHandler : public TestHandler,
49                                     public CefDragHandler,
50                                     public CefFrameHandler {
51  public:
52   // Test steps executed in order.
53   enum Step {
54     // Nav 1: Two regions (get notification).
55     kStepWithRegions = 1,
56     // Nav 2: Starts with the same region as Nav 1 (no notification),
57     // then a changed region (get notification).
58     kStepWithChangingRegions,
59     // Nav 3: No regions (get notification).
60     kStepWithoutRegions,
61     // GoBack: Two regions (get notification), then a changed region (get
62     // notification). Note the first notification is not sent if
63     // BackForwardCache is enabled.
64     kStepWithChangingRegions2,
65     kStepWithChangingRegions3,
66     // GoForward: No regions (get notification).
67     kStepWithoutRegions2,
68 
69     kStepMax = kStepWithoutRegions2,
70   };
71 
DraggableRegionsTestHandler(bool same_origin)72   explicit DraggableRegionsTestHandler(bool same_origin)
73       : same_origin_(same_origin) {}
74 
RunTest()75   void RunTest() override {
76     // Add HTML documents with and without draggable regions.
77     AddResource(GetURL(kStepWithRegions), kTestHTMLWithRegions, "text/html");
78     AddResource(GetURL(kStepWithChangingRegions), kTestHTMLWithChangingRegions,
79                 "text/html");
80     AddResource(GetURL(kStepWithoutRegions), kTestHTMLWithoutRegions,
81                 "text/html");
82 
83     // Create the browser
84     CreateBrowser(GetURL(kStepWithRegions));
85 
86     // Time out the test after a reasonable period of time.
87     SetTestTimeout();
88   }
89 
GetDragHandler()90   CefRefPtr<CefDragHandler> GetDragHandler() override { return this; }
GetFrameHandler()91   CefRefPtr<CefFrameHandler> GetFrameHandler() override { return this; }
92 
OnDraggableRegionsChanged(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,const std::vector<CefDraggableRegion> & regions)93   void OnDraggableRegionsChanged(
94       CefRefPtr<CefBrowser> browser,
95       CefRefPtr<CefFrame> frame,
96       const std::vector<CefDraggableRegion>& regions) override {
97     EXPECT_UI_THREAD();
98     EXPECT_TRUE(browser->IsSame(GetBrowser()));
99     EXPECT_TRUE(frame->IsMain());
100 
101     draggable_regions_changed_ct_++;
102 
103     switch (step_) {
104       case kStepWithRegions:
105       case kStepWithChangingRegions2:
106         EXPECT_EQ(2U, regions.size());
107         EXPECT_NEAR(50, regions[0].bounds.x, 1);
108         EXPECT_NEAR(50, regions[0].bounds.y, 1);
109         EXPECT_NEAR(200, regions[0].bounds.width, 1);
110         EXPECT_NEAR(200, regions[0].bounds.height, 1);
111         EXPECT_EQ(1, regions[0].draggable);
112         EXPECT_NEAR(125, regions[1].bounds.x, 1);
113         EXPECT_NEAR(125, regions[1].bounds.y, 1);
114         EXPECT_NEAR(50, regions[1].bounds.width, 1);
115         EXPECT_NEAR(50, regions[1].bounds.height, 1);
116         EXPECT_EQ(0, regions[1].draggable);
117         break;
118       case kStepWithChangingRegions:
119       case kStepWithChangingRegions3:
120         EXPECT_EQ(2U, regions.size());
121         EXPECT_EQ(0, regions[0].bounds.x);
122         EXPECT_EQ(0, regions[0].bounds.y);
123         EXPECT_NEAR(200, regions[0].bounds.width, 1);
124         EXPECT_NEAR(200, regions[0].bounds.height, 1);
125         EXPECT_EQ(1, regions[0].draggable);
126         EXPECT_NEAR(75, regions[1].bounds.x, 1);
127         EXPECT_NEAR(75, regions[1].bounds.y, 1);
128         EXPECT_NEAR(50, regions[1].bounds.width, 2);
129         EXPECT_NEAR(50, regions[1].bounds.height, 2);
130         EXPECT_EQ(0, regions[1].draggable);
131         break;
132       case kStepWithoutRegions:
133       case kStepWithoutRegions2:
134         EXPECT_TRUE(regions.empty());
135         break;
136     }
137 
138     NextTest(browser);
139   }
140 
OnFrameAttached(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,bool reattached)141   void OnFrameAttached(CefRefPtr<CefBrowser> browser,
142                        CefRefPtr<CefFrame> frame,
143                        bool reattached) override {
144     EXPECT_UI_THREAD();
145     EXPECT_TRUE(browser->IsSame(GetBrowser()));
146     EXPECT_TRUE(frame->IsMain());
147 
148     if (reattached) {
149       // When BackForwardCache is enabled and we go back to
150       // kTestHTMLWithChangingRegions, draggable regions will already be in the
151       // final position because the page content is not reloaded.
152       if (step_ == kStepWithChangingRegions2) {
153         step_ = kStepWithChangingRegions3;
154         expected_draggable_regions_changed_ct_--;
155       }
156     }
157   }
158 
DestroyTest()159   void DestroyTest() override {
160     EXPECT_EQ(expected_draggable_regions_changed_ct_,
161               draggable_regions_changed_ct_);
162 
163     TestHandler::DestroyTest();
164   }
165 
166  private:
NextTest(CefRefPtr<CefBrowser> browser)167   void NextTest(CefRefPtr<CefBrowser> browser) {
168     CefRefPtr<CefFrame> frame(browser->GetMainFrame());
169 
170     switch (step_) {
171       case kStepWithRegions:
172         step_ = kStepWithChangingRegions;
173         frame->LoadURL(GetURL(kStepWithChangingRegions));
174         break;
175       case kStepWithChangingRegions:
176         step_ = kStepWithoutRegions;
177         frame->LoadURL(GetURL(kStepWithoutRegions));
178         break;
179       case kStepWithoutRegions: {
180         step_ = kStepWithChangingRegions2;
181         browser->GoBack();
182         break;
183       }
184       case kStepWithChangingRegions2: {
185         step_ = kStepWithChangingRegions3;
186         break;
187       }
188       case kStepWithChangingRegions3: {
189         step_ = kStepWithoutRegions2;
190         browser->GoForward();
191         break;
192       }
193       case kStepWithoutRegions2: {
194         DestroyTest();
195         break;
196       }
197     }
198   }
199 
GetURL(Step step) const200   std::string GetURL(Step step) const {
201     // When |same_origin_| is true every other URL gets a different origin.
202     switch (step) {
203       case kStepWithRegions:
204         return same_origin_ ? "http://test.com/regions"
205                             : "http://test2.com/regions";
206       case kStepWithChangingRegions:
207       case kStepWithChangingRegions2:
208       case kStepWithChangingRegions3:
209         return "http://test.com/changing-regions";
210       case kStepWithoutRegions:
211       case kStepWithoutRegions2:
212         return same_origin_ ? "http://test.com/no-regions"
213                             : "http://test2.com/no-regions";
214     }
215 
216     NOTREACHED();
217     return "";
218   }
219 
220   const bool same_origin_;
221 
222   Step step_ = kStepWithRegions;
223   int draggable_regions_changed_ct_ = 0;
224   int expected_draggable_regions_changed_ct_ = kStepMax;
225 
226   IMPLEMENT_REFCOUNTING(DraggableRegionsTestHandler);
227 };
228 
229 }  // namespace
230 
231 // Verify that draggable regions work in the same origin.
TEST(DraggableRegionsTest,DraggableRegionsSameOrigin)232 TEST(DraggableRegionsTest, DraggableRegionsSameOrigin) {
233   CefRefPtr<DraggableRegionsTestHandler> handler =
234       new DraggableRegionsTestHandler(/*same_origin=*/true);
235   handler->ExecuteTest();
236   ReleaseAndWaitForDestructor(handler);
237 }
238 
239 // Verify that draggable regions work cross-origin.
TEST(DraggableRegionsTest,DraggableRegionsCrossOrigin)240 TEST(DraggableRegionsTest, DraggableRegionsCrossOrigin) {
241   CefRefPtr<DraggableRegionsTestHandler> handler =
242       new DraggableRegionsTestHandler(/*same_origin=*/false);
243   handler->ExecuteTest();
244   ReleaseAndWaitForDestructor(handler);
245 }
246