autofill_popup_controller_unittest.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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 3// found in the LICENSE file. 4 5#include "base/memory/scoped_ptr.h" 6#include "base/memory/weak_ptr.h" 7#include "base/prefs/testing_pref_service.h" 8#include "base/strings/utf_string_conversions.h" 9#include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h" 10#include "chrome/browser/ui/autofill/autofill_popup_view.h" 11#include "chrome/test/base/chrome_render_view_host_test_harness.h" 12#include "chrome/test/base/testing_profile.h" 13#include "components/autofill/content/browser/autofill_driver_impl.h" 14#include "components/autofill/core/browser/autofill_external_delegate.h" 15#include "components/autofill/core/browser/autofill_manager.h" 16#include "components/autofill/core/browser/test_autofill_external_delegate.h" 17#include "components/autofill/core/browser/test_autofill_manager_delegate.h" 18#include "testing/gmock/include/gmock/gmock.h" 19#include "testing/gtest/include/gtest/gtest.h" 20#include "third_party/WebKit/public/web/WebAutofillClient.h" 21#include "ui/gfx/display.h" 22#include "ui/gfx/rect.h" 23 24using ::testing::_; 25using ::testing::AtLeast; 26using ::testing::NiceMock; 27using base::WeakPtr; 28using WebKit::WebAutofillClient; 29 30namespace autofill { 31namespace { 32 33class MockAutofillExternalDelegate : public AutofillExternalDelegate { 34 public: 35 MockAutofillExternalDelegate(content::WebContents* web_contents, 36 AutofillManager* autofill_manager, 37 AutofillDriver* autofill_driver) 38 : AutofillExternalDelegate(web_contents, autofill_manager, 39 autofill_driver) {} 40 virtual ~MockAutofillExternalDelegate() {} 41 42 virtual void DidSelectSuggestion(int identifier) OVERRIDE {} 43 virtual void RemoveSuggestion(const string16& value, int identifier) OVERRIDE 44 {} 45 virtual void ClearPreviewedForm() OVERRIDE {} 46 base::WeakPtr<AutofillExternalDelegate> GetWeakPtr() { 47 return AutofillExternalDelegate::GetWeakPtr(); 48 } 49}; 50 51class MockAutofillManagerDelegate 52 : public autofill::TestAutofillManagerDelegate { 53 public: 54 MockAutofillManagerDelegate() {} 55 virtual ~MockAutofillManagerDelegate() {} 56 57 virtual PrefService* GetPrefs() OVERRIDE { return &prefs_; } 58 59 private: 60 TestingPrefServiceSimple prefs_; 61 62 DISALLOW_COPY_AND_ASSIGN(MockAutofillManagerDelegate); 63}; 64 65class TestAutofillPopupController : public AutofillPopupControllerImpl { 66 public: 67 explicit TestAutofillPopupController( 68 base::WeakPtr<AutofillExternalDelegate> external_delegate, 69 const gfx::RectF& element_bounds) 70 : AutofillPopupControllerImpl( 71 external_delegate, NULL, element_bounds, 72 base::i18n::UNKNOWN_DIRECTION) {} 73 virtual ~TestAutofillPopupController() {} 74 75 void set_display(const gfx::Display display) { 76 display_ = display; 77 } 78 virtual gfx::Display GetDisplayNearestPoint(const gfx::Point& point) const 79 OVERRIDE { 80 return display_; 81 } 82 83 // Making protected functions public for testing 84 using AutofillPopupControllerImpl::SetPopupBounds; 85 using AutofillPopupControllerImpl::names; 86 using AutofillPopupControllerImpl::subtexts; 87 using AutofillPopupControllerImpl::identifiers; 88 using AutofillPopupControllerImpl::selected_line; 89 using AutofillPopupControllerImpl::SetSelectedLine; 90 using AutofillPopupControllerImpl::SelectNextLine; 91 using AutofillPopupControllerImpl::SelectPreviousLine; 92 using AutofillPopupControllerImpl::RemoveSelectedLine; 93 using AutofillPopupControllerImpl::popup_bounds; 94 using AutofillPopupControllerImpl::element_bounds; 95#if !defined(OS_ANDROID) 96 using AutofillPopupControllerImpl::GetNameFontForRow; 97 using AutofillPopupControllerImpl::subtext_font; 98 using AutofillPopupControllerImpl::RowWidthWithoutText; 99#endif 100 using AutofillPopupControllerImpl::SetValues; 101 using AutofillPopupControllerImpl::GetDesiredPopupWidth; 102 using AutofillPopupControllerImpl::GetDesiredPopupHeight; 103 using AutofillPopupControllerImpl::GetWeakPtr; 104 MOCK_METHOD1(InvalidateRow, void(size_t)); 105 MOCK_METHOD0(UpdateBoundsAndRedrawPopup, void()); 106 MOCK_METHOD0(Hide, void()); 107 108 void DoHide() { 109 AutofillPopupControllerImpl::Hide(); 110 } 111 112 private: 113 virtual void ShowView() OVERRIDE {} 114 115 gfx::Display display_; 116}; 117 118} // namespace 119 120class AutofillPopupControllerUnitTest : public ChromeRenderViewHostTestHarness { 121 public: 122 AutofillPopupControllerUnitTest() 123 : manager_delegate_(new MockAutofillManagerDelegate()), 124 autofill_popup_controller_(NULL) {} 125 virtual ~AutofillPopupControllerUnitTest() {} 126 127 virtual void SetUp() OVERRIDE { 128 ChromeRenderViewHostTestHarness::SetUp(); 129 130 AutofillDriverImpl::CreateForWebContentsAndDelegate( 131 web_contents(), 132 manager_delegate_.get(), 133 "en-US", 134 AutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER); 135 AutofillDriverImpl* driver = 136 AutofillDriverImpl::FromWebContents(web_contents()); 137 external_delegate_.reset( 138 new NiceMock<MockAutofillExternalDelegate>( 139 web_contents(), 140 driver->autofill_manager(), 141 driver)); 142 143 autofill_popup_controller_ = 144 new testing::NiceMock<TestAutofillPopupController>( 145 external_delegate_->GetWeakPtr(), gfx::Rect()); 146 } 147 148 virtual void TearDown() OVERRIDE { 149 // This will make sure the controller and the view (if any) are both 150 // cleaned up. 151 if (autofill_popup_controller_) 152 autofill_popup_controller_->DoHide(); 153 154 external_delegate_.reset(); 155 ChromeRenderViewHostTestHarness::TearDown(); 156 } 157 158 TestAutofillPopupController* popup_controller() { 159 return autofill_popup_controller_; 160 } 161 162 MockAutofillExternalDelegate* delegate() { 163 return external_delegate_.get(); 164 } 165 166 protected: 167 scoped_ptr<MockAutofillManagerDelegate> manager_delegate_; 168 scoped_ptr<NiceMock<MockAutofillExternalDelegate> > external_delegate_; 169 testing::NiceMock<TestAutofillPopupController>* autofill_popup_controller_; 170}; 171 172TEST_F(AutofillPopupControllerUnitTest, SetBounds) { 173 // Ensure the popup size can be set and causes a redraw. 174 gfx::Rect popup_bounds(10, 10, 100, 100); 175 176 EXPECT_CALL(*autofill_popup_controller_, 177 UpdateBoundsAndRedrawPopup()); 178 179 popup_controller()->SetPopupBounds(popup_bounds); 180 181 EXPECT_EQ(popup_bounds, popup_controller()->popup_bounds()); 182} 183 184TEST_F(AutofillPopupControllerUnitTest, ChangeSelectedLine) { 185 // Set up the popup. 186 std::vector<string16> names(2, string16()); 187 std::vector<int> autofill_ids(2, 0); 188 autofill_popup_controller_->Show(names, names, names, autofill_ids); 189 190 EXPECT_LT(autofill_popup_controller_->selected_line(), 0); 191 // Check that there are at least 2 values so that the first and last selection 192 // are different. 193 EXPECT_GE(2, 194 static_cast<int>(autofill_popup_controller_->subtexts().size())); 195 196 // Test wrapping before the front. 197 autofill_popup_controller_->SelectPreviousLine(); 198 EXPECT_EQ(static_cast<int>( 199 autofill_popup_controller_->subtexts().size() - 1), 200 autofill_popup_controller_->selected_line()); 201 202 // Test wrapping after the end. 203 autofill_popup_controller_->SelectNextLine(); 204 EXPECT_EQ(0, autofill_popup_controller_->selected_line()); 205} 206 207TEST_F(AutofillPopupControllerUnitTest, RedrawSelectedLine) { 208 // Set up the popup. 209 std::vector<string16> names(2, string16()); 210 std::vector<int> autofill_ids(2, 0); 211 autofill_popup_controller_->Show(names, names, names, autofill_ids); 212 213 // Make sure that when a new line is selected, it is invalidated so it can 214 // be updated to show it is selected. 215 int selected_line = 0; 216 EXPECT_CALL(*autofill_popup_controller_, InvalidateRow(selected_line)); 217 autofill_popup_controller_->SetSelectedLine(selected_line); 218 219 // Ensure that the row isn't invalidated if it didn't change. 220 EXPECT_CALL(*autofill_popup_controller_, 221 InvalidateRow(selected_line)).Times(0); 222 autofill_popup_controller_->SetSelectedLine(selected_line); 223 224 // Change back to no selection. 225 EXPECT_CALL(*autofill_popup_controller_, InvalidateRow(selected_line)); 226 autofill_popup_controller_->SetSelectedLine(-1); 227} 228 229TEST_F(AutofillPopupControllerUnitTest, RemoveLine) { 230 // Set up the popup. 231 std::vector<string16> names(3, string16()); 232 std::vector<int> autofill_ids; 233 autofill_ids.push_back(1); 234 autofill_ids.push_back(1); 235 autofill_ids.push_back(WebAutofillClient::MenuItemIDAutofillOptions); 236 autofill_popup_controller_->Show(names, names, names, autofill_ids); 237 238 // Generate a popup, so it can be hidden later. It doesn't matter what the 239 // external_delegate thinks is being shown in the process, since we are just 240 // testing the popup here. 241 autofill::GenerateTestAutofillPopup(external_delegate_.get()); 242 243 // No line is selected so the removal should fail. 244 EXPECT_FALSE(autofill_popup_controller_->RemoveSelectedLine()); 245 246 // Try to remove the last entry and ensure it fails (it is an option). 247 autofill_popup_controller_->SetSelectedLine( 248 autofill_popup_controller_->subtexts().size() - 1); 249 EXPECT_FALSE(autofill_popup_controller_->RemoveSelectedLine()); 250 EXPECT_LE(0, autofill_popup_controller_->selected_line()); 251 252 // Remove the first entry. The popup should be redrawn since its size has 253 // changed. 254 EXPECT_CALL(*autofill_popup_controller_, UpdateBoundsAndRedrawPopup()); 255 autofill_popup_controller_->SetSelectedLine(0); 256 EXPECT_TRUE(autofill_popup_controller_->RemoveSelectedLine()); 257 258 // Remove the last entry. The popup should then be hidden since there are 259 // no Autofill entries left. 260 EXPECT_CALL(*autofill_popup_controller_, Hide()); 261 autofill_popup_controller_->SetSelectedLine(0); 262 EXPECT_TRUE(autofill_popup_controller_->RemoveSelectedLine()); 263} 264 265TEST_F(AutofillPopupControllerUnitTest, RemoveOnlyLine) { 266 // Set up the popup. 267 std::vector<string16> names(1, string16()); 268 std::vector<int> autofill_ids; 269 autofill_ids.push_back(1); 270 autofill_popup_controller_->Show(names, names, names, autofill_ids); 271 272 // Generate a popup. 273 autofill::GenerateTestAutofillPopup(external_delegate_.get()); 274 275 // Select the only line. 276 autofill_popup_controller_->SetSelectedLine(0); 277 278 // Remove the only line. There should be no row invalidation and the popup 279 // should then be hidden since there are no Autofill entries left. 280 EXPECT_CALL(*autofill_popup_controller_, Hide()); 281 EXPECT_CALL(*autofill_popup_controller_, InvalidateRow(_)).Times(0); 282 EXPECT_TRUE(autofill_popup_controller_->RemoveSelectedLine()); 283} 284 285TEST_F(AutofillPopupControllerUnitTest, SkipSeparator) { 286 // Set up the popup. 287 std::vector<string16> names(3, string16()); 288 std::vector<int> autofill_ids; 289 autofill_ids.push_back(1); 290 autofill_ids.push_back(WebAutofillClient::MenuItemIDSeparator); 291 autofill_ids.push_back(WebAutofillClient::MenuItemIDAutofillOptions); 292 autofill_popup_controller_->Show(names, names, names, autofill_ids); 293 294 autofill_popup_controller_->SetSelectedLine(0); 295 296 // Make sure next skips the unselectable separator. 297 autofill_popup_controller_->SelectNextLine(); 298 EXPECT_EQ(2, autofill_popup_controller_->selected_line()); 299 300 // Make sure previous skips the unselectable separator. 301 autofill_popup_controller_->SelectPreviousLine(); 302 EXPECT_EQ(0, autofill_popup_controller_->selected_line()); 303} 304 305TEST_F(AutofillPopupControllerUnitTest, RowWidthWithoutText) { 306 std::vector<string16> names(4); 307 std::vector<string16> subtexts(4); 308 std::vector<string16> icons(4); 309 std::vector<int> ids(4); 310 311 // Set up some visible display so the text values are kept. 312 gfx::Display display(0, gfx::Rect(0, 0, 100, 100)); 313 autofill_popup_controller_->set_display(display); 314 315 // Give elements 1 and 3 subtexts and elements 2 and 3 icons, to ensure 316 // all combinations of subtexts and icons. 317 subtexts[1] = ASCIIToUTF16("x"); 318 subtexts[3] = ASCIIToUTF16("x"); 319 icons[2] = ASCIIToUTF16("x"); 320 icons[3] = ASCIIToUTF16("x"); 321 autofill_popup_controller_->Show(names, subtexts, icons, ids); 322 323 int base_size = 324 AutofillPopupView::kEndPadding * 2 + 325 AutofillPopupView::kBorderThickness * 2; 326 int subtext_increase = AutofillPopupView::kNamePadding; 327 int icon_increase = AutofillPopupView::kIconPadding + 328 AutofillPopupView::kAutofillIconWidth; 329 330 EXPECT_EQ(base_size, autofill_popup_controller_->RowWidthWithoutText(0)); 331 EXPECT_EQ(base_size + subtext_increase, 332 autofill_popup_controller_->RowWidthWithoutText(1)); 333 EXPECT_EQ(base_size + icon_increase, 334 autofill_popup_controller_->RowWidthWithoutText(2)); 335 EXPECT_EQ(base_size + subtext_increase + icon_increase, 336 autofill_popup_controller_->RowWidthWithoutText(3)); 337} 338 339TEST_F(AutofillPopupControllerUnitTest, UpdateDataListValues) { 340 std::vector<string16> items; 341 items.push_back(string16()); 342 std::vector<int> ids; 343 ids.push_back(1); 344 345 autofill_popup_controller_->Show(items, items, items, ids); 346 347 EXPECT_EQ(items, autofill_popup_controller_->names()); 348 EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); 349 350 // Add one data list entry. 351 std::vector<string16> data_list_values; 352 data_list_values.push_back(ASCIIToUTF16("data list value 1")); 353 354 autofill_popup_controller_->UpdateDataListValues(data_list_values, 355 data_list_values); 356 357 // Update the expected values. 358 items.insert(items.begin(), data_list_values[0]); 359 items.insert(items.begin() + 1, string16()); 360 ids.insert(ids.begin(), WebAutofillClient::MenuItemIDDataListEntry); 361 ids.insert(ids.begin() + 1, WebAutofillClient::MenuItemIDSeparator); 362 363 EXPECT_EQ(items, autofill_popup_controller_->names()); 364 EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); 365 366 // Add two data list entries (which should replace the current one). 367 data_list_values.push_back(ASCIIToUTF16("data list value 2")); 368 369 autofill_popup_controller_->UpdateDataListValues(data_list_values, 370 data_list_values); 371 372 // Update the expected values. 373 items.insert(items.begin() + 1, data_list_values[1]); 374 ids.insert(ids.begin(), WebAutofillClient::MenuItemIDDataListEntry); 375 376 EXPECT_EQ(items, autofill_popup_controller_->names()); 377 EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); 378 379 // Clear all data list values. 380 data_list_values.clear(); 381 382 autofill_popup_controller_->UpdateDataListValues(data_list_values, 383 data_list_values); 384 385 items.clear(); 386 items.push_back(string16()); 387 ids.clear(); 388 ids.push_back(1); 389 390 EXPECT_EQ(items, autofill_popup_controller_->names()); 391 EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); 392} 393 394TEST_F(AutofillPopupControllerUnitTest, PopupsWithOnlyDataLists) { 395 // Create the popup with a single datalist element. 396 std::vector<string16> items; 397 items.push_back(string16()); 398 std::vector<int> ids; 399 ids.push_back(WebAutofillClient::MenuItemIDDataListEntry); 400 401 autofill_popup_controller_->Show(items, items, items, ids); 402 403 EXPECT_EQ(items, autofill_popup_controller_->names()); 404 EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); 405 406 // Replace the datalist element with a new one. 407 std::vector<string16> data_list_values; 408 data_list_values.push_back(ASCIIToUTF16("data list value 1")); 409 410 autofill_popup_controller_->UpdateDataListValues(data_list_values, 411 data_list_values); 412 413 EXPECT_EQ(data_list_values, autofill_popup_controller_->names()); 414 // The id value should stay the same. 415 EXPECT_EQ(ids, autofill_popup_controller_->identifiers()); 416 417 // Clear datalist values and check that the popup becomes hidden. 418 EXPECT_CALL(*autofill_popup_controller_, Hide()); 419 data_list_values.clear(); 420 autofill_popup_controller_->UpdateDataListValues(data_list_values, 421 data_list_values); 422} 423 424TEST_F(AutofillPopupControllerUnitTest, GetOrCreate) { 425 AutofillDriverImpl* driver = 426 AutofillDriverImpl::FromWebContents(web_contents()); 427 MockAutofillExternalDelegate delegate( 428 web_contents(), driver->autofill_manager(), driver); 429 430 WeakPtr<AutofillPopupControllerImpl> controller = 431 AutofillPopupControllerImpl::GetOrCreate( 432 WeakPtr<AutofillPopupControllerImpl>(), delegate.GetWeakPtr(), NULL, 433 gfx::Rect(), base::i18n::UNKNOWN_DIRECTION); 434 EXPECT_TRUE(controller.get()); 435 436 controller->Hide(); 437 438 controller = AutofillPopupControllerImpl::GetOrCreate( 439 WeakPtr<AutofillPopupControllerImpl>(), delegate.GetWeakPtr(), NULL, 440 gfx::Rect(), base::i18n::UNKNOWN_DIRECTION); 441 EXPECT_TRUE(controller.get()); 442 443 WeakPtr<AutofillPopupControllerImpl> controller2 = 444 AutofillPopupControllerImpl::GetOrCreate(controller, 445 delegate.GetWeakPtr(), 446 NULL, 447 gfx::Rect(), 448 base::i18n::UNKNOWN_DIRECTION); 449 EXPECT_EQ(controller.get(), controller2.get()); 450 controller->Hide(); 451 452 testing::NiceMock<TestAutofillPopupController>* test_controller = 453 new testing::NiceMock<TestAutofillPopupController>(delegate.GetWeakPtr(), 454 gfx::Rect()); 455 EXPECT_CALL(*test_controller, Hide()); 456 457 gfx::RectF bounds(0.f, 0.f, 1.f, 2.f); 458 base::WeakPtr<AutofillPopupControllerImpl> controller3 = 459 AutofillPopupControllerImpl::GetOrCreate( 460 test_controller->GetWeakPtr(), 461 delegate.GetWeakPtr(), 462 NULL, 463 bounds, 464 base::i18n::UNKNOWN_DIRECTION); 465 EXPECT_EQ( 466 bounds, 467 static_cast<AutofillPopupController*>(controller3.get())-> 468 element_bounds()); 469 controller3->Hide(); 470 471 // Hide the test_controller to delete it. 472 test_controller->DoHide(); 473} 474 475TEST_F(AutofillPopupControllerUnitTest, ProperlyResetController) { 476 std::vector<string16> names(2); 477 std::vector<int> ids(2); 478 popup_controller()->SetValues(names, names, names, ids); 479 popup_controller()->SetSelectedLine(0); 480 481 // Now show a new popup with the same controller, but with fewer items. 482 WeakPtr<AutofillPopupControllerImpl> controller = 483 AutofillPopupControllerImpl::GetOrCreate( 484 popup_controller()->GetWeakPtr(), 485 delegate()->GetWeakPtr(), 486 NULL, 487 gfx::Rect(), 488 base::i18n::UNKNOWN_DIRECTION); 489 EXPECT_NE(0, controller->selected_line()); 490 EXPECT_TRUE(controller->names().empty()); 491} 492 493#if !defined(OS_ANDROID) 494TEST_F(AutofillPopupControllerUnitTest, ElideText) { 495 std::vector<string16> names; 496 names.push_back(ASCIIToUTF16("Text that will need to be trimmed")); 497 names.push_back(ASCIIToUTF16("Untrimmed")); 498 499 std::vector<string16> subtexts; 500 subtexts.push_back(ASCIIToUTF16("Label that will be trimmed")); 501 subtexts.push_back(ASCIIToUTF16("Untrimmed")); 502 503 std::vector<string16> icons(2, string16()); 504 std::vector<int> autofill_ids(2, 0); 505 506 // Show the popup once so we can easily generate the size it needs. 507 autofill_popup_controller_->Show(names, subtexts, icons, autofill_ids); 508 509 // Ensure the popup will be too small to display all of the first row. 510 int popup_max_width = 511 autofill_popup_controller_->GetNameFontForRow(0).GetStringWidth( 512 names[0]) + 513 autofill_popup_controller_->subtext_font().GetStringWidth(subtexts[0]) - 514 25; 515 gfx::Rect popup_bounds = gfx::Rect(0, 0, popup_max_width, 0); 516 autofill_popup_controller_->set_display(gfx::Display(0, popup_bounds)); 517 518 autofill_popup_controller_->Show(names, subtexts, icons, autofill_ids); 519 520 // The first element was long so it should have been trimmed. 521 EXPECT_NE(names[0], autofill_popup_controller_->names()[0]); 522 EXPECT_NE(subtexts[0], autofill_popup_controller_->subtexts()[0]); 523 524 // The second element was shorter so it should be unchanged. 525 EXPECT_EQ(names[1], autofill_popup_controller_->names()[1]); 526 EXPECT_EQ(subtexts[1], autofill_popup_controller_->subtexts()[1]); 527} 528#endif 529 530TEST_F(AutofillPopupControllerUnitTest, GrowPopupInSpace) { 531 std::vector<string16> names(1); 532 std::vector<int> autofill_ids(1, 1); 533 534 // Call Show so that GetDesired...() will be able to provide valid values. 535 autofill_popup_controller_->Show(names, names, names, autofill_ids); 536 int desired_width = autofill_popup_controller_->GetDesiredPopupWidth(); 537 int desired_height = autofill_popup_controller_->GetDesiredPopupHeight(); 538 539 // Set up the visible screen space. 540 gfx::Display display(0, 541 gfx::Rect(0, 0, desired_width * 2, desired_height * 2)); 542 543 // Store the possible element bounds and the popup bounds they should result 544 // in. 545 std::vector<gfx::RectF> element_bounds; 546 std::vector<gfx::Rect> expected_popup_bounds; 547 548 // The popup grows down and to the right. 549 element_bounds.push_back(gfx::RectF(0, 0, 0, 0)); 550 expected_popup_bounds.push_back( 551 gfx::Rect(0, 0, desired_width, desired_height)); 552 553 // The popup grows down and to the left. 554 element_bounds.push_back(gfx::RectF(2 * desired_width, 0, 0, 0)); 555 expected_popup_bounds.push_back( 556 gfx::Rect(desired_width, 0, desired_width, desired_height)); 557 558 // The popup grows up and to the right. 559 element_bounds.push_back(gfx::RectF(0, 2 * desired_height, 0, 0)); 560 expected_popup_bounds.push_back( 561 gfx::Rect(0, desired_height, desired_width, desired_height)); 562 563 // The popup grows up and to the left. 564 element_bounds.push_back( 565 gfx::RectF(2 * desired_width, 2 * desired_height, 0, 0)); 566 expected_popup_bounds.push_back( 567 gfx::Rect(desired_width, desired_height, desired_width, desired_height)); 568 569 // The popup would be partial off the top and left side of the screen. 570 element_bounds.push_back( 571 gfx::RectF(-desired_width / 2, -desired_height / 2, 0, 0)); 572 expected_popup_bounds.push_back( 573 gfx::Rect(0, 0, desired_width, desired_height)); 574 575 // The popup would be partially off the bottom and the right side of 576 // the screen. 577 element_bounds.push_back( 578 gfx::RectF(desired_width * 1.5, desired_height * 1.5, 0, 0)); 579 expected_popup_bounds.push_back( 580 gfx::Rect((desired_width + 1) / 2, (desired_height + 1) / 2, 581 desired_width, desired_height)); 582 583 for (size_t i = 0; i < element_bounds.size(); ++i) { 584 AutofillDriverImpl* driver = 585 AutofillDriverImpl::FromWebContents(web_contents()); 586 NiceMock<MockAutofillExternalDelegate> external_delegate( 587 web_contents(), driver->autofill_manager(), driver); 588 TestAutofillPopupController* autofill_popup_controller = 589 new TestAutofillPopupController(external_delegate.GetWeakPtr(), 590 element_bounds[i]); 591 592 autofill_popup_controller->set_display(display); 593 autofill_popup_controller->Show(names, names, names, autofill_ids); 594 595 EXPECT_EQ(expected_popup_bounds[i].ToString(), 596 autofill_popup_controller->popup_bounds().ToString()) << 597 "Popup bounds failed to match for test " << i; 598 599 // Hide the controller to delete it. 600 autofill_popup_controller->DoHide(); 601 } 602} 603 604} // namespace autofill 605