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 #include "platform/PopupMenu.h" 33 34 #include "core/dom/Element.h" 35 #include "core/frame/FrameView.h" 36 #include "core/frame/Settings.h" 37 #include "core/html/HTMLSelectElement.h" 38 #include "core/page/EventHandler.h" 39 #include "core/rendering/RenderMenuList.h" 40 #include "core/testing/URLTestHelpers.h" 41 #include "platform/KeyboardCodes.h" 42 #include "platform/PlatformMouseEvent.h" 43 #include "platform/PopupMenuClient.h" 44 #include "platform/RuntimeEnabledFeatures.h" 45 #include "platform/graphics/Color.h" 46 #include "platform/scroll/ScrollbarTheme.h" 47 #include "public/platform/Platform.h" 48 #include "public/platform/WebScreenInfo.h" 49 #include "public/platform/WebString.h" 50 #include "public/platform/WebURL.h" 51 #include "public/platform/WebURLRequest.h" 52 #include "public/platform/WebURLResponse.h" 53 #include "public/platform/WebUnitTestSupport.h" 54 #include "public/web/WebDocument.h" 55 #include "public/web/WebElement.h" 56 #include "public/web/WebFrame.h" 57 #include "public/web/WebFrameClient.h" 58 #include "public/web/WebInputEvent.h" 59 #include "public/web/WebSettings.h" 60 #include "public/web/WebView.h" 61 #include "public/web/WebViewClient.h" 62 #include "v8.h" 63 #include "web/PopupContainer.h" 64 #include "web/PopupListBox.h" 65 #include "web/PopupMenuChromium.h" 66 #include "web/WebLocalFrameImpl.h" 67 #include "web/WebPopupMenuImpl.h" 68 #include "web/WebViewImpl.h" 69 #include "web/tests/FrameTestHelpers.h" 70 #include <gtest/gtest.h> 71 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. 80 TestPopupMenuClient() : m_selectIndex(0), m_node(0), m_listSize(10) { } 81 virtual ~TestPopupMenuClient() { } 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 } 90 virtual void selectionChanged(unsigned, bool) { } 91 virtual void selectionCleared() { } 92 93 virtual String itemText(unsigned listIndex) const 94 { 95 String str("Item "); 96 str.append(String::number(listIndex)); 97 return str; 98 } 99 virtual String itemLabel(unsigned) const { return String(); } 100 virtual String itemIcon(unsigned) const { return String(); } 101 virtual String itemToolTip(unsigned listIndex) const { return itemText(listIndex); } 102 virtual String itemAccessibilityText(unsigned listIndex) const { return itemText(listIndex); } 103 virtual bool itemIsEnabled(unsigned listIndex) const { return m_disabledIndexSet.find(listIndex) == m_disabledIndexSet.end(); } 104 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 } 112 virtual PopupMenuStyle menuStyle() const { return itemStyle(0); } 113 virtual int clientInsetLeft() const { return 0; } 114 virtual int clientInsetRight() const { return 0; } 115 virtual LayoutUnit clientPaddingLeft() const { return 0; } 116 virtual LayoutUnit clientPaddingRight() const { return 0; } 117 virtual int listSize() const { return m_listSize; } 118 virtual int selectedIndex() const { return m_selectIndex; } 119 virtual void popupDidHide() { } 120 virtual bool itemIsSeparator(unsigned listIndex) const { return false; } 121 virtual bool itemIsLabel(unsigned listIndex) const { return false; } 122 virtual bool itemIsSelected(unsigned listIndex) const { return listIndex == m_selectIndex; } 123 virtual bool valueShouldChangeOnHotTrack() const { return false; } 124 virtual void setTextFromItem(unsigned listIndex) { } 125 126 virtual FontSelector* fontSelector() const { return 0; } 127 virtual HostWindow* hostWindow() const { return 0; } 128 129 virtual PassRefPtr<Scrollbar> createScrollbar(ScrollableArea*, ScrollbarOrientation, ScrollbarControlSize) { return nullptr; } 130 131 void setDisabledIndex(unsigned index) { m_disabledIndexSet.insert(index); } 132 void setFocusedNode(Node* node) { m_node = node; } 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: 144 ~TestWebWidgetClient() { } 145 }; 146 147 class TestWebPopupMenuImpl : public WebPopupMenuImpl { 148 public: 149 static PassRefPtr<TestWebPopupMenuImpl> create(WebWidgetClient* client) 150 { 151 return adoptRef(new TestWebPopupMenuImpl(client)); 152 } 153 154 ~TestWebPopupMenuImpl() { } 155 156 private: 157 TestWebPopupMenuImpl(WebWidgetClient* client) : WebPopupMenuImpl(client) { } 158 }; 159 160 class PopupTestWebViewClient : public FrameTestHelpers::TestWebViewClient { 161 public: 162 PopupTestWebViewClient() : m_webPopupMenu(TestWebPopupMenuImpl::create(&m_webWidgetClient)) { } 163 ~PopupTestWebViewClient() { } 164 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). 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: 184 SelectPopupMenuTest() 185 : baseURL("http://www.test.com/") 186 { 187 } 188 189 protected: 190 virtual void SetUp() 191 { 192 m_helper.initialize(false, 0, &m_webviewClient); 193 m_popupMenu = adoptRefWillBeNoop(new PopupMenuChromium(*mainFrame()->frame(), &m_popupMenuClient)); 194 } 195 196 virtual void TearDown() 197 { 198 Platform::current()->unitTestSupport()->unregisterAllMockedURLs(); 199 } 200 201 // Returns true if there currently is a select popup in the WebView. 202 bool popupOpen() const { return webView()->selectPopup(); } 203 204 int selectedIndex() const { return m_popupMenuClient.selectedIndex(); } 205 206 void showPopup() 207 { 208 m_popupMenu->show(FloatQuad(FloatRect(0, 0, 100, 100)), IntSize(100, 100), 0); 209 ASSERT_TRUE(popupOpen()); 210 } 211 212 void hidePopup() 213 { 214 m_popupMenu->hide(); 215 EXPECT_FALSE(popupOpen()); 216 } 217 218 void simulateKeyDownEvent(int keyCode) 219 { 220 simulateKeyEvent(WebInputEvent::RawKeyDown, keyCode); 221 } 222 223 void simulateKeyUpEvent(int keyCode) 224 { 225 simulateKeyEvent(WebInputEvent::KeyUp, keyCode); 226 } 227 228 // Simulates a key event on the WebView. 229 // The WebView forwards the event to the select popup if one is open. 230 void simulateKeyEvent(WebInputEvent::Type eventType, int keyCode) 231 { 232 WebKeyboardEvent keyEvent; 233 keyEvent.windowsKeyCode = keyCode; 234 keyEvent.type = eventType; 235 webView()->handleInputEvent(keyEvent); 236 } 237 238 // Simulates a mouse event on the select popup. 239 void simulateLeftMouseDownEvent(const IntPoint& point) 240 { 241 PlatformMouseEvent mouseEvent(point, point, LeftButton, PlatformEvent::MousePressed, 242 1, false, false, false, false, PlatformMouseEvent::RealOrIndistinguishable, 0); 243 webView()->selectPopup()->handleMouseDownEvent(mouseEvent); 244 } 245 void simulateLeftMouseUpEvent(const IntPoint& point) 246 { 247 PlatformMouseEvent mouseEvent(point, point, LeftButton, PlatformEvent::MouseReleased, 248 1, false, false, false, false, PlatformMouseEvent::RealOrIndistinguishable, 0); 249 webView()->selectPopup()->handleMouseReleaseEvent(mouseEvent); 250 } 251 252 void registerMockedURLLoad(const std::string& fileName) 253 { 254 URLTestHelpers::registerMockedURLLoad(toKURL(baseURL + fileName), WebString::fromUTF8(fileName.c_str()), WebString::fromUTF8("popup/"), WebString::fromUTF8("text/html")); 255 } 256 257 void loadFrame(WebFrame* frame, const std::string& fileName) 258 { 259 FrameTestHelpers::loadFrame(frame, baseURL + fileName); 260 } 261 262 WebViewImpl* webView() const { return m_helper.webViewImpl(); } 263 WebLocalFrameImpl* mainFrame() const { return m_helper.webViewImpl()->mainFrameImpl(); } 264 265 protected: 266 PopupTestWebViewClient m_webviewClient; 267 TestPopupMenuClient m_popupMenuClient; 268 RefPtrWillBePersistent<PopupMenu> m_popupMenu; 269 std::string baseURL; 270 271 private: 272 FrameTestHelpers::WebViewHelper m_helper; 273 }; 274 275 // Tests that show/hide and repeats. Select popups are reused in web pages when 276 // they are reopened, that what this is testing. 277 TEST_F(SelectPopupMenuTest, ShowThenHide) 278 { 279 for (int i = 0; i < 3; i++) { 280 showPopup(); 281 hidePopup(); 282 } 283 } 284 285 // Tests that showing a select popup and deleting it does not cause problem. 286 // This happens in real-life if a page navigates while a select popup is showing. 287 TEST_F(SelectPopupMenuTest, ShowThenDelete) 288 { 289 showPopup(); 290 // Nothing else to do, TearDown() deletes the popup. 291 } 292 293 // Tests that losing focus closes the select popup. 294 TEST_F(SelectPopupMenuTest, ShowThenLoseFocus) 295 { 296 showPopup(); 297 // Simulate losing focus. 298 webView()->setFocus(false); 299 300 // Popup should have closed. 301 EXPECT_FALSE(popupOpen()); 302 } 303 304 // Tests that pressing ESC closes the popup. 305 TEST_F(SelectPopupMenuTest, ShowThenPressESC) 306 { 307 showPopup(); 308 simulateKeyDownEvent(VKEY_ESCAPE); 309 // Popup should have closed. 310 EXPECT_FALSE(popupOpen()); 311 } 312 313 // Tests selecting an item with the arrows and enter/esc/tab. 314 TEST_F(SelectPopupMenuTest, SelectWithKeys) 315 { 316 showPopup(); 317 // Simulate selecting the 2nd item by pressing Down, Down, enter. 318 simulateKeyDownEvent(VKEY_DOWN); 319 simulateKeyDownEvent(VKEY_DOWN); 320 simulateKeyDownEvent(VKEY_RETURN); 321 322 // Popup should have closed. 323 EXPECT_TRUE(!popupOpen()); 324 EXPECT_EQ(2, selectedIndex()); 325 326 // It should work as well with ESC. 327 showPopup(); 328 simulateKeyDownEvent(VKEY_DOWN); 329 simulateKeyDownEvent(VKEY_ESCAPE); 330 EXPECT_FALSE(popupOpen()); 331 EXPECT_EQ(3, selectedIndex()); 332 333 // It should work as well with TAB. 334 showPopup(); 335 simulateKeyDownEvent(VKEY_DOWN); 336 simulateKeyDownEvent(VKEY_TAB); 337 EXPECT_FALSE(popupOpen()); 338 EXPECT_EQ(4, selectedIndex()); 339 } 340 341 // Tests that selecting an item with the mouse does select the item and close 342 // the popup. 343 TEST_F(SelectPopupMenuTest, ClickItem) 344 { 345 showPopup(); 346 347 int menuItemHeight = webView()->selectPopup()->menuItemHeight(); 348 // menuItemHeight * 1.5 means the Y position on the item at index 1. 349 IntPoint row1Point(2, menuItemHeight * 1.5); 350 // Simulate a click down/up on the first item. 351 simulateLeftMouseDownEvent(row1Point); 352 simulateLeftMouseUpEvent(row1Point); 353 354 // Popup should have closed and the item at index 1 selected. 355 EXPECT_FALSE(popupOpen()); 356 EXPECT_EQ(1, selectedIndex()); 357 } 358 359 // Tests that moving the mouse over an item and then clicking outside the select popup 360 // leaves the seleted item unchanged. 361 TEST_F(SelectPopupMenuTest, MouseOverItemClickOutside) 362 { 363 showPopup(); 364 365 int menuItemHeight = webView()->selectPopup()->menuItemHeight(); 366 // menuItemHeight * 1.5 means the Y position on the item at index 1. 367 IntPoint row1Point(2, menuItemHeight * 1.5); 368 // Simulate the mouse moving over the first item. 369 PlatformMouseEvent mouseEvent(row1Point, row1Point, NoButton, PlatformEvent::MouseMoved, 370 1, false, false, false, false, PlatformMouseEvent::RealOrIndistinguishable, 0); 371 webView()->selectPopup()->handleMouseMoveEvent(mouseEvent); 372 373 // Click outside the popup. 374 simulateLeftMouseDownEvent(IntPoint(1000, 1000)); 375 376 // Popup should have closed and item 0 should still be selected. 377 EXPECT_FALSE(popupOpen()); 378 EXPECT_EQ(0, selectedIndex()); 379 } 380 381 // Tests that selecting an item with the keyboard and then clicking outside the select 382 // popup does select that item. 383 TEST_F(SelectPopupMenuTest, SelectItemWithKeyboardItemClickOutside) 384 { 385 showPopup(); 386 387 // Simulate selecting the 2nd item by pressing Down, Down. 388 simulateKeyDownEvent(VKEY_DOWN); 389 simulateKeyDownEvent(VKEY_DOWN); 390 391 // Click outside the popup. 392 simulateLeftMouseDownEvent(IntPoint(1000, 1000)); 393 394 // Popup should have closed and the item should have been selected. 395 EXPECT_FALSE(popupOpen()); 396 EXPECT_EQ(2, selectedIndex()); 397 } 398 399 TEST_F(SelectPopupMenuTest, DISABLED_SelectItemEventFire) 400 { 401 registerMockedURLLoad("select_event.html"); 402 webView()->settings()->setJavaScriptEnabled(true); 403 loadFrame(mainFrame(), "select_event.html"); 404 405 m_popupMenuClient.setFocusedNode(mainFrame()->frame()->document()->focusedElement()); 406 407 showPopup(); 408 409 int menuItemHeight = webView()->selectPopup()->menuItemHeight(); 410 // menuItemHeight * 0.5 means the Y position on the item at index 0. 411 IntPoint row1Point(2, menuItemHeight * 0.5); 412 simulateLeftMouseDownEvent(row1Point); 413 simulateLeftMouseUpEvent(row1Point); 414 415 WebElement element = webView()->mainFrame()->document().getElementById("message"); 416 417 // mousedown event is held by select node, and we don't simulate the event for the node. 418 // So we can only see mouseup and click event. 419 EXPECT_STREQ("upclick", element.innerText().utf8().data()); 420 421 // Disable the item at index 1. 422 m_popupMenuClient.setDisabledIndex(1); 423 424 showPopup(); 425 // menuItemHeight * 1.5 means the Y position on the item at index 1. 426 row1Point.setY(menuItemHeight * 1.5); 427 simulateLeftMouseDownEvent(row1Point); 428 simulateLeftMouseUpEvent(row1Point); 429 430 // The item at index 1 is disabled, so the text should not be changed. 431 EXPECT_STREQ("upclick", element.innerText().utf8().data()); 432 433 showPopup(); 434 // menuItemHeight * 2.5 means the Y position on the item at index 2. 435 row1Point.setY(menuItemHeight * 2.5); 436 simulateLeftMouseDownEvent(row1Point); 437 simulateLeftMouseUpEvent(row1Point); 438 439 // The item is changed to the item at index 2, from index 0, so change event is fired. 440 EXPECT_STREQ("upclickchangeupclick", element.innerText().utf8().data()); 441 } 442 443 TEST_F(SelectPopupMenuTest, FLAKY_SelectItemKeyEvent) 444 { 445 registerMockedURLLoad("select_event.html"); 446 webView()->settings()->setJavaScriptEnabled(true); 447 loadFrame(mainFrame(), "select_event.html"); 448 449 m_popupMenuClient.setFocusedNode(mainFrame()->frame()->document()->focusedElement()); 450 451 showPopup(); 452 453 // Siumulate to choose the item at index 1 with keyboard. 454 simulateKeyDownEvent(VKEY_DOWN); 455 simulateKeyDownEvent(VKEY_DOWN); 456 simulateKeyDownEvent(VKEY_RETURN); 457 458 WebElement element = webView()->mainFrame()->document().getElementById("message"); 459 // We only can see change event but no other mouse related events. 460 EXPECT_STREQ("change", element.innerText().utf8().data()); 461 } 462 463 TEST_F(SelectPopupMenuTest, SelectItemRemoveSelectOnChange) 464 { 465 // Make sure no crash, even if select node is removed on 'change' event handler. 466 registerMockedURLLoad("select_event_remove_on_change.html"); 467 webView()->settings()->setJavaScriptEnabled(true); 468 loadFrame(mainFrame(), "select_event_remove_on_change.html"); 469 470 m_popupMenuClient.setFocusedNode(mainFrame()->frame()->document()->focusedElement()); 471 472 showPopup(); 473 474 int menuItemHeight = webView()->selectPopup()->menuItemHeight(); 475 // menuItemHeight * 1.5 means the Y position on the item at index 1. 476 IntPoint row1Point(2, menuItemHeight * 1.5); 477 simulateLeftMouseDownEvent(row1Point); 478 simulateLeftMouseUpEvent(row1Point); 479 480 WebElement element = webView()->mainFrame()->document().getElementById("message"); 481 EXPECT_STREQ("change", element.innerText().utf8().data()); 482 } 483 484 TEST_F(SelectPopupMenuTest, SelectItemRemoveSelectOnClick) 485 { 486 // Make sure no crash, even if select node is removed on 'click' event handler. 487 registerMockedURLLoad("select_event_remove_on_click.html"); 488 webView()->settings()->setJavaScriptEnabled(true); 489 loadFrame(mainFrame(), "select_event_remove_on_click.html"); 490 491 m_popupMenuClient.setFocusedNode(mainFrame()->frame()->document()->focusedElement()); 492 493 showPopup(); 494 495 int menuItemHeight = webView()->selectPopup()->menuItemHeight(); 496 // menuItemHeight * 1.5 means the Y position on the item at index 1. 497 IntPoint row1Point(2, menuItemHeight * 1.5); 498 simulateLeftMouseDownEvent(row1Point); 499 simulateLeftMouseUpEvent(row1Point); 500 501 WebElement element = webView()->mainFrame()->document().getElementById("message"); 502 EXPECT_STREQ("click", element.innerText().utf8().data()); 503 } 504 505 #if OS(ANDROID) 506 TEST_F(SelectPopupMenuTest, DISABLED_PopupListBoxWithOverlayScrollbarEnabled) 507 #else 508 TEST_F(SelectPopupMenuTest, PopupListBoxWithOverlayScrollbarEnabled) 509 #endif 510 { 511 Settings::setMockScrollbarsEnabled(true); 512 RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(true); 513 EXPECT_TRUE(ScrollbarTheme::theme()->usesOverlayScrollbars()); 514 registerMockedURLLoad("select_rtl.html"); 515 loadFrame(mainFrame(), "select_rtl.html"); 516 517 m_popupMenuClient.setFocusedNode(mainFrame()->frame()->document()->focusedElement()); 518 m_popupMenuClient.setListSize(30); 519 520 showPopup(); 521 PopupContainer* container = webView()->selectPopup(); 522 PopupListBox* listBox = container->listBox(); 523 524 EXPECT_EQ(container->width(), listBox->contentsSize().width() + 2); 525 Settings::setMockScrollbarsEnabled(false); 526 RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(false); 527 EXPECT_FALSE(ScrollbarTheme::theme()->usesOverlayScrollbars()); 528 } 529 530 #if OS(ANDROID) 531 TEST_F(SelectPopupMenuTest, DISABLED_PopupListBoxWithOverlayScrollbarDisabled) 532 #else 533 TEST_F(SelectPopupMenuTest, PopupListBoxWithOverlayScrollbarDisabled) 534 #endif 535 { 536 EXPECT_FALSE(ScrollbarTheme::theme()->usesOverlayScrollbars()); 537 registerMockedURLLoad("select_rtl.html"); 538 loadFrame(mainFrame(), "select_rtl.html"); 539 540 m_popupMenuClient.setFocusedNode(mainFrame()->frame()->document()->focusedElement()); 541 m_popupMenuClient.setListSize(30); 542 543 showPopup(); 544 PopupContainer* container = webView()->selectPopup(); 545 PopupListBox* listBox = container->listBox(); 546 547 EXPECT_EQ(container->width(), listBox->contentsSize().width() + ScrollbarTheme::theme()->scrollbarThickness() + 2); 548 } 549 550 class SelectPopupMenuStyleTest : public testing::Test { 551 public: 552 SelectPopupMenuStyleTest() 553 : baseURL("http://www.test.com/") 554 { 555 } 556 557 protected: 558 virtual void SetUp() OVERRIDE 559 { 560 m_helper.initialize(false, 0, &m_webviewClient); 561 } 562 563 virtual void TearDown() OVERRIDE 564 { 565 Platform::current()->unitTestSupport()->unregisterAllMockedURLs(); 566 } 567 568 // Returns true if there currently is a select popup in the WebView. 569 bool popupOpen() const { return webView()->selectPopup(); } 570 571 void registerMockedURLLoad(const std::string& fileName) 572 { 573 URLTestHelpers::registerMockedURLLoad(toKURL(baseURL + fileName), WebString::fromUTF8(fileName.c_str()), WebString::fromUTF8("popup/"), WebString::fromUTF8("text/html")); 574 } 575 576 void loadFrame(WebFrame* frame, const std::string& fileName) 577 { 578 FrameTestHelpers::loadFrame(frame, baseURL + fileName); 579 } 580 581 WebViewImpl* webView() const { return m_helper.webViewImpl(); } 582 WebLocalFrameImpl* mainFrame() const { return m_helper.webViewImpl()->mainFrameImpl(); } 583 584 protected: 585 PopupTestWebViewClient m_webviewClient; 586 std::string baseURL; 587 588 private: 589 FrameTestHelpers::WebViewHelper m_helper; 590 }; 591 592 #if OS(MACOSX) || OS(ANDROID) 593 TEST_F(SelectPopupMenuStyleTest, DISABLED_PopupListBoxRTLRowWidth) 594 #else 595 TEST_F(SelectPopupMenuStyleTest, PopupListBoxRTLRowWidth) 596 #endif 597 { 598 registerMockedURLLoad("select_rtl_width.html"); 599 loadFrame(mainFrame(), "select_rtl_width.html"); 600 HTMLSelectElement* select = toHTMLSelectElement(mainFrame()->frame()->document()->focusedElement()); 601 RenderMenuList* menuList = toRenderMenuList(select->renderer()); 602 ASSERT(menuList); 603 menuList->showPopup(); 604 ASSERT(popupOpen()); 605 PopupListBox* listBox = webView()->selectPopup()->listBox(); 606 int ltrWidth = listBox->getRowBaseWidth(0); 607 int rtlWidth = listBox->getRowBaseWidth(1); 608 EXPECT_LT(rtlWidth, ltrWidth); 609 } 610 611 } // namespace 612