1 // Copyright 2014 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.
6 #include "public/web/WebDocument.h"
8 #include "core/CSSPropertyNames.h"
9 #include "core/HTMLNames.h"
10 #include "core/dom/NodeComputedStyle.h"
11 #include "core/dom/StyleEngine.h"
12 #include "core/frame/LocalFrame.h"
13 #include "core/html/HTMLElement.h"
14 #include "core/html/HTMLLinkElement.h"
15 #include "core/page/Page.h"
16 #include "core/style/ComputedStyle.h"
17 #include "platform/RuntimeEnabledFeatures.h"
18 #include "platform/graphics/Color.h"
19 #include "platform/testing/URLTestHelpers.h"
20 #include "platform/weborigin/SchemeRegistry.h"
21 #include "platform/weborigin/SecurityOrigin.h"
22 #include "web/tests/FrameTestHelpers.h"
23 #include <gtest/gtest.h>
27 using blink::FrameTestHelpers::WebViewHelper
;
28 using blink::URLTestHelpers::toKURL
;
30 const char* kDefaultOrigin
= "https://example.test/";
31 const char* kManifestDummyFilePath
= "manifest-dummy.html";
33 class WebDocumentTest
: public ::testing::Test
{
35 static void SetUpTestCase();
37 void loadURL(const std::string
& url
);
38 Document
* topDocument() const;
39 WebDocument
topWebDocument() const;
41 WebViewHelper m_webViewHelper
;
44 void WebDocumentTest::SetUpTestCase()
46 URLTestHelpers::registerMockedURLLoad(toKURL(std::string(kDefaultOrigin
) + kManifestDummyFilePath
), WebString::fromUTF8(kManifestDummyFilePath
));
49 void WebDocumentTest::loadURL(const std::string
& url
)
51 m_webViewHelper
.initializeAndLoad(url
);
54 Document
* WebDocumentTest::topDocument() const
56 return toLocalFrame(m_webViewHelper
.webViewImpl()->page()->mainFrame())->document();
59 WebDocument
WebDocumentTest::topWebDocument() const
61 return m_webViewHelper
.webView()->mainFrame()->document();
64 TEST_F(WebDocumentTest
, InsertStyleSheet
)
66 loadURL("about:blank");
68 WebDocument webDoc
= topWebDocument();
69 Document
* coreDoc
= topDocument();
71 webDoc
.insertStyleSheet("body { color: green }");
73 // Check insertStyleSheet did not cause a synchronous style recalc.
74 unsigned accessCount
= coreDoc
->styleEngine().resolverAccessCount();
75 ASSERT_EQ(0U, accessCount
);
77 HTMLElement
* bodyElement
= coreDoc
->body();
80 const ComputedStyle
& styleBeforeInsertion
= bodyElement
->computedStyleRef();
82 // Inserted stylesheet not yet applied.
83 ASSERT_EQ(Color(0, 0, 0), styleBeforeInsertion
.visitedDependentColor(CSSPropertyColor
));
85 // Apply inserted stylesheet.
86 coreDoc
->updateLayoutTreeIfNeeded();
88 const ComputedStyle
& styleAfterInsertion
= bodyElement
->computedStyleRef();
90 // Inserted stylesheet applied.
91 ASSERT_EQ(Color(0, 128, 0), styleAfterInsertion
.visitedDependentColor(CSSPropertyColor
));
94 TEST_F(WebDocumentTest
, ManifestURL
)
96 loadURL(std::string(kDefaultOrigin
) + kManifestDummyFilePath
);
98 WebDocument webDoc
= topWebDocument();
99 Document
* document
= topDocument();
100 HTMLLinkElement
* linkManifest
= document
->linkManifest();
102 // No href attribute was set.
103 ASSERT_EQ(linkManifest
->href(), static_cast<KURL
>(webDoc
.manifestURL()));
105 // Set to some absolute url.
106 linkManifest
->setAttribute(HTMLNames::hrefAttr
, "http://example.com/manifest.json");
107 ASSERT_EQ(linkManifest
->href(), static_cast<KURL
>(webDoc
.manifestURL()));
109 // Set to some relative url.
110 linkManifest
->setAttribute(HTMLNames::hrefAttr
, "static/manifest.json");
111 ASSERT_EQ(linkManifest
->href(), static_cast<KURL
>(webDoc
.manifestURL()));
114 TEST_F(WebDocumentTest
, ManifestUseCredentials
)
116 loadURL(std::string(kDefaultOrigin
) + kManifestDummyFilePath
);
118 WebDocument webDoc
= topWebDocument();
119 Document
* document
= topDocument();
120 HTMLLinkElement
* linkManifest
= document
->linkManifest();
122 // No crossorigin attribute was set so credentials shouldn't be used.
123 ASSERT_FALSE(linkManifest
->fastHasAttribute(HTMLNames::crossoriginAttr
));
124 ASSERT_FALSE(webDoc
.manifestUseCredentials());
126 // Crossorigin set to a random string shouldn't trigger using credentials.
127 linkManifest
->setAttribute(HTMLNames::crossoriginAttr
, "foobar");
128 ASSERT_FALSE(webDoc
.manifestUseCredentials());
130 // Crossorigin set to 'anonymous' shouldn't trigger using credentials.
131 linkManifest
->setAttribute(HTMLNames::crossoriginAttr
, "anonymous");
132 ASSERT_FALSE(webDoc
.manifestUseCredentials());
134 // Crossorigin set to 'use-credentials' should trigger using credentials.
135 linkManifest
->setAttribute(HTMLNames::crossoriginAttr
, "use-credentials");
136 ASSERT_TRUE(webDoc
.manifestUseCredentials());
141 const char* baseURLOriginA
= "http://example.test:0/";
142 const char* baseURLOriginSubA
= "http://subdomain.example.test:0/";
143 const char* baseURLOriginB
= "http://not-example.test:0/";
144 const char* emptyFile
= "first_party/empty.html";
145 const char* nestedData
= "first_party/nested-data.html";
146 const char* nestedOriginA
= "first_party/nested-originA.html";
147 const char* nestedOriginSubA
= "first_party/nested-originSubA.html";
148 const char* nestedOriginAInOriginA
= "first_party/nested-originA-in-originA.html";
149 const char* nestedOriginAInOriginB
= "first_party/nested-originA-in-originB.html";
150 const char* nestedOriginB
= "first_party/nested-originB.html";
151 const char* nestedOriginBInOriginA
= "first_party/nested-originB-in-originA.html";
152 const char* nestedOriginBInOriginB
= "first_party/nested-originB-in-originB.html";
153 const char* nestedSrcDoc
= "first_party/nested-srcdoc.html";
155 KURL
toOriginA(const char* file
)
157 return toKURL(std::string(baseURLOriginA
) + file
);
160 KURL
toOriginSubA(const char* file
)
162 return toKURL(std::string(baseURLOriginSubA
) + file
);
165 KURL
toOriginB(const char* file
)
167 return toKURL(std::string(baseURLOriginB
) + file
);
170 } // anonymous namespace
172 class WebDocumentFirstPartyTest
: public WebDocumentTest
{
174 static void SetUpTestCase();
177 void load(const char*);
178 Document
* nestedDocument() const;
179 Document
* nestedNestedDocument() const;
182 void WebDocumentFirstPartyTest::SetUpTestCase()
184 URLTestHelpers::registerMockedURLLoad(toOriginA(emptyFile
), WebString::fromUTF8(emptyFile
));
185 URLTestHelpers::registerMockedURLLoad(toOriginA(nestedData
), WebString::fromUTF8(nestedData
));
186 URLTestHelpers::registerMockedURLLoad(toOriginA(nestedOriginA
), WebString::fromUTF8(nestedOriginA
));
187 URLTestHelpers::registerMockedURLLoad(toOriginA(nestedOriginSubA
), WebString::fromUTF8(nestedOriginSubA
));
188 URLTestHelpers::registerMockedURLLoad(toOriginA(nestedOriginAInOriginA
), WebString::fromUTF8(nestedOriginAInOriginA
));
189 URLTestHelpers::registerMockedURLLoad(toOriginA(nestedOriginAInOriginB
), WebString::fromUTF8(nestedOriginAInOriginB
));
190 URLTestHelpers::registerMockedURLLoad(toOriginA(nestedOriginB
), WebString::fromUTF8(nestedOriginB
));
191 URLTestHelpers::registerMockedURLLoad(toOriginA(nestedOriginBInOriginA
), WebString::fromUTF8(nestedOriginBInOriginA
));
192 URLTestHelpers::registerMockedURLLoad(toOriginA(nestedOriginBInOriginB
), WebString::fromUTF8(nestedOriginBInOriginB
));
193 URLTestHelpers::registerMockedURLLoad(toOriginA(nestedSrcDoc
), WebString::fromUTF8(nestedSrcDoc
));
195 URLTestHelpers::registerMockedURLLoad(toOriginSubA(emptyFile
), WebString::fromUTF8(emptyFile
));
197 URLTestHelpers::registerMockedURLLoad(toOriginB(emptyFile
), WebString::fromUTF8(emptyFile
));
198 URLTestHelpers::registerMockedURLLoad(toOriginB(nestedOriginA
), WebString::fromUTF8(nestedOriginA
));
199 URLTestHelpers::registerMockedURLLoad(toOriginB(nestedOriginB
), WebString::fromUTF8(nestedOriginB
));
202 void WebDocumentFirstPartyTest::load(const char* file
)
204 m_webViewHelper
.initializeAndLoad(std::string(baseURLOriginA
) + file
);
207 Document
* WebDocumentFirstPartyTest::nestedDocument() const
209 return toLocalFrame(m_webViewHelper
.webViewImpl()->page()->mainFrame()->tree().firstChild())->document();
212 Document
* WebDocumentFirstPartyTest::nestedNestedDocument() const
214 return toLocalFrame(m_webViewHelper
.webViewImpl()->page()->mainFrame()->tree().firstChild()->tree().firstChild())->document();
217 TEST_F(WebDocumentFirstPartyTest
, Empty
)
221 ASSERT_EQ(toOriginA(emptyFile
), topDocument()->firstPartyForCookies());
224 TEST_F(WebDocumentFirstPartyTest
, NestedOriginA
)
228 ASSERT_EQ(toOriginA(nestedOriginA
), topDocument()->firstPartyForCookies());
229 ASSERT_EQ(toOriginA(nestedOriginA
), nestedDocument()->firstPartyForCookies());
232 TEST_F(WebDocumentFirstPartyTest
, NestedOriginSubA
)
234 load(nestedOriginSubA
);
236 ASSERT_EQ(toOriginA(nestedOriginSubA
), topDocument()->firstPartyForCookies());
237 ASSERT_EQ(toOriginA(nestedOriginSubA
), nestedDocument()->firstPartyForCookies());
240 TEST_F(WebDocumentFirstPartyTest
, NestedOriginAInOriginA
)
242 load(nestedOriginAInOriginA
);
244 ASSERT_EQ(toOriginA(nestedOriginAInOriginA
), topDocument()->firstPartyForCookies());
245 ASSERT_EQ(toOriginA(nestedOriginAInOriginA
), nestedDocument()->firstPartyForCookies());
246 ASSERT_EQ(toOriginA(nestedOriginAInOriginA
), nestedNestedDocument()->firstPartyForCookies());
249 TEST_F(WebDocumentFirstPartyTest
, NestedOriginAInOriginB
)
251 load(nestedOriginAInOriginB
);
253 ASSERT_EQ(toOriginA(nestedOriginAInOriginB
), topDocument()->firstPartyForCookies());
254 ASSERT_EQ(SecurityOrigin::urlWithUniqueSecurityOrigin(), nestedDocument()->firstPartyForCookies());
255 ASSERT_EQ(SecurityOrigin::urlWithUniqueSecurityOrigin(), nestedNestedDocument()->firstPartyForCookies());
258 TEST_F(WebDocumentFirstPartyTest
, NestedOriginB
)
262 ASSERT_EQ(toOriginA(nestedOriginB
), topDocument()->firstPartyForCookies());
263 ASSERT_EQ(SecurityOrigin::urlWithUniqueSecurityOrigin(), nestedDocument()->firstPartyForCookies());
266 TEST_F(WebDocumentFirstPartyTest
, NestedOriginBInOriginA
)
268 load(nestedOriginBInOriginA
);
270 ASSERT_EQ(toOriginA(nestedOriginBInOriginA
), topDocument()->firstPartyForCookies());
271 ASSERT_EQ(toOriginA(nestedOriginBInOriginA
), nestedDocument()->firstPartyForCookies());
272 ASSERT_EQ(SecurityOrigin::urlWithUniqueSecurityOrigin(), nestedNestedDocument()->firstPartyForCookies());
275 TEST_F(WebDocumentFirstPartyTest
, NestedOriginBInOriginB
)
277 load(nestedOriginBInOriginB
);
279 ASSERT_EQ(toOriginA(nestedOriginBInOriginB
), topDocument()->firstPartyForCookies());
280 ASSERT_EQ(SecurityOrigin::urlWithUniqueSecurityOrigin(), nestedDocument()->firstPartyForCookies());
281 ASSERT_EQ(SecurityOrigin::urlWithUniqueSecurityOrigin(), nestedNestedDocument()->firstPartyForCookies());
284 TEST_F(WebDocumentFirstPartyTest
, NestedSrcdoc
)
288 ASSERT_EQ(toOriginA(nestedSrcDoc
), topDocument()->firstPartyForCookies());
289 ASSERT_EQ(toOriginA(nestedSrcDoc
), nestedDocument()->firstPartyForCookies());
292 TEST_F(WebDocumentFirstPartyTest
, NestedData
)
296 ASSERT_EQ(toOriginA(nestedData
), topDocument()->firstPartyForCookies());
297 ASSERT_EQ(SecurityOrigin::urlWithUniqueSecurityOrigin(), nestedDocument()->firstPartyForCookies());
300 TEST_F(WebDocumentFirstPartyTest
, NestedOriginAInOriginBWithFirstPartyOverride
)
302 load(nestedOriginAInOriginB
);
304 SchemeRegistry::registerURLSchemeAsFirstPartyWhenTopLevel("http");
306 ASSERT_EQ(toOriginA(nestedOriginAInOriginB
), topDocument()->firstPartyForCookies());
307 ASSERT_EQ(toOriginA(nestedOriginAInOriginB
), nestedDocument()->firstPartyForCookies());
308 ASSERT_EQ(toOriginA(nestedOriginAInOriginB
), nestedNestedDocument()->firstPartyForCookies());