blob: d5e16432dc05fa1d4e07ed8149f70a70c09d859b [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
tzik1068f1be2016-06-03 07:25:205#include <tuple>
6
avi1023d012015-12-25 02:39:147#include "base/macros.h"
[email protected]74ebfb12013-06-07 20:48:008#include "base/strings/utf_string_conversions.h"
avi485e5fd62014-08-25 23:26:149#include "content/common/frame_messages.h"
[email protected]899617f2012-06-04 02:27:1410#include "content/public/test/render_view_test.h"
avi485e5fd62014-08-25 23:26:1411#include "content/renderer/render_frame_impl.h"
[email protected]068970d2011-10-11 00:05:1612#include "content/renderer/render_view_impl.h"
[email protected]caf706f2010-10-26 17:54:0813#include "testing/gtest/include/gtest/gtest.h"
[email protected]74ebfb12013-06-07 20:48:0014#include "third_party/WebKit/public/platform/WebSize.h"
avi1023d012015-12-25 02:39:1415#include "third_party/WebKit/public/web/WebView.h"
[email protected]caf706f2010-10-26 17:54:0816
17// Tests for the external select popup menu (Mac specific).
18
[email protected]e9ff79c2012-10-19 21:31:2619namespace content {
[email protected]caf706f2010-10-26 17:54:0820namespace {
21
22const char* const kSelectID = "mySelect";
[email protected]92ccbdd2010-12-01 19:30:4423const char* const kEmptySelectID = "myEmptySelect";
[email protected]caf706f2010-10-26 17:54:0824
25} // namespace
26
[email protected]e9ff79c2012-10-19 21:31:2627class ExternalPopupMenuTest : public RenderViewTest {
[email protected]caf706f2010-10-26 17:54:0828 public:
29 ExternalPopupMenuTest() {}
30
[email protected]068970d2011-10-11 00:05:1631 RenderViewImpl* view() {
32 return static_cast<RenderViewImpl*>(view_);
33 }
34
avi485e5fd62014-08-25 23:26:1435 RenderFrameImpl* frame() {
mostynbc33353232014-09-12 09:38:3136 return view()->GetMainRenderFrame();
avi485e5fd62014-08-25 23:26:1437 }
38
dcheng60135332015-01-09 02:05:3439 void SetUp() override {
[email protected]e9ff79c2012-10-19 21:31:2640 RenderViewTest::SetUp();
[email protected]caf706f2010-10-26 17:54:0841 // We need to set this explictly as RenderMain is not run.
[email protected]180ef242013-11-07 06:50:4642 blink::WebView::setUseExternalPopupMenus(true);
[email protected]caf706f2010-10-26 17:54:0843
[email protected]360bc0b12010-11-11 19:21:2644 std::string html = "<select id='mySelect' onchange='selectChanged(this)'>"
45 " <option>zero</option>"
46 " <option selected='1'>one</option>"
47 " <option>two</option>"
[email protected]92ccbdd2010-12-01 19:30:4448 "</select>"
49 "<select id='myEmptySelect'>"
[email protected]360bc0b12010-11-11 19:21:2650 "</select>";
51 if (ShouldRemoveSelectOnChange()) {
52 html += "<script>"
53 " function selectChanged(select) {"
54 " select.parentNode.removeChild(select);"
55 " }"
56 "</script>";
57 }
58
[email protected]caf706f2010-10-26 17:54:0859 // Load the test page.
[email protected]360bc0b12010-11-11 19:21:2660 LoadHTML(html.c_str());
[email protected]caf706f2010-10-26 17:54:0861
62 // Set a minimum size and give focus so simulated events work.
lfg8ff33912016-09-13 20:59:2163 view()->GetWidget()->GetWebWidget()->resize(blink::WebSize(500, 500));
64 view()->GetWidget()->GetWebWidget()->setFocus(true);
[email protected]caf706f2010-10-26 17:54:0865 }
66
67 int GetSelectedIndex() {
[email protected]32956122013-12-25 07:29:2468 base::string16 script(base::ASCIIToUTF16(kSelectID));
69 script.append(base::ASCIIToUTF16(".selectedIndex"));
[email protected]caf706f2010-10-26 17:54:0870 int selected_index = -1;
71 ExecuteJavaScriptAndReturnIntValue(script, &selected_index);
72 return selected_index;
73 }
74
[email protected]360bc0b12010-11-11 19:21:2675 protected:
76 virtual bool ShouldRemoveSelectOnChange() const { return false; }
77
[email protected]caf706f2010-10-26 17:54:0878 DISALLOW_COPY_AND_ASSIGN(ExternalPopupMenuTest);
79};
80
81// Normal case: test showing a select popup, canceling/selecting an item.
82TEST_F(ExternalPopupMenuTest, NormalCase) {
[email protected]c6d068ff2011-10-14 17:28:2383 IPC::TestSink& sink = render_thread_->sink();
[email protected]caf706f2010-10-26 17:54:0884
85 // Click the text field once.
86 EXPECT_TRUE(SimulateElementClick(kSelectID));
87
88 // We should have sent a message to the browser to show the popup menu.
89 const IPC::Message* message =
avi485e5fd62014-08-25 23:26:1490 sink.GetUniqueMessageMatching(FrameHostMsg_ShowPopup::ID);
[email protected]caf706f2010-10-26 17:54:0891 ASSERT_TRUE(message != NULL);
tzik1068f1be2016-06-03 07:25:2092 std::tuple<FrameHostMsg_ShowPopup_Params> param;
avi485e5fd62014-08-25 23:26:1493 FrameHostMsg_ShowPopup::Read(message, &param);
tzik1068f1be2016-06-03 07:25:2094 ASSERT_EQ(3U, std::get<0>(param).popup_items.size());
95 EXPECT_EQ(1, std::get<0>(param).selected_item);
[email protected]caf706f2010-10-26 17:54:0896
avi485e5fd62014-08-25 23:26:1497 // Simulate the user canceling the popup; the index should not have changed.
98 frame()->OnSelectPopupMenuItem(-1);
[email protected]caf706f2010-10-26 17:54:0899 EXPECT_EQ(1, GetSelectedIndex());
100
101 // Show the pop-up again and this time make a selection.
102 EXPECT_TRUE(SimulateElementClick(kSelectID));
avi485e5fd62014-08-25 23:26:14103 frame()->OnSelectPopupMenuItem(0);
[email protected]caf706f2010-10-26 17:54:08104 EXPECT_EQ(0, GetSelectedIndex());
105
106 // Show the pop-up again and make another selection.
107 sink.ClearMessages();
108 EXPECT_TRUE(SimulateElementClick(kSelectID));
avi485e5fd62014-08-25 23:26:14109 message = sink.GetUniqueMessageMatching(FrameHostMsg_ShowPopup::ID);
[email protected]caf706f2010-10-26 17:54:08110 ASSERT_TRUE(message != NULL);
avi485e5fd62014-08-25 23:26:14111 FrameHostMsg_ShowPopup::Read(message, &param);
tzik1068f1be2016-06-03 07:25:20112 ASSERT_EQ(3U, std::get<0>(param).popup_items.size());
113 EXPECT_EQ(0, std::get<0>(param).selected_item);
[email protected]caf706f2010-10-26 17:54:08114}
115
116// Page shows popup, then navigates away while popup showing, then select.
117TEST_F(ExternalPopupMenuTest, ShowPopupThenNavigate) {
118 // Click the text field once.
119 EXPECT_TRUE(SimulateElementClick(kSelectID));
120
121 // Now we navigate to another pager.
122 LoadHTML("<blink>Awesome page!</blink>");
123
124 // Now the user selects something, we should not crash.
avi485e5fd62014-08-25 23:26:14125 frame()->OnSelectPopupMenuItem(-1);
[email protected]caf706f2010-10-26 17:54:08126}
[email protected]360bc0b12010-11-11 19:21:26127
[email protected]92ccbdd2010-12-01 19:30:44128// An empty select should not cause a crash when clicked.
129// http://crbug.com/63774
130TEST_F(ExternalPopupMenuTest, EmptySelect) {
131 EXPECT_TRUE(SimulateElementClick(kEmptySelectID));
132}
133
[email protected]360bc0b12010-11-11 19:21:26134class ExternalPopupMenuRemoveTest : public ExternalPopupMenuTest {
135 public:
136 ExternalPopupMenuRemoveTest() {}
137
138 protected:
dcheng6d18e402014-10-21 12:32:52139 bool ShouldRemoveSelectOnChange() const override { return true; }
[email protected]360bc0b12010-11-11 19:21:26140};
141
142// Tests that nothing bad happen when the page removes the select when it
143// changes. (http://crbug.com/61997)
tkent4e91ab82015-08-05 22:36:46144TEST_F(ExternalPopupMenuRemoveTest, RemoveOnChange) {
[email protected]360bc0b12010-11-11 19:21:26145 // Click the text field once to show the popup.
146 EXPECT_TRUE(SimulateElementClick(kSelectID));
147
148 // Select something, it causes the select to be removed from the page.
avi485e5fd62014-08-25 23:26:14149 frame()->OnSelectPopupMenuItem(0);
[email protected]360bc0b12010-11-11 19:21:26150
151 // Just to check the soundness of the test, call SimulateElementClick again.
152 // It should return false as the select has been removed.
153 EXPECT_FALSE(SimulateElementClick(kSelectID));
154}
[email protected]e9ff79c2012-10-19 21:31:26155
[email protected]d0cd67482014-08-12 19:17:12156class ExternalPopupMenuDisplayNoneTest : public ExternalPopupMenuTest {
157 public:
158 ExternalPopupMenuDisplayNoneTest() {}
159
dcheng60135332015-01-09 02:05:34160 void SetUp() override {
[email protected]d0cd67482014-08-12 19:17:12161 RenderViewTest::SetUp();
162 // We need to set this explictly as RenderMain is not run.
163 blink::WebView::setUseExternalPopupMenus(true);
164
165 std::string html = "<select id='mySelect'>"
166 " <option value='zero'>zero</option>"
167 " <optgroup label='hide' style='display: none'>"
168 " <option value='one'>one</option>"
169 " </optgroup>"
170 " <option value='two'>two</option>"
171 " <option value='three'>three</option>"
172 " <option value='four'>four</option>"
173 " <option value='five'>five</option>"
174 "</select>";
175 // Load the test page.
176 LoadHTML(html.c_str());
177
178 // Set a minimum size and give focus so simulated events work.
lfg8ff33912016-09-13 20:59:21179 view()->GetWidget()->GetWebWidget()->resize(blink::WebSize(500, 500));
180 view()->GetWidget()->GetWebWidget()->setFocus(true);
[email protected]d0cd67482014-08-12 19:17:12181 }
182
183};
184
185TEST_F(ExternalPopupMenuDisplayNoneTest, SelectItem) {
sudarshan.p9ff8ce32014-09-03 11:20:37186 IPC::TestSink& sink = render_thread_->sink();
187
[email protected]d0cd67482014-08-12 19:17:12188 // Click the text field once to show the popup.
189 EXPECT_TRUE(SimulateElementClick(kSelectID));
190
sudarshan.p9ff8ce32014-09-03 11:20:37191 // Read the message sent to browser to show the popup menu.
192 const IPC::Message* message =
193 sink.GetUniqueMessageMatching(FrameHostMsg_ShowPopup::ID);
194 ASSERT_TRUE(message != NULL);
tzik1068f1be2016-06-03 07:25:20195 std::tuple<FrameHostMsg_ShowPopup_Params> param;
sudarshan.p9ff8ce32014-09-03 11:20:37196 FrameHostMsg_ShowPopup::Read(message, &param);
197 // Number of items should match item count minus the number
198 // of "display: none" items.
tzik1068f1be2016-06-03 07:25:20199 ASSERT_EQ(5U, std::get<0>(param).popup_items.size());
sudarshan.p9ff8ce32014-09-03 11:20:37200
[email protected]d0cd67482014-08-12 19:17:12201 // Select index 1 item. This should select item with index 2,
202 // skipping the item with 'display: none'
avi485e5fd62014-08-25 23:26:14203 frame()->OnSelectPopupMenuItem(1);
[email protected]d0cd67482014-08-12 19:17:12204
avi485e5fd62014-08-25 23:26:14205 EXPECT_EQ(2, GetSelectedIndex());
[email protected]d0cd67482014-08-12 19:17:12206}
207
[email protected]e9ff79c2012-10-19 21:31:26208} // namespace content