OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/views/tabs/tab.h" | 5 #include "chrome/browser/ui/views/tabs/tab.h" |
6 | 6 |
| 7 #include "base/i18n/rtl.h" |
7 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "chrome/browser/ui/views/tabs/media_indicator_button.h" |
8 #include "chrome/browser/ui/views/tabs/tab_controller.h" | 10 #include "chrome/browser/ui/views/tabs/tab_controller.h" |
9 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
10 #include "ui/base/models/list_selection_model.h" | 12 #include "ui/base/models/list_selection_model.h" |
11 #include "ui/views/controls/button/image_button.h" | 13 #include "ui/views/controls/button/image_button.h" |
12 #include "ui/views/controls/label.h" | 14 #include "ui/views/controls/label.h" |
13 #include "ui/views/test/views_test_base.h" | 15 #include "ui/views/test/views_test_base.h" |
14 #include "ui/views/widget/widget.h" | 16 #include "ui/views/widget/widget.h" |
15 | 17 |
16 using views::Widget; | 18 using views::Widget; |
17 | 19 |
18 class FakeTabController : public TabController { | 20 class FakeTabController : public TabController { |
19 public: | 21 public: |
20 FakeTabController() : immersive_style_(false), active_tab_(false) { | 22 FakeTabController() : immersive_style_(false), active_tab_(false) { |
21 } | 23 } |
22 virtual ~FakeTabController() {} | 24 virtual ~FakeTabController() {} |
23 | 25 |
24 void set_immersive_style(bool value) { immersive_style_ = value; } | 26 void set_immersive_style(bool value) { immersive_style_ = value; } |
25 void set_active_tab(bool value) { active_tab_ = value; } | 27 void set_active_tab(bool value) { active_tab_ = value; } |
26 | 28 |
27 virtual const ui::ListSelectionModel& GetSelectionModel() OVERRIDE { | 29 virtual const ui::ListSelectionModel& GetSelectionModel() OVERRIDE { |
28 return selection_model_; | 30 return selection_model_; |
29 } | 31 } |
30 virtual bool SupportsMultipleSelection() OVERRIDE { return false; } | 32 virtual bool SupportsMultipleSelection() OVERRIDE { return false; } |
31 virtual void SelectTab(Tab* tab) OVERRIDE {} | 33 virtual void SelectTab(Tab* tab) OVERRIDE {} |
32 virtual void ExtendSelectionTo(Tab* tab) OVERRIDE {} | 34 virtual void ExtendSelectionTo(Tab* tab) OVERRIDE {} |
33 virtual void ToggleSelected(Tab* tab) OVERRIDE {} | 35 virtual void ToggleSelected(Tab* tab) OVERRIDE {} |
34 virtual void AddSelectionFromAnchorTo(Tab* tab) OVERRIDE {} | 36 virtual void AddSelectionFromAnchorTo(Tab* tab) OVERRIDE {} |
35 virtual void CloseTab(Tab* tab, CloseTabSource source) OVERRIDE {} | 37 virtual void CloseTab(Tab* tab, CloseTabSource source) OVERRIDE {} |
| 38 virtual void ToggleTabAudioMute(Tab* tab) OVERRIDE {} |
36 virtual void ShowContextMenuForTab(Tab* tab, | 39 virtual void ShowContextMenuForTab(Tab* tab, |
37 const gfx::Point& p, | 40 const gfx::Point& p, |
38 ui::MenuSourceType source_type) OVERRIDE {} | 41 ui::MenuSourceType source_type) OVERRIDE {} |
39 virtual bool IsActiveTab(const Tab* tab) const OVERRIDE { | 42 virtual bool IsActiveTab(const Tab* tab) const OVERRIDE { |
40 return active_tab_; | 43 return active_tab_; |
41 } | 44 } |
42 virtual bool IsTabSelected(const Tab* tab) const OVERRIDE { | 45 virtual bool IsTabSelected(const Tab* tab) const OVERRIDE { |
43 return false; | 46 return false; |
44 } | 47 } |
45 virtual bool IsTabPinned(const Tab* tab) const OVERRIDE { return false; } | 48 virtual bool IsTabPinned(const Tab* tab) const OVERRIDE { return false; } |
(...skipping 18 matching lines...) Expand all Loading... |
64 ui::AXViewState* state) OVERRIDE{}; | 67 ui::AXViewState* state) OVERRIDE{}; |
65 | 68 |
66 private: | 69 private: |
67 ui::ListSelectionModel selection_model_; | 70 ui::ListSelectionModel selection_model_; |
68 bool immersive_style_; | 71 bool immersive_style_; |
69 bool active_tab_; | 72 bool active_tab_; |
70 | 73 |
71 DISALLOW_COPY_AND_ASSIGN(FakeTabController); | 74 DISALLOW_COPY_AND_ASSIGN(FakeTabController); |
72 }; | 75 }; |
73 | 76 |
74 class TabTest : public views::ViewsTestBase { | 77 class TabTest : public views::ViewsTestBase, |
| 78 public ::testing::WithParamInterface<bool> { |
75 public: | 79 public: |
76 TabTest() {} | 80 TabTest() {} |
77 virtual ~TabTest() {} | 81 virtual ~TabTest() {} |
78 | 82 |
79 static void DisableMediaIndicatorAnimation(Tab* tab) { | 83 bool testing_for_rtl_locale() const { return GetParam(); } |
80 tab->media_indicator_animation_.reset(); | 84 |
81 tab->animating_media_state_ = tab->data_.media_state; | 85 virtual void SetUp() OVERRIDE { |
| 86 if (testing_for_rtl_locale()) { |
| 87 original_locale_ = base::i18n::GetConfiguredLocale(); |
| 88 base::i18n::SetICUDefaultLocale("he"); |
| 89 } |
| 90 views::ViewsTestBase::SetUp(); |
| 91 } |
| 92 |
| 93 virtual void TearDown() OVERRIDE { |
| 94 views::ViewsTestBase::TearDown(); |
| 95 if (testing_for_rtl_locale()) |
| 96 base::i18n::SetICUDefaultLocale(original_locale_); |
82 } | 97 } |
83 | 98 |
84 static void CheckForExpectedLayoutAndVisibilityOfElements(const Tab& tab) { | 99 static void CheckForExpectedLayoutAndVisibilityOfElements(const Tab& tab) { |
85 // Check whether elements are visible when they are supposed to be, given | 100 // Check whether elements are visible when they are supposed to be, given |
86 // Tab size and TabRendererData state. | 101 // Tab size and TabRendererData state. |
87 if (tab.data_.mini) { | 102 if (tab.data_.mini) { |
88 EXPECT_EQ(1, tab.IconCapacity()); | 103 EXPECT_EQ(1, tab.IconCapacity()); |
89 if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) { | 104 if (tab.data_.media_state != TAB_MEDIA_STATE_NONE) { |
90 EXPECT_FALSE(tab.ShouldShowIcon()); | 105 EXPECT_FALSE(tab.ShouldShowIcon()); |
91 EXPECT_TRUE(tab.ShouldShowMediaIndicator()); | 106 EXPECT_TRUE(tab.ShouldShowMediaIndicator()); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 // are fully within the contents bounds. | 167 // are fully within the contents bounds. |
153 const gfx::Rect contents_bounds = tab.GetContentsBounds(); | 168 const gfx::Rect contents_bounds = tab.GetContentsBounds(); |
154 if (tab.ShouldShowIcon()) { | 169 if (tab.ShouldShowIcon()) { |
155 EXPECT_LE(contents_bounds.x(), tab.favicon_bounds_.x()); | 170 EXPECT_LE(contents_bounds.x(), tab.favicon_bounds_.x()); |
156 if (tab.title_->width() > 0) | 171 if (tab.title_->width() > 0) |
157 EXPECT_LE(tab.favicon_bounds_.right(), tab.title_->x()); | 172 EXPECT_LE(tab.favicon_bounds_.right(), tab.title_->x()); |
158 EXPECT_LE(contents_bounds.y(), tab.favicon_bounds_.y()); | 173 EXPECT_LE(contents_bounds.y(), tab.favicon_bounds_.y()); |
159 EXPECT_LE(tab.favicon_bounds_.bottom(), contents_bounds.bottom()); | 174 EXPECT_LE(tab.favicon_bounds_.bottom(), contents_bounds.bottom()); |
160 } | 175 } |
161 if (tab.ShouldShowIcon() && tab.ShouldShowMediaIndicator()) | 176 if (tab.ShouldShowIcon() && tab.ShouldShowMediaIndicator()) |
162 EXPECT_LE(tab.favicon_bounds_.right(), tab.media_indicator_bounds_.x()); | 177 EXPECT_LE(tab.favicon_bounds_.right(), GetMediaIndicatorBounds(tab).x()); |
163 if (tab.ShouldShowMediaIndicator()) { | 178 if (tab.ShouldShowMediaIndicator()) { |
164 if (tab.title_->width() > 0) { | 179 if (tab.title_->width() > 0) { |
165 EXPECT_LE(tab.title_->bounds().right(), | 180 EXPECT_LE(tab.title_->bounds().right(), |
166 tab.media_indicator_bounds_.x()); | 181 GetMediaIndicatorBounds(tab).x()); |
167 } | 182 } |
168 EXPECT_LE(tab.media_indicator_bounds_.right(), contents_bounds.right()); | 183 EXPECT_LE(GetMediaIndicatorBounds(tab).right(), contents_bounds.right()); |
169 EXPECT_LE(contents_bounds.y(), tab.media_indicator_bounds_.y()); | 184 EXPECT_LE(contents_bounds.y(), GetMediaIndicatorBounds(tab).y()); |
170 EXPECT_LE(tab.media_indicator_bounds_.bottom(), contents_bounds.bottom()); | 185 EXPECT_LE(GetMediaIndicatorBounds(tab).bottom(), |
| 186 contents_bounds.bottom()); |
171 } | 187 } |
172 if (tab.ShouldShowMediaIndicator() && tab.ShouldShowCloseBox()) { | 188 if (tab.ShouldShowMediaIndicator() && tab.ShouldShowCloseBox()) { |
173 // Note: The media indicator can overlap the left-insets of the close box, | 189 // Note: The media indicator can overlap the left-insets of the close box, |
174 // but should otherwise be to the left of the close button. | 190 // but should otherwise be to the left of the close button. |
175 EXPECT_LE(tab.media_indicator_bounds_.right(), | 191 EXPECT_LE(GetMediaIndicatorBounds(tab).right(), |
176 tab.close_button_->bounds().x() + | 192 tab.close_button_->bounds().x() + |
177 tab.close_button_->GetInsets().left()); | 193 tab.close_button_->GetInsets().left()); |
178 } | 194 } |
179 if (tab.ShouldShowCloseBox()) { | 195 if (tab.ShouldShowCloseBox()) { |
180 // Note: The title bounds can overlap the left-insets of the close box, | 196 // Note: The title bounds can overlap the left-insets of the close box, |
181 // but should otherwise be to the left of the close button. | 197 // but should otherwise be to the left of the close button. |
182 if (tab.title_->width() > 0) { | 198 if (tab.title_->width() > 0) { |
183 EXPECT_LE(tab.title_->bounds().right(), | 199 EXPECT_LE(tab.title_->bounds().right(), |
184 tab.close_button_->bounds().x() + | 200 tab.close_button_->bounds().x() + |
185 tab.close_button_->GetInsets().left()); | 201 tab.close_button_->GetInsets().left()); |
186 } | 202 } |
187 EXPECT_LE(tab.close_button_->bounds().right(), contents_bounds.right()); | 203 EXPECT_LE(tab.close_button_->bounds().right(), contents_bounds.right()); |
188 EXPECT_LE(contents_bounds.y(), tab.close_button_->bounds().y()); | 204 EXPECT_LE(contents_bounds.y(), tab.close_button_->bounds().y()); |
189 EXPECT_LE(tab.close_button_->bounds().bottom(), contents_bounds.bottom()); | 205 EXPECT_LE(tab.close_button_->bounds().bottom(), contents_bounds.bottom()); |
190 } | 206 } |
191 } | 207 } |
| 208 |
| 209 private: |
| 210 static gfx::Rect GetMediaIndicatorBounds(const Tab& tab) { |
| 211 if (!tab.media_indicator_button_) { |
| 212 ADD_FAILURE(); |
| 213 return gfx::Rect(); |
| 214 } |
| 215 return tab.media_indicator_button_->bounds(); |
| 216 } |
| 217 |
| 218 std::string original_locale_; |
192 }; | 219 }; |
193 | 220 |
194 TEST_F(TabTest, HitTestTopPixel) { | 221 TEST_P(TabTest, HitTestTopPixel) { |
| 222 if (testing_for_rtl_locale() && !base::i18n::IsRTL()) { |
| 223 LOG(WARNING) << "Testing of RTL locale not supported on current platform."; |
| 224 return; |
| 225 } |
| 226 |
195 Widget widget; | 227 Widget widget; |
196 Widget::InitParams params(CreateParams(Widget::InitParams::TYPE_WINDOW)); | 228 Widget::InitParams params(CreateParams(Widget::InitParams::TYPE_WINDOW)); |
197 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 229 params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
198 params.bounds.SetRect(10, 20, 300, 400); | 230 params.bounds.SetRect(10, 20, 300, 400); |
199 widget.Init(params); | 231 widget.Init(params); |
200 | 232 |
201 FakeTabController tab_controller; | 233 FakeTabController tab_controller; |
202 Tab tab(&tab_controller); | 234 Tab tab(&tab_controller); |
203 widget.GetContentsView()->AddChildView(&tab); | 235 widget.GetContentsView()->AddChildView(&tab); |
204 tab.SetBoundsRect(gfx::Rect(gfx::Point(0, 0), Tab::GetStandardSize())); | 236 tab.SetBoundsRect(gfx::Rect(gfx::Point(0, 0), Tab::GetStandardSize())); |
205 | 237 |
206 // Tabs have some shadow in the top, so by default we don't hit the tab there. | 238 // Tabs have some shadow in the top, so by default we don't hit the tab there. |
207 int middle_x = tab.width() / 2; | 239 int middle_x = tab.width() / 2; |
208 EXPECT_FALSE(tab.HitTestPoint(gfx::Point(middle_x, 0))); | 240 EXPECT_FALSE(tab.HitTestPoint(gfx::Point(middle_x, 0))); |
209 | 241 |
210 // Tabs are slanted, so a click halfway down the left edge won't hit it. | 242 // Tabs are slanted, so a click halfway down the left edge won't hit it. |
211 int middle_y = tab.height() / 2; | 243 int middle_y = tab.height() / 2; |
212 EXPECT_FALSE(tab.HitTestPoint(gfx::Point(0, middle_y))); | 244 EXPECT_FALSE(tab.HitTestPoint(gfx::Point(0, middle_y))); |
213 | 245 |
214 // If the window is maximized, however, we want clicks in the top edge to | 246 // If the window is maximized, however, we want clicks in the top edge to |
215 // select the tab. | 247 // select the tab. |
216 widget.Maximize(); | 248 widget.Maximize(); |
217 EXPECT_TRUE(tab.HitTestPoint(gfx::Point(middle_x, 0))); | 249 EXPECT_TRUE(tab.HitTestPoint(gfx::Point(middle_x, 0))); |
218 | 250 |
219 // But clicks in the area above the slanted sides should still miss. | 251 // But clicks in the area above the slanted sides should still miss. |
220 EXPECT_FALSE(tab.HitTestPoint(gfx::Point(0, 0))); | 252 EXPECT_FALSE(tab.HitTestPoint(gfx::Point(0, 0))); |
221 EXPECT_FALSE(tab.HitTestPoint(gfx::Point(tab.width() - 1, 0))); | 253 EXPECT_FALSE(tab.HitTestPoint(gfx::Point(tab.width() - 1, 0))); |
222 } | 254 } |
223 | 255 |
224 TEST_F(TabTest, LayoutAndVisibilityOfElements) { | 256 TEST_P(TabTest, LayoutAndVisibilityOfElements) { |
| 257 if (testing_for_rtl_locale() && !base::i18n::IsRTL()) { |
| 258 LOG(WARNING) << "Testing of RTL locale not supported on current platform."; |
| 259 return; |
| 260 } |
| 261 |
225 static const TabMediaState kMediaStatesToTest[] = { | 262 static const TabMediaState kMediaStatesToTest[] = { |
226 TAB_MEDIA_STATE_NONE, TAB_MEDIA_STATE_CAPTURING, | 263 TAB_MEDIA_STATE_NONE, TAB_MEDIA_STATE_CAPTURING, |
227 TAB_MEDIA_STATE_AUDIO_PLAYING | 264 TAB_MEDIA_STATE_AUDIO_PLAYING, TAB_MEDIA_STATE_AUDIO_MUTING |
228 }; | 265 }; |
229 | 266 |
230 FakeTabController controller; | 267 FakeTabController controller; |
231 Tab tab(&controller); | 268 Tab tab(&controller); |
232 | 269 |
233 SkBitmap bitmap; | 270 SkBitmap bitmap; |
234 bitmap.allocN32Pixels(16, 16); | 271 bitmap.allocN32Pixels(16, 16); |
235 TabRendererData data; | 272 TabRendererData data; |
236 data.favicon = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); | 273 data.favicon = gfx::ImageSkia::CreateFrom1xBitmap(bitmap); |
237 | 274 |
238 // Perform layout over all possible combinations, checking for correct | 275 // Perform layout over all possible combinations, checking for correct |
239 // results. | 276 // results. |
240 for (int is_mini_tab = 0; is_mini_tab < 2; ++is_mini_tab) { | 277 for (int is_mini_tab = 0; is_mini_tab < 2; ++is_mini_tab) { |
241 for (int is_active_tab = 0; is_active_tab < 2; ++is_active_tab) { | 278 for (int is_active_tab = 0; is_active_tab < 2; ++is_active_tab) { |
242 for (size_t media_state_index = 0; | 279 for (size_t media_state_index = 0; |
243 media_state_index < arraysize(kMediaStatesToTest); | 280 media_state_index < arraysize(kMediaStatesToTest); |
244 ++media_state_index) { | 281 ++media_state_index) { |
245 const TabMediaState media_state = kMediaStatesToTest[media_state_index]; | 282 const TabMediaState media_state = kMediaStatesToTest[media_state_index]; |
246 SCOPED_TRACE(::testing::Message() | 283 SCOPED_TRACE(::testing::Message() |
247 << (is_active_tab ? "Active" : "Inactive") << ' ' | 284 << (is_active_tab ? "Active" : "Inactive") << ' ' |
248 << (is_mini_tab ? "Mini " : "") | 285 << (is_mini_tab ? "Mini " : "") |
249 << "Tab with media indicator state " << media_state); | 286 << "Tab with media indicator state " << media_state); |
250 | 287 |
251 data.mini = !!is_mini_tab; | 288 data.mini = !!is_mini_tab; |
252 controller.set_active_tab(!!is_active_tab); | 289 controller.set_active_tab(!!is_active_tab); |
253 data.media_state = media_state; | 290 data.media_state = media_state; |
254 tab.SetData(data); | 291 tab.SetData(data); |
255 | 292 |
256 // Disable the media indicator animation so that the layout/visibility | |
257 // logic can be tested effectively. If the animation was left enabled, | |
258 // the ShouldShowMediaIndicator() method would return true during | |
259 // fade-out transitions. | |
260 DisableMediaIndicatorAnimation(&tab); | |
261 | |
262 // Test layout for every width from standard to minimum. | 293 // Test layout for every width from standard to minimum. |
263 gfx::Rect bounds(gfx::Point(0, 0), Tab::GetStandardSize()); | 294 gfx::Rect bounds(gfx::Point(0, 0), Tab::GetStandardSize()); |
264 int min_width; | 295 int min_width; |
265 if (is_mini_tab) { | 296 if (is_mini_tab) { |
266 bounds.set_width(Tab::GetMiniWidth()); | 297 bounds.set_width(Tab::GetMiniWidth()); |
267 min_width = Tab::GetMiniWidth(); | 298 min_width = Tab::GetMiniWidth(); |
268 } else { | 299 } else { |
269 min_width = is_active_tab ? Tab::GetMinimumSelectedSize().width() : | 300 min_width = is_active_tab ? Tab::GetMinimumSelectedSize().width() : |
270 Tab::GetMinimumUnselectedSize().width(); | 301 Tab::GetMinimumUnselectedSize().width(); |
271 } | 302 } |
272 while (bounds.width() >= min_width) { | 303 while (bounds.width() >= min_width) { |
273 SCOPED_TRACE(::testing::Message() << "bounds=" << bounds.ToString()); | 304 SCOPED_TRACE(::testing::Message() << "bounds=" << bounds.ToString()); |
274 tab.SetBoundsRect(bounds); // Invokes Tab::Layout(). | 305 tab.SetBoundsRect(bounds); // Invokes Tab::Layout(). |
275 CheckForExpectedLayoutAndVisibilityOfElements(tab); | 306 CheckForExpectedLayoutAndVisibilityOfElements(tab); |
276 bounds.set_width(bounds.width() - 1); | 307 bounds.set_width(bounds.width() - 1); |
277 } | 308 } |
278 } | 309 } |
279 } | 310 } |
280 } | 311 } |
281 } | 312 } |
282 | 313 |
283 // Regression test for http://crbug.com/226253. Calling Layout() more than once | 314 // Regression test for http://crbug.com/226253. Calling Layout() more than once |
284 // shouldn't change the insets of the close button. | 315 // shouldn't change the insets of the close button. |
285 TEST_F(TabTest, CloseButtonLayout) { | 316 TEST_P(TabTest, CloseButtonLayout) { |
| 317 if (testing_for_rtl_locale() && !base::i18n::IsRTL()) { |
| 318 LOG(WARNING) << "Testing of RTL locale not supported on current platform."; |
| 319 return; |
| 320 } |
| 321 |
286 FakeTabController tab_controller; | 322 FakeTabController tab_controller; |
287 Tab tab(&tab_controller); | 323 Tab tab(&tab_controller); |
288 tab.SetBounds(0, 0, 100, 50); | 324 tab.SetBounds(0, 0, 100, 50); |
289 tab.Layout(); | 325 tab.Layout(); |
290 gfx::Insets close_button_insets = tab.close_button_->GetInsets(); | 326 gfx::Insets close_button_insets = tab.close_button_->GetInsets(); |
291 tab.Layout(); | 327 tab.Layout(); |
292 gfx::Insets close_button_insets_2 = tab.close_button_->GetInsets(); | 328 gfx::Insets close_button_insets_2 = tab.close_button_->GetInsets(); |
293 EXPECT_EQ(close_button_insets.top(), close_button_insets_2.top()); | 329 EXPECT_EQ(close_button_insets.top(), close_button_insets_2.top()); |
294 EXPECT_EQ(close_button_insets.left(), close_button_insets_2.left()); | 330 EXPECT_EQ(close_button_insets.left(), close_button_insets_2.left()); |
295 EXPECT_EQ(close_button_insets.bottom(), close_button_insets_2.bottom()); | 331 EXPECT_EQ(close_button_insets.bottom(), close_button_insets_2.bottom()); |
296 EXPECT_EQ(close_button_insets.right(), close_button_insets_2.right()); | 332 EXPECT_EQ(close_button_insets.right(), close_button_insets_2.right()); |
297 | 333 |
298 // Also make sure the close button is sized as large as the tab. | 334 // Also make sure the close button is sized as large as the tab. |
299 EXPECT_EQ(50, tab.close_button_->bounds().height()); | 335 EXPECT_EQ(50, tab.close_button_->bounds().height()); |
300 } | 336 } |
| 337 |
| 338 // Test in both a LTR and a RTL locale. Note: The fact that the UI code is |
| 339 // configured for an RTL locale does *not* change how the coordinates are |
| 340 // examined in the tests above because views::View and friends are supposed to |
| 341 // auto-mirror the widgets when painting. Thus, what we're testing here is that |
| 342 // there's no code in Tab that will erroneously subvert this automatic |
| 343 // coordinate translation. http://crbug.com/384179 |
| 344 INSTANTIATE_TEST_CASE_P(, TabTest, ::testing::Values(false, true)); |
OLD | NEW |