| Index: third_party/WebKit/Source/core/html/HTMLInputElementTest.cpp
|
| diff --git a/third_party/WebKit/Source/core/html/HTMLInputElementTest.cpp b/third_party/WebKit/Source/core/html/HTMLInputElementTest.cpp
|
| index 7ef7a1cc5d89de236a49987cc3d2bbe1bb7b8b59..1d74864c46b58a179b4463d9d89600f83d07b189 100644
|
| --- a/third_party/WebKit/Source/core/html/HTMLInputElementTest.cpp
|
| +++ b/third_party/WebKit/Source/core/html/HTMLInputElementTest.cpp
|
| @@ -5,6 +5,7 @@
|
| #include "core/html/HTMLInputElement.h"
|
|
|
| #include "core/dom/Document.h"
|
| +#include "core/dom/IntersectionObserverController.h"
|
| #include "core/frame/FrameHost.h"
|
| #include "core/frame/FrameView.h"
|
| #include "core/frame/VisualViewport.h"
|
| @@ -13,6 +14,7 @@
|
| #include "core/html/HTMLHtmlElement.h"
|
| #include "core/html/HTMLOptionElement.h"
|
| #include "core/html/forms/DateTimeChooser.h"
|
| +#include "core/loader/EmptyClients.h"
|
| #include "core/testing/DummyPageHolder.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include <memory>
|
| @@ -165,4 +167,119 @@ TEST_F(HTMLInputElementTest, DateTimeChooserSizeParamRespectsScale)
|
| EXPECT_EQ(IntRect(16, 16, 400, 100), params.anchorRectInScreen);
|
| }
|
|
|
| +class TestPasswordChromeClient : public EmptyChromeClient {
|
| +public:
|
| + static TestPasswordChromeClient* create() { return new TestPasswordChromeClient; }
|
| + ~TestPasswordChromeClient() override {}
|
| + void passwordFieldBecameVisible(HTMLInputElement&) override { m_passwordFieldVisibleCalled = true; }
|
| + bool passwordFieldVisibleCalled() { return m_passwordFieldVisibleCalled; }
|
| +private:
|
| + bool m_passwordFieldVisibleCalled = false;
|
| +};
|
| +
|
| +// Tests that ChromeClient::passwordFieldBecameVisible() is called when
|
| +// a visible password field appears on the page.
|
| +TEST_F(HTMLInputElementTest, PasswordVisibilityObserver)
|
| +{
|
| + Page::PageClients pageClients;
|
| + fillWithEmptyClients(pageClients);
|
| + TestPasswordChromeClient* chromeClientUnowned = TestPasswordChromeClient::create();
|
| + pageClients.chromeClient = chromeClientUnowned;
|
| +
|
| + std::unique_ptr<DummyPageHolder> pageHolder = DummyPageHolder::create(IntSize(2000, 2000), &pageClients);
|
| + pageHolder->document().body()->setInnerHTML("<input type='password'>", ASSERT_NO_EXCEPTION);
|
| + pageHolder->document().view()->updateAllLifecyclePhases();
|
| +
|
| + // Force the intersection observer callback to fire synchronously.
|
| + ASSERT_TRUE(pageHolder->document().intersectionObserverController());
|
| + pageHolder->document().intersectionObserverController()->deliverIntersectionObservations();
|
| +
|
| + EXPECT_TRUE(chromeClientUnowned->passwordFieldVisibleCalled());
|
| +}
|
| +
|
| +// Tests that ChromeClient::passwordFieldBecameVisible() is called when
|
| +// a previously invisible password field becomes visible.
|
| +TEST_F(HTMLInputElementTest, InvisiblePasswordFieldBecomesVisible)
|
| +{
|
| + Page::PageClients pageClients;
|
| + fillWithEmptyClients(pageClients);
|
| + TestPasswordChromeClient* chromeClientUnowned = TestPasswordChromeClient::create();
|
| + pageClients.chromeClient = chromeClientUnowned;
|
| +
|
| + std::unique_ptr<DummyPageHolder> pageHolder = DummyPageHolder::create(IntSize(2000, 2000), &pageClients);
|
| + pageHolder->document().body()->setInnerHTML("<input type='password' style='display:none;'>", ASSERT_NO_EXCEPTION);
|
| + pageHolder->document().view()->updateAllLifecyclePhases();
|
| +
|
| + // Force the intersection observer callback to fire synchronously.
|
| + ASSERT_TRUE(pageHolder->document().intersectionObserverController());
|
| + pageHolder->document().intersectionObserverController()->deliverIntersectionObservations();
|
| +
|
| + // The callback should not fire for a hidden password field.
|
| + EXPECT_FALSE(chromeClientUnowned->passwordFieldVisibleCalled());
|
| +
|
| + // Now make the previously invisible password field visible.
|
| + HTMLInputElement* input = toHTMLInputElement(pageHolder->document().body()->firstChild());
|
| + input->setAttribute("style", "", ASSERT_NO_EXCEPTION);
|
| + pageHolder->document().view()->updateAllLifecyclePhases();
|
| + pageHolder->document().intersectionObserverController()->deliverIntersectionObservations();
|
| + EXPECT_TRUE(chromeClientUnowned->passwordFieldVisibleCalled());
|
| +}
|
| +
|
| +// Tests that ChromeClient::passwordFieldBecameVisible() is called when
|
| +// a previously non-password field becomes a password field.
|
| +TEST_F(HTMLInputElementTest, NonPasswordFieldBecomesPassword)
|
| +{
|
| + Page::PageClients pageClients;
|
| + fillWithEmptyClients(pageClients);
|
| + TestPasswordChromeClient* chromeClientUnowned = TestPasswordChromeClient::create();
|
| + pageClients.chromeClient = chromeClientUnowned;
|
| +
|
| + std::unique_ptr<DummyPageHolder> pageHolder = DummyPageHolder::create(IntSize(2000, 2000), &pageClients);
|
| + pageHolder->document().body()->setInnerHTML("<input type='text'>", ASSERT_NO_EXCEPTION);
|
| + pageHolder->document().view()->updateAllLifecyclePhases();
|
| +
|
| + // With no password field on the page, an intersection observer has
|
| + // not been created and the document does not have an
|
| + // intersectionObserverController().
|
| + EXPECT_FALSE(pageHolder->document().intersectionObserverController());
|
| + EXPECT_FALSE(chromeClientUnowned->passwordFieldVisibleCalled());
|
| +
|
| + // Now make the previously non-password field a password field.
|
| + HTMLInputElement* input = toHTMLInputElement(pageHolder->document().body()->firstChild());
|
| + input->setType("password");
|
| + pageHolder->document().view()->updateAllLifecyclePhases();
|
| + ASSERT_TRUE(pageHolder->document().intersectionObserverController());
|
| + pageHolder->document().intersectionObserverController()->deliverIntersectionObservations();
|
| + EXPECT_TRUE(chromeClientUnowned->passwordFieldVisibleCalled());
|
| +}
|
| +
|
| +// Tests that ChromeClient::passwordFieldBecameVisible() is *not* called
|
| +// when a previously invisible password field becomes a visible
|
| +// non-password field.
|
| +TEST_F(HTMLInputElementTest, InvisiblePasswordFieldBecomesVisibleNonPasswordField)
|
| +{
|
| + Page::PageClients pageClients;
|
| + fillWithEmptyClients(pageClients);
|
| + TestPasswordChromeClient* chromeClientUnowned = TestPasswordChromeClient::create();
|
| + pageClients.chromeClient = chromeClientUnowned;
|
| +
|
| + std::unique_ptr<DummyPageHolder> pageHolder = DummyPageHolder::create(IntSize(2000, 2000), &pageClients);
|
| + pageHolder->document().body()->setInnerHTML("<input type='password' style='display:none;'>", ASSERT_NO_EXCEPTION);
|
| + pageHolder->document().view()->updateAllLifecyclePhases();
|
| +
|
| + ASSERT_TRUE(pageHolder->document().intersectionObserverController());
|
| + pageHolder->document().intersectionObserverController()->deliverIntersectionObservations();
|
| + EXPECT_FALSE(chromeClientUnowned->passwordFieldVisibleCalled());
|
| +
|
| + // Now make the previously invisible password field a visible non-password field.
|
| + HTMLInputElement* input = toHTMLInputElement(pageHolder->document().body()->firstChild());
|
| + input->setType("text");
|
| + input->setAttribute("style", "", ASSERT_NO_EXCEPTION);
|
| + pageHolder->document().view()->updateAllLifecyclePhases();
|
| +
|
| + ASSERT_TRUE(pageHolder->document().intersectionObserverController());
|
| + pageHolder->document().intersectionObserverController()->deliverIntersectionObservations();
|
| + EXPECT_FALSE(chromeClientUnowned->passwordFieldVisibleCalled());
|
| +}
|
| +
|
| } // namespace blink
|
|
|