blob: d7f93124a29d8eb29730fd6c1d0e86fac8f6df7c [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
avi1023d012015-12-25 02:39:145#include "base/macros.h"
[email protected]74ebfb12013-06-07 20:48:006#include "base/strings/utf_string_conversions.h"
avi485e5fd62014-08-25 23:26:147#include "content/common/frame_messages.h"
[email protected]899617f2012-06-04 02:27:148#include "content/public/test/render_view_test.h"
avi485e5fd62014-08-25 23:26:149#include "content/renderer/render_frame_impl.h"
[email protected]068970d2011-10-11 00:05:1610#include "content/renderer/render_view_impl.h"
[email protected]caf706f2010-10-26 17:54:0811#include "testing/gtest/include/gtest/gtest.h"
[email protected]74ebfb12013-06-07 20:48:0012#include "third_party/WebKit/public/platform/WebSize.h"
avi1023d012015-12-25 02:39:1413#include "third_party/WebKit/public/web/WebView.h"
[email protected]caf706f2010-10-26 17:54:0814
15// Tests for the external select popup menu (Mac specific).
16
[email protected]e9ff79c2012-10-19 21:31:2617namespace content {
[email protected]caf706f2010-10-26 17:54:0818namespace {
19
20const char* const kSelectID = "mySelect";
[email protected]92ccbdd2010-12-01 19:30:4421const char* const kEmptySelectID = "myEmptySelect";
[email protected]caf706f2010-10-26 17:54:0822
23} // namespace
24
[email protected]e9ff79c2012-10-19 21:31:2625class ExternalPopupMenuTest : public RenderViewTest {
[email protected]caf706f2010-10-26 17:54:0826 public:
27 ExternalPopupMenuTest() {}
28
[email protected]068970d2011-10-11 00:05:1629 RenderViewImpl* view() {
30 return static_cast<RenderViewImpl*>(view_);
31 }
32
avi485e5fd62014-08-25 23:26:1433 RenderFrameImpl* frame() {
mostynbc33353232014-09-12 09:38:3134 return view()->GetMainRenderFrame();
avi485e5fd62014-08-25 23:26:1435 }
36
dcheng60135332015-01-09 02:05:3437 void SetUp() override {
[email protected]e9ff79c2012-10-19 21:31:2638 RenderViewTest::SetUp();
[email protected]caf706f2010-10-26 17:54:0839 // We need to set this explictly as RenderMain is not run.
[email protected]180ef242013-11-07 06:50:4640 blink::WebView::setUseExternalPopupMenus(true);
[email protected]caf706f2010-10-26 17:54:0841
[email protected]360bc0b12010-11-11 19:21:2642 std::string html = "<select id='mySelect' onchange='selectChanged(this)'>"
43 " <option>zero</option>"
44 " <option selected='1'>one</option>"
45 " <option>two</option>"
[email protected]92ccbdd2010-12-01 19:30:4446 "</select>"
47 "<select id='myEmptySelect'>"
[email protected]360bc0b12010-11-11 19:21:2648 "</select>";
49 if (ShouldRemoveSelectOnChange()) {
50 html += "<script>"
51 " function selectChanged(select) {"
52 " select.parentNode.removeChild(select);"
53 " }"
54 "</script>";
55 }
56
[email protected]caf706f2010-10-26 17:54:0857 // Load the test page.
[email protected]360bc0b12010-11-11 19:21:2658 LoadHTML(html.c_str());
[email protected]caf706f2010-10-26 17:54:0859
60 // Set a minimum size and give focus so simulated events work.
[email protected]180ef242013-11-07 06:50:4661 view()->webwidget()->resize(blink::WebSize(500, 500));
[email protected]068970d2011-10-11 00:05:1662 view()->webwidget()->setFocus(true);
[email protected]caf706f2010-10-26 17:54:0863 }
64
65 int GetSelectedIndex() {
[email protected]32956122013-12-25 07:29:2466 base::string16 script(base::ASCIIToUTF16(kSelectID));
67 script.append(base::ASCIIToUTF16(".selectedIndex"));
[email protected]caf706f2010-10-26 17:54:0868 int selected_index = -1;
69 ExecuteJavaScriptAndReturnIntValue(script, &selected_index);
70 return selected_index;
71 }
72
[email protected]360bc0b12010-11-11 19:21:2673 protected:
74 virtual bool ShouldRemoveSelectOnChange() const { return false; }
75
[email protected]caf706f2010-10-26 17:54:0876 DISALLOW_COPY_AND_ASSIGN(ExternalPopupMenuTest);
77};
78
79// Normal case: test showing a select popup, canceling/selecting an item.
80TEST_F(ExternalPopupMenuTest, NormalCase) {
[email protected]c6d068ff2011-10-14 17:28:2381 IPC::TestSink& sink = render_thread_->sink();
[email protected]caf706f2010-10-26 17:54:0882
83 // Click the text field once.
84 EXPECT_TRUE(SimulateElementClick(kSelectID));
85
86 // We should have sent a message to the browser to show the popup menu.
87 const IPC::Message* message =
avi485e5fd62014-08-25 23:26:1488 sink.GetUniqueMessageMatching(FrameHostMsg_ShowPopup::ID);
[email protected]caf706f2010-10-26 17:54:0889 ASSERT_TRUE(message != NULL);
brettwd5ca2bc2015-05-29 22:15:4790 base::Tuple<FrameHostMsg_ShowPopup_Params> param;
avi485e5fd62014-08-25 23:26:1491 FrameHostMsg_ShowPopup::Read(message, &param);
brettwd5ca2bc2015-05-29 22:15:4792 ASSERT_EQ(3U, base::get<0>(param).popup_items.size());
93 EXPECT_EQ(1, base::get<0>(param).selected_item);
[email protected]caf706f2010-10-26 17:54:0894
avi485e5fd62014-08-25 23:26:1495 // Simulate the user canceling the popup; the index should not have changed.
96 frame()->OnSelectPopupMenuItem(-1);
[email protected]caf706f2010-10-26 17:54:0897 EXPECT_EQ(1, GetSelectedIndex());
98
99 // Show the pop-up again and this time make a selection.
100 EXPECT_TRUE(SimulateElementClick(kSelectID));
avi485e5fd62014-08-25 23:26:14101 frame()->OnSelectPopupMenuItem(0);
[email protected]caf706f2010-10-26 17:54:08102 EXPECT_EQ(0, GetSelectedIndex());
103
104 // Show the pop-up again and make another selection.
105 sink.ClearMessages();
106 EXPECT_TRUE(SimulateElementClick(kSelectID));
avi485e5fd62014-08-25 23:26:14107 message = sink.GetUniqueMessageMatching(FrameHostMsg_ShowPopup::ID);
[email protected]caf706f2010-10-26 17:54:08108 ASSERT_TRUE(message != NULL);
avi485e5fd62014-08-25 23:26:14109 FrameHostMsg_ShowPopup::Read(message, &param);
brettwd5ca2bc2015-05-29 22:15:47110 ASSERT_EQ(3U, base::get<0>(param).popup_items.size());
111 EXPECT_EQ(0, base::get<0>(param).selected_item);
[email protected]caf706f2010-10-26 17:54:08112}
113
114// Page shows popup, then navigates away while popup showing, then select.
115TEST_F(ExternalPopupMenuTest, ShowPopupThenNavigate) {
116 // Click the text field once.
117 EXPECT_TRUE(SimulateElementClick(kSelectID));
118
119 // Now we navigate to another pager.
120 LoadHTML("<blink>Awesome page!</blink>");
121
122 // Now the user selects something, we should not crash.
avi485e5fd62014-08-25 23:26:14123 frame()->OnSelectPopupMenuItem(-1);
[email protected]caf706f2010-10-26 17:54:08124}
[email protected]360bc0b12010-11-11 19:21:26125
[email protected]92ccbdd2010-12-01 19:30:44126// An empty select should not cause a crash when clicked.
127// http://crbug.com/63774
128TEST_F(ExternalPopupMenuTest, EmptySelect) {
129 EXPECT_TRUE(SimulateElementClick(kEmptySelectID));
130}
131
[email protected]360bc0b12010-11-11 19:21:26132class ExternalPopupMenuRemoveTest : public ExternalPopupMenuTest {
133 public:
134 ExternalPopupMenuRemoveTest() {}
135
136 protected:
dcheng6d18e402014-10-21 12:32:52137 bool ShouldRemoveSelectOnChange() const override { return true; }
[email protected]360bc0b12010-11-11 19:21:26138};
139
140// Tests that nothing bad happen when the page removes the select when it
141// changes. (http://crbug.com/61997)
tkent4e91ab82015-08-05 22:36:46142TEST_F(ExternalPopupMenuRemoveTest, RemoveOnChange) {
[email protected]360bc0b12010-11-11 19:21:26143 // Click the text field once to show the popup.
144 EXPECT_TRUE(SimulateElementClick(kSelectID));
145
146 // Select something, it causes the select to be removed from the page.
avi485e5fd62014-08-25 23:26:14147 frame()->OnSelectPopupMenuItem(0);
[email protected]360bc0b12010-11-11 19:21:26148
149 // Just to check the soundness of the test, call SimulateElementClick again.
150 // It should return false as the select has been removed.
151 EXPECT_FALSE(SimulateElementClick(kSelectID));
152}
[email protected]e9ff79c2012-10-19 21:31:26153
[email protected]d0cd67482014-08-12 19:17:12154class ExternalPopupMenuDisplayNoneTest : public ExternalPopupMenuTest {
155 public:
156 ExternalPopupMenuDisplayNoneTest() {}
157
dcheng60135332015-01-09 02:05:34158 void SetUp() override {
[email protected]d0cd67482014-08-12 19:17:12159 RenderViewTest::SetUp();
160 // We need to set this explictly as RenderMain is not run.
161 blink::WebView::setUseExternalPopupMenus(true);
162
163 std::string html = "<select id='mySelect'>"
164 " <option value='zero'>zero</option>"
165 " <optgroup label='hide' style='display: none'>"
166 " <option value='one'>one</option>"
167 " </optgroup>"
168 " <option value='two'>two</option>"
169 " <option value='three'>three</option>"
170 " <option value='four'>four</option>"
171 " <option value='five'>five</option>"
172 "</select>";
173 // Load the test page.
174 LoadHTML(html.c_str());
175
176 // Set a minimum size and give focus so simulated events work.
177 view()->webwidget()->resize(blink::WebSize(500, 500));
178 view()->webwidget()->setFocus(true);
179 }
180
181};
182
183TEST_F(ExternalPopupMenuDisplayNoneTest, SelectItem) {
sudarshan.p9ff8ce32014-09-03 11:20:37184 IPC::TestSink& sink = render_thread_->sink();
185
[email protected]d0cd67482014-08-12 19:17:12186 // Click the text field once to show the popup.
187 EXPECT_TRUE(SimulateElementClick(kSelectID));
188
sudarshan.p9ff8ce32014-09-03 11:20:37189 // Read the message sent to browser to show the popup menu.
190 const IPC::Message* message =
191 sink.GetUniqueMessageMatching(FrameHostMsg_ShowPopup::ID);
192 ASSERT_TRUE(message != NULL);
brettwd5ca2bc2015-05-29 22:15:47193 base::Tuple<FrameHostMsg_ShowPopup_Params> param;
sudarshan.p9ff8ce32014-09-03 11:20:37194 FrameHostMsg_ShowPopup::Read(message, &param);
195 // Number of items should match item count minus the number
196 // of "display: none" items.
brettwd5ca2bc2015-05-29 22:15:47197 ASSERT_EQ(5U, base::get<0>(param).popup_items.size());
sudarshan.p9ff8ce32014-09-03 11:20:37198
[email protected]d0cd67482014-08-12 19:17:12199 // Select index 1 item. This should select item with index 2,
200 // skipping the item with 'display: none'
avi485e5fd62014-08-25 23:26:14201 frame()->OnSelectPopupMenuItem(1);
[email protected]d0cd67482014-08-12 19:17:12202
avi485e5fd62014-08-25 23:26:14203 EXPECT_EQ(2, GetSelectedIndex());
[email protected]d0cd67482014-08-12 19:17:12204}
205
[email protected]e9ff79c2012-10-19 21:31:26206} // namespace content