Chromium Code Reviews| Index: Source/WebKit/chromium/tests/WebFrameTest.cpp |
| diff --git a/Source/WebKit/chromium/tests/WebFrameTest.cpp b/Source/WebKit/chromium/tests/WebFrameTest.cpp |
| index ac3158719c1ed8d1d615e058ac22feeb6a5ca04e..4e158224d0b0d17401677af2779a5d181448a012 100644 |
| --- a/Source/WebKit/chromium/tests/WebFrameTest.cpp |
| +++ b/Source/WebKit/chromium/tests/WebFrameTest.cpp |
| @@ -32,6 +32,7 @@ |
| #include "WebFrame.h" |
| +#include <gmock/gmock.h> |
|
abarth-chromium
2013/07/12 23:44:11
I remember someone was telling us to avoid gmock..
Jeffrey Yasskin
2013/07/16 00:38:51
Actual mocks are often a mistake. Here I'm just us
|
| #include <gtest/gtest.h> |
| #include "FrameTestHelpers.h" |
| #include "SkBitmap.h" |
| @@ -75,12 +76,14 @@ |
| #include "core/rendering/TextAutosizer.h" |
| #include "v8.h" |
| #include "public/platform/Platform.h" |
| +#include "public/platform/WebCString.h" |
| #include "public/platform/WebFloatRect.h" |
| #include "public/platform/WebThread.h" |
| #include "public/platform/WebUnitTestSupport.h" |
| #include "public/platform/WebURLResponse.h" |
| #include "wtf/dtoa/utils.h" |
| #include "wtf/Forward.h" |
| +#include <map> |
| using namespace WebKit; |
| using WebCore::Document; |
| @@ -270,6 +273,157 @@ TEST_F(WebFrameTest, ChromePageNoJavascript) |
| EXPECT_EQ(std::string::npos, content.find("Clobbered")); |
| } |
| +#if ENABLE(CSS_CALLBACKS) |
| +struct CssCallbackWebFrameClient : public WebFrameClient { |
|
abarth-chromium
2013/07/12 23:44:11
CssCallbackWebFrameClient -> CSSCallbackWebFrameCl
Jeffrey Yasskin
2013/07/16 00:38:51
Done.
|
| + CssCallbackWebFrameClient() : m_updateCount(0) { } |
| + virtual void didMatchCss(WebFrame* frame, const WebVector<WebString>& newlyMatchingSelectors, const WebVector<WebString>& stoppedMatchingSelectors) OVERRIDE |
|
abarth-chromium
2013/07/12 23:44:11
didMatchCss -> didMatchCSS
Basically, we use CSS
Jeffrey Yasskin
2013/07/16 00:38:51
Done everywhere.
|
| + { |
| + ++m_updateCount; |
| + std::set<std::string>& frameSelectors = m_matchedSelectors[frame]; |
| + for (size_t i = 0; i < newlyMatchingSelectors.size(); ++i) { |
| + std::string selector = newlyMatchingSelectors[i].utf8(); |
| + EXPECT_EQ(0U, frameSelectors.count(selector)) << selector; |
| + frameSelectors.insert(selector); |
| + } |
| + for (size_t i = 0; i < stoppedMatchingSelectors.size(); ++i) { |
| + std::string selector = stoppedMatchingSelectors[i].utf8(); |
| + EXPECT_EQ(1U, frameSelectors.count(selector)) << selector; |
| + frameSelectors.erase(selector); |
| + } |
| + } |
| + |
| + std::map<WebFrame*, std::set<std::string> > m_matchedSelectors; |
| + int m_updateCount; |
| +}; |
| + |
| +TEST_F(WebFrameTest, CssCallbackAuthorStyleSheet) |
| +{ |
| + CssCallbackWebFrameClient client; |
| + WebView* webView = FrameTestHelpers::createWebViewAndLoad("about:blank", true, &client); |
| + WebFrame* frame = webView->mainFrame(); |
| + |
| + frame->loadHTMLString( |
| + "<style>" |
| + // This stylesheet checks that the internal property and value can't be |
| + // set by a stylesheet, only WebDocument::watchCssSelectors(). |
| + "div.initial_on { -internal-callback: none; }" |
| + "div.initial_off { -internal-callback: -internal-presence; }" |
| + "</style>" |
| + "<div class=\"initial_on\"></div>" |
| + "<div class=\"initial_off\"></div>", |
| + toKURL("about:blank")); |
| + runPendingTasks(); |
| + |
| + std::vector<WebString> selectors; |
| + selectors.push_back(WebString::fromUTF8("div.initial_on")); |
| + frame->document().watchCssSelectors(WebVector<WebString>(selectors)); |
| + runPendingTasks(); |
| + EXPECT_EQ(1, client.m_updateCount); |
| + EXPECT_THAT(client.m_matchedSelectors[frame], |
| + testing::ElementsAre("div.initial_on")); |
| + |
| + WebDocument doc = frame->document(); |
| + // Check that adding a watched selector calls back for already-present nodes. |
| + selectors.push_back(WebString::fromUTF8("div.initial_off")); |
| + frame->document().watchCssSelectors(WebVector<WebString>(selectors)); |
| + runPendingTasks(); |
| + EXPECT_EQ(2, client.m_updateCount); |
| + EXPECT_THAT(client.m_matchedSelectors[frame], |
| + testing::ElementsAre("div.initial_off", "div.initial_on")); |
| + |
| + // Check that we can turn off callbacks for certain selectors. |
| + frame->document().watchCssSelectors(WebVector<WebString>()); |
| + runPendingTasks(); |
| + EXPECT_EQ(3, client.m_updateCount); |
| + EXPECT_THAT(client.m_matchedSelectors[frame], |
| + testing::ElementsAre()); |
| + |
| + EXPECT_EQ(1U, client.m_matchedSelectors.size()); |
| + webView->close(); |
| +} |
| + |
| +TEST_F(WebFrameTest, CssCallbackSharedRenderStyle) |
| +{ |
| + CssCallbackWebFrameClient client; |
| + WebView* webView = FrameTestHelpers::createWebViewAndLoad("about:blank", true, &client); |
| + WebFrame* frame = webView->mainFrame(); |
| + WebDocument doc = frame->document(); |
| + |
| + // Check that adding an element calls back when it matches an existing rule. |
| + std::vector<WebString> selectors; |
| + selectors.push_back(WebString::fromUTF8("span")); |
| + doc.watchCssSelectors(WebVector<WebString>(selectors)); |
| + |
| + frame->executeScript(WebScriptSource( |
| + "i1 = document.createElement('span');" |
| + "i1.id = 'first_span';" |
| + "document.body.appendChild(i1)")); |
| + runPendingTasks(); |
| + EXPECT_EQ(1, client.m_updateCount); |
| + EXPECT_THAT(client.m_matchedSelectors[frame], |
| + testing::ElementsAre("span")); |
| + |
| + // Adding a second element that shares a RenderStyle shouldn't call back. |
| + // We use <span>s to avoid default style rules that can set |
| + // RenderStyle::unique(). |
| + frame->executeScript(WebScriptSource( |
| + "i2 = document.createElement('span');" |
| + "i2.id = 'second_span';" |
| + "i1 = document.getElementById('first_span');" |
| + "i1.parentNode.insertBefore(i2, i1.nextSibling);")); |
| + runPendingTasks(); |
| + EXPECT_EQ(1, client.m_updateCount); |
| + EXPECT_THAT(client.m_matchedSelectors[frame], |
| + testing::ElementsAre("span")); |
| + |
| + // Removing the first element shouldn't call back. |
| + frame->executeScript(WebScriptSource( |
| + "i1 = document.getElementById('first_span');" |
| + "i1.parentNode.removeChild(i1);")); |
| + runPendingTasks(); |
| + EXPECT_EQ(1, client.m_updateCount); |
| + EXPECT_THAT(client.m_matchedSelectors[frame], |
| + testing::ElementsAre("span")); |
| + |
| + // But removing the second element *should* call back. |
| + frame->executeScript(WebScriptSource( |
| + "i2 = document.getElementById('second_span');" |
| + "i2.parentNode.removeChild(i2);")); |
| + runPendingTasks(); |
| + EXPECT_EQ(2, client.m_updateCount); |
| + EXPECT_THAT(client.m_matchedSelectors[frame], |
| + testing::ElementsAre()); |
| + |
| + EXPECT_EQ(1U, client.m_matchedSelectors.size()); |
| + webView->close(); |
| +} |
| + |
| +TEST_F(WebFrameTest, CssCallbackMultiSelector) |
| +{ |
| + CssCallbackWebFrameClient client; |
| + WebView* webView = FrameTestHelpers::createWebViewAndLoad("about:blank", true, &client); |
| + WebFrame* frame = webView->mainFrame(); |
| + frame->loadHTMLString("<span></span>", toKURL("about:blank")); |
| + runPendingTasks(); |
| + WebDocument doc = frame->document(); |
| + |
| + // Check that selector lists match as the whole list, not as each element |
| + // independently. |
| + std::vector<WebString> selectors; |
| + selectors.push_back(WebString::fromUTF8("span")); |
| + selectors.push_back(WebString::fromUTF8("span,p")); |
| + frame->document().watchCssSelectors(WebVector<WebString>(selectors)); |
| + |
| + runPendingTasks(); |
| + EXPECT_EQ(1, client.m_updateCount); |
| + EXPECT_THAT(client.m_matchedSelectors[frame], |
| + testing::ElementsAre("span", "span, p")); |
| + |
| + EXPECT_EQ(1U, client.m_matchedSelectors.size()); |
| + webView->close(); |
| +} |
| +#endif |
| + |
| TEST_F(WebFrameTest, DispatchMessageEventWithOriginCheck) |
| { |
| registerMockedHttpURLLoad("postmessage_test.html"); |