Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / content / renderer / external_popup_menu_browsertest.cc
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
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 "base/strings/utf_string_conversions.h"
6 #include "content/common/view_messages.h"
7 #include "content/public/test/render_view_test.h"
8 #include "content/renderer/render_view_impl.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "third_party/WebKit/public/web/WebView.h"
11 #include "third_party/WebKit/public/platform/WebSize.h"
12
13 // Tests for the external select popup menu (Mac specific).
14
15 namespace content {
16 namespace {
17
18 const char* const kSelectID = "mySelect";
19 const char* const kEmptySelectID = "myEmptySelect";
20
21 }  // namespace
22
23 class ExternalPopupMenuTest : public RenderViewTest {
24  public:
25   ExternalPopupMenuTest() {}
26
27   RenderViewImpl* view() {
28     return static_cast<RenderViewImpl*>(view_);
29   }
30
31   virtual void SetUp() {
32     RenderViewTest::SetUp();
33     // We need to set this explictly as RenderMain is not run.
34     blink::WebView::setUseExternalPopupMenus(true);
35
36     std::string html = "<select id='mySelect' onchange='selectChanged(this)'>"
37                        "  <option>zero</option>"
38                        "  <option selected='1'>one</option>"
39                        "  <option>two</option>"
40                        "</select>"
41                        "<select id='myEmptySelect'>"
42                        "</select>";
43     if (ShouldRemoveSelectOnChange()) {
44       html += "<script>"
45               "  function selectChanged(select) {"
46               "    select.parentNode.removeChild(select);"
47               "  }"
48               "</script>";
49     }
50
51     // Load the test page.
52     LoadHTML(html.c_str());
53
54     // Set a minimum size and give focus so simulated events work.
55     view()->webwidget()->resize(blink::WebSize(500, 500));
56     view()->webwidget()->setFocus(true);
57   }
58
59   int GetSelectedIndex() {
60     base::string16 script(base::ASCIIToUTF16(kSelectID));
61     script.append(base::ASCIIToUTF16(".selectedIndex"));
62     int selected_index = -1;
63     ExecuteJavaScriptAndReturnIntValue(script, &selected_index);
64     return selected_index;
65   }
66
67  protected:
68   virtual bool ShouldRemoveSelectOnChange() const { return false; }
69
70   DISALLOW_COPY_AND_ASSIGN(ExternalPopupMenuTest);
71 };
72
73 // Normal case: test showing a select popup, canceling/selecting an item.
74 TEST_F(ExternalPopupMenuTest, NormalCase) {
75   IPC::TestSink& sink = render_thread_->sink();
76
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.
90   view()->OnSelectPopupMenuItem(-1);
91   EXPECT_EQ(1, GetSelectedIndex());
92
93   // Show the pop-up again and this time make a selection.
94   EXPECT_TRUE(SimulateElementClick(kSelectID));
95   view()->OnSelectPopupMenuItem(0);
96   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.
109 TEST_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.
117   view()->OnSelectPopupMenuItem(-1);
118 }
119
120 // An empty select should not cause a crash when clicked.
121 // http://crbug.com/63774
122 TEST_F(ExternalPopupMenuTest, EmptySelect) {
123   EXPECT_TRUE(SimulateElementClick(kEmptySelectID));
124 }
125
126 class ExternalPopupMenuRemoveTest : public ExternalPopupMenuTest {
127  public:
128   ExternalPopupMenuRemoveTest() {}
129
130  protected:
131   virtual bool ShouldRemoveSelectOnChange() const OVERRIDE { return true; }
132 };
133
134 // Tests that nothing bad happen when the page removes the select when it
135 // changes. (http://crbug.com/61997)
136 TEST_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.
141   view()->OnSelectPopupMenuItem(0);
142
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 }
147
148 class ExternalPopupMenuDisplayNoneTest : public ExternalPopupMenuTest {
149   public:
150   ExternalPopupMenuDisplayNoneTest() {}
151
152   virtual void SetUp() {
153     RenderViewTest::SetUp();
154     // We need to set this explictly as RenderMain is not run.
155     blink::WebView::setUseExternalPopupMenus(true);
156
157     std::string html = "<select id='mySelect'>"
158                        "  <option value='zero'>zero</option>"
159                        "  <optgroup label='hide' style='display: none'>"
160                        "    <option value='one'>one</option>"
161                        "  </optgroup>"
162                        "  <option value='two'>two</option>"
163                        "  <option value='three'>three</option>"
164                        "  <option value='four'>four</option>"
165                        "  <option value='five'>five</option>"
166                        "</select>";
167     // Load the test page.
168     LoadHTML(html.c_str());
169
170     // Set a minimum size and give focus so simulated events work.
171     view()->webwidget()->resize(blink::WebSize(500, 500));
172     view()->webwidget()->setFocus(true);
173   }
174
175 };
176
177 TEST_F(ExternalPopupMenuDisplayNoneTest, SelectItem) {
178   // Click the text field once to show the popup.
179   EXPECT_TRUE(SimulateElementClick(kSelectID));
180
181   // Select index 1 item. This should select item with index 2,
182   // skipping the item with 'display: none'
183   view()->OnSelectPopupMenuItem(1);
184
185   EXPECT_EQ(2,GetSelectedIndex());
186 }
187
188 }  // namespace content