1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32
33 #include "core/dom/Element.h"
34 #include "core/frame/FrameView.h"
35 #include "core/frame/Settings.h"
36 #include "core/html/HTMLSelectElement.h"
37 #include "core/page/EventHandler.h"
38 #include "platform/KeyboardCodes.h"
39 #include "platform/PlatformMouseEvent.h"
40 #include "platform/PopupMenu.h"
41 #include "platform/PopupMenuClient.h"
42 #include "platform/RuntimeEnabledFeatures.h"
43 #include "platform/graphics/Color.h"
44 #include "platform/scroll/ScrollbarTheme.h"
45 #include "public/platform/Platform.h"
46 #include "public/platform/WebScreenInfo.h"
47 #include "public/platform/WebString.h"
48 #include "public/platform/WebURL.h"
49 #include "public/platform/WebURLRequest.h"
50 #include "public/platform/WebURLResponse.h"
51 #include "public/platform/WebUnitTestSupport.h"
52 #include "public/web/WebDocument.h"
53 #include "public/web/WebElement.h"
54 #include "public/web/WebFrame.h"
55 #include "public/web/WebFrameClient.h"
56 #include "public/web/WebInputEvent.h"
57 #include "public/web/WebSettings.h"
58 #include "public/web/WebView.h"
59 #include "public/web/WebViewClient.h"
60 #include "v8.h"
61 #include "web/PopupContainer.h"
62 #include "web/PopupListBox.h"
63 #include "web/PopupMenuChromium.h"
64 #include "web/WebLocalFrameImpl.h"
65 #include "web/WebPopupMenuImpl.h"
66 #include "web/WebViewImpl.h"
67 #include "web/tests/FrameTestHelpers.h"
68 #include "web/tests/URLTestHelpers.h"
69 #include <gtest/gtest.h>
70
71 using namespace WebCore;
72 using namespace blink;
73 using blink::URLTestHelpers::toKURL;
74
75 namespace {
76
77 class TestPopupMenuClient : public PopupMenuClient {
78 public:
79 // Item at index 0 is selected by default.
TestPopupMenuClient()80 TestPopupMenuClient() : m_selectIndex(0), m_node(0), m_listSize(10) { }
~TestPopupMenuClient()81 virtual ~TestPopupMenuClient() {}
valueChanged(unsigned listIndex,bool fireEvents=true)82 virtual void valueChanged(unsigned listIndex, bool fireEvents = true)
83 {
84 m_selectIndex = listIndex;
85 if (m_node) {
86 HTMLSelectElement* select = toHTMLSelectElement(m_node);
87 select->optionSelectedByUser(select->listToOptionIndex(listIndex), fireEvents);
88 }
89 }
selectionChanged(unsigned,bool)90 virtual void selectionChanged(unsigned, bool) {}
selectionCleared()91 virtual void selectionCleared() {}
92
itemText(unsigned listIndex) const93 virtual String itemText(unsigned listIndex) const
94 {
95 String str("Item ");
96 str.append(String::number(listIndex));
97 return str;
98 }
itemLabel(unsigned) const99 virtual String itemLabel(unsigned) const { return String(); }
itemIcon(unsigned) const100 virtual String itemIcon(unsigned) const { return String(); }
itemToolTip(unsigned listIndex) const101 virtual String itemToolTip(unsigned listIndex) const { return itemText(listIndex); }
itemAccessibilityText(unsigned listIndex) const102 virtual String itemAccessibilityText(unsigned listIndex) const { return itemText(listIndex); }
itemIsEnabled(unsigned listIndex) const103 virtual bool itemIsEnabled(unsigned listIndex) const { return m_disabledIndexSet.find(listIndex) == m_disabledIndexSet.end(); }
itemStyle(unsigned listIndex) const104 virtual PopupMenuStyle itemStyle(unsigned listIndex) const
105 {
106 FontDescription fontDescription;
107 fontDescription.setComputedSize(12.0);
108 Font font(fontDescription);
109 font.update(nullptr);
110 return PopupMenuStyle(Color::black, Color::white, font, true, false, Length(), TextDirection(), false /* has text direction override */);
111 }
menuStyle() const112 virtual PopupMenuStyle menuStyle() const { return itemStyle(0); }
clientInsetLeft() const113 virtual int clientInsetLeft() const { return 0; }
clientInsetRight() const114 virtual int clientInsetRight() const { return 0; }
clientPaddingLeft() const115 virtual LayoutUnit clientPaddingLeft() const { return 0; }
clientPaddingRight() const116 virtual LayoutUnit clientPaddingRight() const { return 0; }
listSize() const117 virtual int listSize() const { return m_listSize; }
selectedIndex() const118 virtual int selectedIndex() const { return m_selectIndex; }
popupDidHide()119 virtual void popupDidHide() { }
itemIsSeparator(unsigned listIndex) const120 virtual bool itemIsSeparator(unsigned listIndex) const { return false; }
itemIsLabel(unsigned listIndex) const121 virtual bool itemIsLabel(unsigned listIndex) const { return false; }
itemIsSelected(unsigned listIndex) const122 virtual bool itemIsSelected(unsigned listIndex) const { return listIndex == m_selectIndex; }
valueShouldChangeOnHotTrack() const123 virtual bool valueShouldChangeOnHotTrack() const { return false; }
setTextFromItem(unsigned listIndex)124 virtual void setTextFromItem(unsigned listIndex) { }
125
fontSelector() const126 virtual FontSelector* fontSelector() const { return 0; }
hostWindow() const127 virtual HostWindow* hostWindow() const { return 0; }
128
createScrollbar(ScrollableArea *,ScrollbarOrientation,ScrollbarControlSize)129 virtual PassRefPtr<Scrollbar> createScrollbar(ScrollableArea*, ScrollbarOrientation, ScrollbarControlSize) { return nullptr; }
130
setDisabledIndex(unsigned index)131 void setDisabledIndex(unsigned index) { m_disabledIndexSet.insert(index); }
setFocusedNode(Node * node)132 void setFocusedNode(Node* node) { m_node = node; }
setListSize(int listSize)133 void setListSize(int listSize) { m_listSize = listSize; }
134
135 private:
136 unsigned m_selectIndex;
137 std::set<unsigned> m_disabledIndexSet;
138 Node* m_node;
139 int m_listSize;
140 };
141
142 class TestWebWidgetClient : public WebWidgetClient {
143 public:
~TestWebWidgetClient()144 ~TestWebWidgetClient() { }
145 };
146
147 class TestWebPopupMenuImpl : public WebPopupMenuImpl {
148 public:
create(WebWidgetClient * client)149 static PassRefPtr<TestWebPopupMenuImpl> create(WebWidgetClient* client)
150 {
151 return adoptRef(new TestWebPopupMenuImpl(client));
152 }
153
~TestWebPopupMenuImpl()154 ~TestWebPopupMenuImpl() { }
155
156 private:
TestWebPopupMenuImpl(WebWidgetClient * client)157 TestWebPopupMenuImpl(WebWidgetClient* client) : WebPopupMenuImpl(client) { }
158 };
159
160 class PopupTestWebViewClient : public FrameTestHelpers::TestWebViewClient {
161 public:
PopupTestWebViewClient()162 PopupTestWebViewClient() : m_webPopupMenu(TestWebPopupMenuImpl::create(&m_webWidgetClient)) { }
~PopupTestWebViewClient()163 ~PopupTestWebViewClient() { }
164
createPopupMenu(WebPopupType)165 virtual WebWidget* createPopupMenu(WebPopupType) { return m_webPopupMenu.get(); }
166
167 // We need to override this so that the popup menu size is not 0
168 // (the layout code checks to see if the popup fits on the screen).
screenInfo()169 virtual WebScreenInfo screenInfo()
170 {
171 WebScreenInfo screenInfo;
172 screenInfo.availableRect.height = 2000;
173 screenInfo.availableRect.width = 2000;
174 return screenInfo;
175 }
176
177 private:
178 TestWebWidgetClient m_webWidgetClient;
179 RefPtr<TestWebPopupMenuImpl> m_webPopupMenu;
180 };
181
182 class SelectPopupMenuTest : public testing::Test {
183 public:
SelectPopupMenuTest()184 SelectPopupMenuTest()
185 : baseURL("http://www.test.com/")
186 {
187 }
188
189 protected:
SetUp()190 virtual void SetUp()
191 {
192 m_helper.initialize(false, 0, &m_webviewClient);
193 m_popupMenu = adoptRef(new PopupMenuChromium(*mainFrame()->frame(), &m_popupMenuClient));
194 }
195
TearDown()196 virtual void TearDown()
197 {
198 m_popupMenu = nullptr;
199 Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
200 }
201
202 // Returns true if there currently is a select popup in the WebView.
popupOpen() const203 bool popupOpen() const { return webView()->selectPopup(); }
204
selectedIndex() const205 int selectedIndex() const { return m_popupMenuClient.selectedIndex(); }
206
showPopup()207 void showPopup()
208 {
209 m_popupMenu->show(FloatQuad(FloatRect(0, 0, 100, 100)), IntSize(100, 100), 0);
210 ASSERT_TRUE(popupOpen());
211 }
212
hidePopup()213 void hidePopup()
214 {
215 m_popupMenu->hide();
216 EXPECT_FALSE(popupOpen());
217 }
218
simulateKeyDownEvent(int keyCode)219 void simulateKeyDownEvent(int keyCode)
220 {
221 simulateKeyEvent(WebInputEvent::RawKeyDown, keyCode);
222 }
223
simulateKeyUpEvent(int keyCode)224 void simulateKeyUpEvent(int keyCode)
225 {
226 simulateKeyEvent(WebInputEvent::KeyUp, keyCode);
227 }
228
229 // Simulates a key event on the WebView.
230 // The WebView forwards the event to the select popup if one is open.
simulateKeyEvent(WebInputEvent::Type eventType,int keyCode)231 void simulateKeyEvent(WebInputEvent::Type eventType, int keyCode)
232 {
233 WebKeyboardEvent keyEvent;
234 keyEvent.windowsKeyCode = keyCode;
235 keyEvent.type = eventType;
236 webView()->handleInputEvent(keyEvent);
237 }
238
239 // Simulates a mouse event on the select popup.
simulateLeftMouseDownEvent(const IntPoint & point)240 void simulateLeftMouseDownEvent(const IntPoint& point)
241 {
242 PlatformMouseEvent mouseEvent(point, point, LeftButton, PlatformEvent::MousePressed,
243 1, false, false, false, false, 0);
244 webView()->selectPopup()->handleMouseDownEvent(mouseEvent);
245 }
simulateLeftMouseUpEvent(const IntPoint & point)246 void simulateLeftMouseUpEvent(const IntPoint& point)
247 {
248 PlatformMouseEvent mouseEvent(point, point, LeftButton, PlatformEvent::MouseReleased,
249 1, false, false, false, false, 0);
250 webView()->selectPopup()->handleMouseReleaseEvent(mouseEvent);
251 }
252
registerMockedURLLoad(const std::string & fileName)253 void registerMockedURLLoad(const std::string& fileName)
254 {
255 URLTestHelpers::registerMockedURLLoad(toKURL(baseURL + fileName), WebString::fromUTF8(fileName.c_str()), WebString::fromUTF8("popup/"), WebString::fromUTF8("text/html"));
256 }
257
loadFrame(WebFrame * frame,const std::string & fileName)258 void loadFrame(WebFrame* frame, const std::string& fileName)
259 {
260 FrameTestHelpers::loadFrame(frame, baseURL + fileName);
261 }
262
webView() const263 WebViewImpl* webView() const { return m_helper.webViewImpl(); }
mainFrame() const264 WebLocalFrameImpl* mainFrame() const { return m_helper.webViewImpl()->mainFrameImpl(); }
265
266 protected:
267 PopupTestWebViewClient m_webviewClient;
268 TestPopupMenuClient m_popupMenuClient;
269 RefPtr<PopupMenu> m_popupMenu;
270 std::string baseURL;
271
272 private:
273 FrameTestHelpers::WebViewHelper m_helper;
274 };
275
276 // Tests that show/hide and repeats. Select popups are reused in web pages when
277 // they are reopened, that what this is testing.
TEST_F(SelectPopupMenuTest,ShowThenHide)278 TEST_F(SelectPopupMenuTest, ShowThenHide)
279 {
280 for (int i = 0; i < 3; i++) {
281 showPopup();
282 hidePopup();
283 }
284 }
285
286 // Tests that showing a select popup and deleting it does not cause problem.
287 // This happens in real-life if a page navigates while a select popup is showing.
TEST_F(SelectPopupMenuTest,ShowThenDelete)288 TEST_F(SelectPopupMenuTest, ShowThenDelete)
289 {
290 showPopup();
291 // Nothing else to do, TearDown() deletes the popup.
292 }
293
294 // Tests that losing focus closes the select popup.
TEST_F(SelectPopupMenuTest,ShowThenLoseFocus)295 TEST_F(SelectPopupMenuTest, ShowThenLoseFocus)
296 {
297 showPopup();
298 // Simulate losing focus.
299 webView()->setFocus(false);
300
301 // Popup should have closed.
302 EXPECT_FALSE(popupOpen());
303 }
304
305 // Tests that pressing ESC closes the popup.
TEST_F(SelectPopupMenuTest,ShowThenPressESC)306 TEST_F(SelectPopupMenuTest, ShowThenPressESC)
307 {
308 showPopup();
309 simulateKeyDownEvent(VKEY_ESCAPE);
310 // Popup should have closed.
311 EXPECT_FALSE(popupOpen());
312 }
313
314 // Tests selecting an item with the arrows and enter/esc/tab.
TEST_F(SelectPopupMenuTest,SelectWithKeys)315 TEST_F(SelectPopupMenuTest, SelectWithKeys)
316 {
317 showPopup();
318 // Simulate selecting the 2nd item by pressing Down, Down, enter.
319 simulateKeyDownEvent(VKEY_DOWN);
320 simulateKeyDownEvent(VKEY_DOWN);
321 simulateKeyDownEvent(VKEY_RETURN);
322
323 // Popup should have closed.
324 EXPECT_TRUE(!popupOpen());
325 EXPECT_EQ(2, selectedIndex());
326
327 // It should work as well with ESC.
328 showPopup();
329 simulateKeyDownEvent(VKEY_DOWN);
330 simulateKeyDownEvent(VKEY_ESCAPE);
331 EXPECT_FALSE(popupOpen());
332 EXPECT_EQ(3, selectedIndex());
333
334 // It should work as well with TAB.
335 showPopup();
336 simulateKeyDownEvent(VKEY_DOWN);
337 simulateKeyDownEvent(VKEY_TAB);
338 EXPECT_FALSE(popupOpen());
339 EXPECT_EQ(4, selectedIndex());
340 }
341
342 // Tests that selecting an item with the mouse does select the item and close
343 // the popup.
TEST_F(SelectPopupMenuTest,ClickItem)344 TEST_F(SelectPopupMenuTest, ClickItem)
345 {
346 showPopup();
347
348 int menuItemHeight = webView()->selectPopup()->menuItemHeight();
349 // menuItemHeight * 1.5 means the Y position on the item at index 1.
350 IntPoint row1Point(2, menuItemHeight * 1.5);
351 // Simulate a click down/up on the first item.
352 simulateLeftMouseDownEvent(row1Point);
353 simulateLeftMouseUpEvent(row1Point);
354
355 // Popup should have closed and the item at index 1 selected.
356 EXPECT_FALSE(popupOpen());
357 EXPECT_EQ(1, selectedIndex());
358 }
359
360 // Tests that moving the mouse over an item and then clicking outside the select popup
361 // leaves the seleted item unchanged.
TEST_F(SelectPopupMenuTest,MouseOverItemClickOutside)362 TEST_F(SelectPopupMenuTest, MouseOverItemClickOutside)
363 {
364 showPopup();
365
366 int menuItemHeight = webView()->selectPopup()->menuItemHeight();
367 // menuItemHeight * 1.5 means the Y position on the item at index 1.
368 IntPoint row1Point(2, menuItemHeight * 1.5);
369 // Simulate the mouse moving over the first item.
370 PlatformMouseEvent mouseEvent(row1Point, row1Point, NoButton, PlatformEvent::MouseMoved,
371 1, false, false, false, false, 0);
372 webView()->selectPopup()->handleMouseMoveEvent(mouseEvent);
373
374 // Click outside the popup.
375 simulateLeftMouseDownEvent(IntPoint(1000, 1000));
376
377 // Popup should have closed and item 0 should still be selected.
378 EXPECT_FALSE(popupOpen());
379 EXPECT_EQ(0, selectedIndex());
380 }
381
382 // Tests that selecting an item with the keyboard and then clicking outside the select
383 // popup does select that item.
TEST_F(SelectPopupMenuTest,SelectItemWithKeyboardItemClickOutside)384 TEST_F(SelectPopupMenuTest, SelectItemWithKeyboardItemClickOutside)
385 {
386 showPopup();
387
388 // Simulate selecting the 2nd item by pressing Down, Down.
389 simulateKeyDownEvent(VKEY_DOWN);
390 simulateKeyDownEvent(VKEY_DOWN);
391
392 // Click outside the popup.
393 simulateLeftMouseDownEvent(IntPoint(1000, 1000));
394
395 // Popup should have closed and the item should have been selected.
396 EXPECT_FALSE(popupOpen());
397 EXPECT_EQ(2, selectedIndex());
398 }
399
TEST_F(SelectPopupMenuTest,DISABLED_SelectItemEventFire)400 TEST_F(SelectPopupMenuTest, DISABLED_SelectItemEventFire)
401 {
402 registerMockedURLLoad("select_event.html");
403 webView()->settings()->setJavaScriptEnabled(true);
404 loadFrame(mainFrame(), "select_event.html");
405
406 m_popupMenuClient.setFocusedNode(mainFrame()->frame()->document()->focusedElement());
407
408 showPopup();
409
410 int menuItemHeight = webView()->selectPopup()->menuItemHeight();
411 // menuItemHeight * 0.5 means the Y position on the item at index 0.
412 IntPoint row1Point(2, menuItemHeight * 0.5);
413 simulateLeftMouseDownEvent(row1Point);
414 simulateLeftMouseUpEvent(row1Point);
415
416 WebElement element = webView()->mainFrame()->document().getElementById("message");
417
418 // mousedown event is held by select node, and we don't simulate the event for the node.
419 // So we can only see mouseup and click event.
420 EXPECT_STREQ("upclick", element.innerText().utf8().data());
421
422 // Disable the item at index 1.
423 m_popupMenuClient.setDisabledIndex(1);
424
425 showPopup();
426 // menuItemHeight * 1.5 means the Y position on the item at index 1.
427 row1Point.setY(menuItemHeight * 1.5);
428 simulateLeftMouseDownEvent(row1Point);
429 simulateLeftMouseUpEvent(row1Point);
430
431 // The item at index 1 is disabled, so the text should not be changed.
432 EXPECT_STREQ("upclick", element.innerText().utf8().data());
433
434 showPopup();
435 // menuItemHeight * 2.5 means the Y position on the item at index 2.
436 row1Point.setY(menuItemHeight * 2.5);
437 simulateLeftMouseDownEvent(row1Point);
438 simulateLeftMouseUpEvent(row1Point);
439
440 // The item is changed to the item at index 2, from index 0, so change event is fired.
441 EXPECT_STREQ("upclickchangeupclick", element.innerText().utf8().data());
442 }
443
TEST_F(SelectPopupMenuTest,FLAKY_SelectItemKeyEvent)444 TEST_F(SelectPopupMenuTest, FLAKY_SelectItemKeyEvent)
445 {
446 registerMockedURLLoad("select_event.html");
447 webView()->settings()->setJavaScriptEnabled(true);
448 loadFrame(mainFrame(), "select_event.html");
449
450 m_popupMenuClient.setFocusedNode(mainFrame()->frame()->document()->focusedElement());
451
452 showPopup();
453
454 // Siumulate to choose the item at index 1 with keyboard.
455 simulateKeyDownEvent(VKEY_DOWN);
456 simulateKeyDownEvent(VKEY_DOWN);
457 simulateKeyDownEvent(VKEY_RETURN);
458
459 WebElement element = webView()->mainFrame()->document().getElementById("message");
460 // We only can see change event but no other mouse related events.
461 EXPECT_STREQ("change", element.innerText().utf8().data());
462 }
463
TEST_F(SelectPopupMenuTest,SelectItemRemoveSelectOnChange)464 TEST_F(SelectPopupMenuTest, SelectItemRemoveSelectOnChange)
465 {
466 // Make sure no crash, even if select node is removed on 'change' event handler.
467 registerMockedURLLoad("select_event_remove_on_change.html");
468 webView()->settings()->setJavaScriptEnabled(true);
469 loadFrame(mainFrame(), "select_event_remove_on_change.html");
470
471 m_popupMenuClient.setFocusedNode(mainFrame()->frame()->document()->focusedElement());
472
473 showPopup();
474
475 int menuItemHeight = webView()->selectPopup()->menuItemHeight();
476 // menuItemHeight * 1.5 means the Y position on the item at index 1.
477 IntPoint row1Point(2, menuItemHeight * 1.5);
478 simulateLeftMouseDownEvent(row1Point);
479 simulateLeftMouseUpEvent(row1Point);
480
481 WebElement element = webView()->mainFrame()->document().getElementById("message");
482 EXPECT_STREQ("change", element.innerText().utf8().data());
483 }
484
TEST_F(SelectPopupMenuTest,SelectItemRemoveSelectOnClick)485 TEST_F(SelectPopupMenuTest, SelectItemRemoveSelectOnClick)
486 {
487 // Make sure no crash, even if select node is removed on 'click' event handler.
488 registerMockedURLLoad("select_event_remove_on_click.html");
489 webView()->settings()->setJavaScriptEnabled(true);
490 loadFrame(mainFrame(), "select_event_remove_on_click.html");
491
492 m_popupMenuClient.setFocusedNode(mainFrame()->frame()->document()->focusedElement());
493
494 showPopup();
495
496 int menuItemHeight = webView()->selectPopup()->menuItemHeight();
497 // menuItemHeight * 1.5 means the Y position on the item at index 1.
498 IntPoint row1Point(2, menuItemHeight * 1.5);
499 simulateLeftMouseDownEvent(row1Point);
500 simulateLeftMouseUpEvent(row1Point);
501
502 WebElement element = webView()->mainFrame()->document().getElementById("message");
503 EXPECT_STREQ("click", element.innerText().utf8().data());
504 }
505
506 #if OS(ANDROID)
TEST_F(SelectPopupMenuTest,DISABLED_PopupListBoxWithOverlayScrollbarEnabled)507 TEST_F(SelectPopupMenuTest, DISABLED_PopupListBoxWithOverlayScrollbarEnabled)
508 #else
509 TEST_F(SelectPopupMenuTest, PopupListBoxWithOverlayScrollbarEnabled)
510 #endif
511 {
512 Settings::setMockScrollbarsEnabled(true);
513 RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(true);
514 EXPECT_TRUE(ScrollbarTheme::theme()->usesOverlayScrollbars());
515 registerMockedURLLoad("select_rtl.html");
516 loadFrame(mainFrame(), "select_rtl.html");
517
518 m_popupMenuClient.setFocusedNode(mainFrame()->frame()->document()->focusedElement());
519 m_popupMenuClient.setListSize(30);
520
521 showPopup();
522 PopupContainer* container = webView()->selectPopup();
523 PopupListBox* listBox = container->listBox();
524
525 EXPECT_EQ(container->width(), listBox->contentsSize().width() + 2);
526 Settings::setMockScrollbarsEnabled(false);
527 RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(false);
528 EXPECT_FALSE(ScrollbarTheme::theme()->usesOverlayScrollbars());
529 }
530
531 #if OS(ANDROID)
TEST_F(SelectPopupMenuTest,DISABLED_PopupListBoxWithOverlayScrollbarDisabled)532 TEST_F(SelectPopupMenuTest, DISABLED_PopupListBoxWithOverlayScrollbarDisabled)
533 #else
534 TEST_F(SelectPopupMenuTest, PopupListBoxWithOverlayScrollbarDisabled)
535 #endif
536 {
537 EXPECT_FALSE(ScrollbarTheme::theme()->usesOverlayScrollbars());
538 registerMockedURLLoad("select_rtl.html");
539 loadFrame(mainFrame(), "select_rtl.html");
540
541 m_popupMenuClient.setFocusedNode(mainFrame()->frame()->document()->focusedElement());
542 m_popupMenuClient.setListSize(30);
543
544 showPopup();
545 PopupContainer* container = webView()->selectPopup();
546 PopupListBox* listBox = container->listBox();
547
548 EXPECT_EQ(container->width(), listBox->contentsSize().width() + ScrollbarTheme::theme()->scrollbarThickness() + 2);
549 }
550
551 } // namespace
552