blob: a0a6a90c8f373354d170c5fe6757df2a4dcba85d [file] [log] [blame]
[email protected]c6d068ff2011-10-14 17:28:231// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]caf706f2010-10-26 17:54:082// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]74ebfb12013-06-07 20:48:005#include "base/strings/utf_string_conversions.h"
[email protected]55722152011-03-22 01:33:536#include "content/common/view_messages.h"
[email protected]899617f2012-06-04 02:27:147#include "content/public/test/render_view_test.h"
[email protected]068970d2011-10-11 00:05:168#include "content/renderer/render_view_impl.h"
[email protected]caf706f2010-10-26 17:54:089#include "testing/gtest/include/gtest/gtest.h"
[email protected]2255a9332013-06-17 05:12:3110#include "third_party/WebKit/public/web/WebView.h"
[email protected]74ebfb12013-06-07 20:48:0011#include "third_party/WebKit/public/platform/WebSize.h"
[email protected]caf706f2010-10-26 17:54:0812
13// Tests for the external select popup menu (Mac specific).
14
[email protected]e9ff79c2012-10-19 21:31:2615namespace content {
[email protected]caf706f2010-10-26 17:54:0816namespace {
17
18const char* const kSelectID = "mySelect";
[email protected]92ccbdd2010-12-01 19:30:4419const char* const kEmptySelectID = "myEmptySelect";
[email protected]caf706f2010-10-26 17:54:0820
21} // namespace
22
[email protected]e9ff79c2012-10-19 21:31:2623class ExternalPopupMenuTest : public RenderViewTest {
[email protected]caf706f2010-10-26 17:54:0824 public:
25 ExternalPopupMenuTest() {}
26
[email protected]068970d2011-10-11 00:05:1627 RenderViewImpl* view() {
28 return static_cast<RenderViewImpl*>(view_);
29 }
30
[email protected]caf706f2010-10-26 17:54:0831 virtual void SetUp() {
[email protected]e9ff79c2012-10-19 21:31:2632 RenderViewTest::SetUp();
[email protected]caf706f2010-10-26 17:54:0833 // We need to set this explictly as RenderMain is not run.
[email protected]180ef242013-11-07 06:50:4634 blink::WebView::setUseExternalPopupMenus(true);
[email protected]caf706f2010-10-26 17:54:0835
[email protected]360bc0b12010-11-11 19:21:2636 std::string html = "<select id='mySelect' onchange='selectChanged(this)'>"
37 " <option>zero</option>"
38 " <option selected='1'>one</option>"
39 " <option>two</option>"
[email protected]92ccbdd2010-12-01 19:30:4440 "</select>"
41 "<select id='myEmptySelect'>"
[email protected]360bc0b12010-11-11 19:21:2642 "</select>";
43 if (ShouldRemoveSelectOnChange()) {
44 html += "<script>"
45 " function selectChanged(select) {"
46 " select.parentNode.removeChild(select);"
47 " }"
48 "</script>";
49 }
50
[email protected]caf706f2010-10-26 17:54:0851 // Load the test page.
[email protected]360bc0b12010-11-11 19:21:2652 LoadHTML(html.c_str());
[email protected]caf706f2010-10-26 17:54:0853
54 // Set a minimum size and give focus so simulated events work.
[email protected]180ef242013-11-07 06:50:4655 view()->webwidget()->resize(blink::WebSize(500, 500));
[email protected]068970d2011-10-11 00:05:1656 view()->webwidget()->setFocus(true);
[email protected]caf706f2010-10-26 17:54:0857 }
58
59 int GetSelectedIndex() {
[email protected]32956122013-12-25 07:29:2460 base::string16 script(base::ASCIIToUTF16(kSelectID));
61 script.append(base::ASCIIToUTF16(".selectedIndex"));
[email protected]caf706f2010-10-26 17:54:0862 int selected_index = -1;
63 ExecuteJavaScriptAndReturnIntValue(script, &selected_index);
64 return selected_index;
65 }
66
[email protected]360bc0b12010-11-11 19:21:2667 protected:
68 virtual bool ShouldRemoveSelectOnChange() const { return false; }
69
[email protected]caf706f2010-10-26 17:54:0870 DISALLOW_COPY_AND_ASSIGN(ExternalPopupMenuTest);
71};
72
73// Normal case: test showing a select popup, canceling/selecting an item.
74TEST_F(ExternalPopupMenuTest, NormalCase) {
[email protected]c6d068ff2011-10-14 17:28:2375 IPC::TestSink& sink = render_thread_->sink();
[email protected]caf706f2010-10-26 17:54:0876
77 // Click the text field once.
78 EXPECT_TRUE(SimulateElementClick(kSelectID));
79
80 // We should have sent a message to the browser to show the popup menu.
81 const IPC::Message* message =
82 sink.GetUniqueMessageMatching(ViewHostMsg_ShowPopup::ID);
83 ASSERT_TRUE(message != NULL);
84 Tuple1<ViewHostMsg_ShowPopup_Params> param;
85 ViewHostMsg_ShowPopup::Read(message, &param);
86 ASSERT_EQ(3U, param.a.popup_items.size());
87 EXPECT_EQ(1, param.a.selected_item);
88
89 // Simulate the user canceling the popup, the index should not have changed.
[email protected]068970d2011-10-11 00:05:1690 view()->OnSelectPopupMenuItem(-1);
[email protected]caf706f2010-10-26 17:54:0891 EXPECT_EQ(1, GetSelectedIndex());
92
93 // Show the pop-up again and this time make a selection.
94 EXPECT_TRUE(SimulateElementClick(kSelectID));
[email protected]068970d2011-10-11 00:05:1695 view()->OnSelectPopupMenuItem(0);
[email protected]caf706f2010-10-26 17:54:0896 EXPECT_EQ(0, GetSelectedIndex());
97
98 // Show the pop-up again and make another selection.
99 sink.ClearMessages();
100 EXPECT_TRUE(SimulateElementClick(kSelectID));
101 message = sink.GetUniqueMessageMatching(ViewHostMsg_ShowPopup::ID);
102 ASSERT_TRUE(message != NULL);
103 ViewHostMsg_ShowPopup::Read(message, &param);
104 ASSERT_EQ(3U, param.a.popup_items.size());
105 EXPECT_EQ(0, param.a.selected_item);
106}
107
108// Page shows popup, then navigates away while popup showing, then select.
109TEST_F(ExternalPopupMenuTest, ShowPopupThenNavigate) {
110 // Click the text field once.
111 EXPECT_TRUE(SimulateElementClick(kSelectID));
112
113 // Now we navigate to another pager.
114 LoadHTML("<blink>Awesome page!</blink>");
115
116 // Now the user selects something, we should not crash.
[email protected]068970d2011-10-11 00:05:16117 view()->OnSelectPopupMenuItem(-1);
[email protected]caf706f2010-10-26 17:54:08118}
[email protected]360bc0b12010-11-11 19:21:26119
[email protected]92ccbdd2010-12-01 19:30:44120// An empty select should not cause a crash when clicked.
121// http://crbug.com/63774
122TEST_F(ExternalPopupMenuTest, EmptySelect) {
123 EXPECT_TRUE(SimulateElementClick(kEmptySelectID));
124}
125
[email protected]360bc0b12010-11-11 19:21:26126class ExternalPopupMenuRemoveTest : public ExternalPopupMenuTest {
127 public:
128 ExternalPopupMenuRemoveTest() {}
129
130 protected:
[email protected]6b7fa22d2013-02-20 11:16:21131 virtual bool ShouldRemoveSelectOnChange() const OVERRIDE { return true; }
[email protected]360bc0b12010-11-11 19:21:26132};
133
134// Tests that nothing bad happen when the page removes the select when it
135// changes. (http://crbug.com/61997)
136TEST_F(ExternalPopupMenuRemoveTest, RemoveOnChange) {
137 // Click the text field once to show the popup.
138 EXPECT_TRUE(SimulateElementClick(kSelectID));
139
140 // Select something, it causes the select to be removed from the page.
[email protected]068970d2011-10-11 00:05:16141 view()->OnSelectPopupMenuItem(0);
[email protected]360bc0b12010-11-11 19:21:26142
143 // Just to check the soundness of the test, call SimulateElementClick again.
144 // It should return false as the select has been removed.
145 EXPECT_FALSE(SimulateElementClick(kSelectID));
146}
[email protected]e9ff79c2012-10-19 21:31:26147
148} // namespace content