blob: e2532af25e2f6f0eaf088c48456ca387900ab28d [file] [log] [blame]
skyostild34af142016-06-23 17:19:451// Copyright 2016 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 <memory>
6
altimin93a02402016-08-03 16:26:437#include "base/files/scoped_temp_dir.h"
skyostild34af142016-06-23 17:19:458#include "base/strings/stringprintf.h"
altimin93a02402016-08-03 16:26:439#include "base/threading/thread_restrictions.h"
esecklerd71fc502016-09-30 10:07:5910#include "content/public/browser/render_view_host.h"
11#include "content/public/browser/web_contents.h"
skyostild34af142016-06-23 17:19:4512#include "content/public/test/browser_test.h"
esecklerd71fc502016-09-30 10:07:5913#include "headless/lib/browser/headless_web_contents_impl.h"
skyostil6bac5f642017-05-04 11:40:3014#include "headless/public/devtools/domains/runtime.h"
skyostild34af142016-06-23 17:19:4515#include "headless/public/headless_browser.h"
16#include "headless/public/headless_browser_context.h"
17#include "headless/public/headless_devtools_client.h"
18#include "headless/public/headless_devtools_target.h"
19#include "headless/public/headless_web_contents.h"
20#include "headless/test/headless_browser_test.h"
skyostild34af142016-06-23 17:19:4521#include "testing/gtest/include/gtest/gtest.h"
22#include "ui/gfx/geometry/size.h"
23
24namespace headless {
25namespace {
26const char kMainPageCookie[] = "mood=quizzical";
27const char kIsolatedPageCookie[] = "mood=quixotic";
28} // namespace
29
30// This test creates two tabs pointing to the same security origin in two
31// different browser contexts and checks that they are isolated by creating two
32// cookies with the same name in both tabs. The steps are:
33//
34// 1. Wait for tab #1 to become ready for DevTools.
35// 2. Create tab #2 and wait for it to become ready for DevTools.
36// 3. Navigate tab #1 to the test page and wait for it to finish loading.
37// 4. Navigate tab #2 to the test page and wait for it to finish loading.
38// 5. Set a cookie in tab #1.
39// 6. Set the same cookie in tab #2 to a different value.
40// 7. Read the cookie in tab #1 and check that it has the first value.
41// 8. Read the cookie in tab #2 and check that it has the second value.
42//
43// If the tabs aren't properly isolated, step 7 will fail.
44class HeadlessBrowserContextIsolationTest
45 : public HeadlessAsyncDevTooledBrowserTest {
46 public:
47 HeadlessBrowserContextIsolationTest()
Eric Seckler4948f932018-08-28 14:51:2248 : browser_context_(nullptr), web_contents2_(nullptr) {
skyostild34af142016-06-23 17:19:4549 EXPECT_TRUE(embedded_test_server()->Start());
50 }
51
52 // HeadlessWebContentsObserver implementation:
53 void DevToolsTargetReady() override {
54 if (!web_contents2_) {
55 browser_context_ = browser()->CreateBrowserContextBuilder().Build();
altimin93a02402016-08-03 16:26:4356 web_contents2_ = browser_context_->CreateWebContentsBuilder().Build();
skyostild34af142016-06-23 17:19:4557 web_contents2_->AddObserver(this);
58 return;
59 }
60
Eric Seckler4948f932018-08-28 14:51:2261 devtools_client2_ = HeadlessDevToolsClient::Create();
skyostild34af142016-06-23 17:19:4562 web_contents2_->GetDevToolsTarget()->AttachClient(devtools_client2_.get());
63 HeadlessAsyncDevTooledBrowserTest::DevToolsTargetReady();
64 }
65
66 void RunDevTooledTest() override {
67 load_observer_.reset(new LoadObserver(
68 devtools_client_.get(),
69 base::Bind(&HeadlessBrowserContextIsolationTest::OnFirstLoadComplete,
70 base::Unretained(this))));
71 devtools_client_->GetPage()->Navigate(
72 embedded_test_server()->GetURL("/hello.html").spec());
73 }
74
75 void OnFirstLoadComplete() {
76 EXPECT_TRUE(load_observer_->navigation_succeeded());
77 load_observer_.reset(new LoadObserver(
78 devtools_client2_.get(),
79 base::Bind(&HeadlessBrowserContextIsolationTest::OnSecondLoadComplete,
80 base::Unretained(this))));
81 devtools_client2_->GetPage()->Navigate(
82 embedded_test_server()->GetURL("/hello.html").spec());
83 }
84
85 void OnSecondLoadComplete() {
86 EXPECT_TRUE(load_observer_->navigation_succeeded());
87 load_observer_.reset();
88
89 devtools_client_->GetRuntime()->Evaluate(
90 base::StringPrintf("document.cookie = '%s'", kMainPageCookie),
tzikf7adad1a2018-03-10 20:31:0191 base::BindOnce(
92 &HeadlessBrowserContextIsolationTest::OnFirstSetCookieResult,
93 base::Unretained(this)));
skyostild34af142016-06-23 17:19:4594 }
95
96 void OnFirstSetCookieResult(std::unique_ptr<runtime::EvaluateResult> result) {
Alex Clarke1dbb6092017-10-18 16:53:3497 EXPECT_EQ(kMainPageCookie, result->GetResult()->GetValue()->GetString());
skyostild34af142016-06-23 17:19:4598
99 devtools_client2_->GetRuntime()->Evaluate(
100 base::StringPrintf("document.cookie = '%s'", kIsolatedPageCookie),
tzikf7adad1a2018-03-10 20:31:01101 base::BindOnce(
skyostild34af142016-06-23 17:19:45102 &HeadlessBrowserContextIsolationTest::OnSecondSetCookieResult,
103 base::Unretained(this)));
104 }
105
106 void OnSecondSetCookieResult(
107 std::unique_ptr<runtime::EvaluateResult> result) {
Alex Clarke1dbb6092017-10-18 16:53:34108 EXPECT_EQ(kIsolatedPageCookie,
109 result->GetResult()->GetValue()->GetString());
skyostild34af142016-06-23 17:19:45110
111 devtools_client_->GetRuntime()->Evaluate(
112 "document.cookie",
tzikf7adad1a2018-03-10 20:31:01113 base::BindOnce(
114 &HeadlessBrowserContextIsolationTest::OnFirstGetCookieResult,
115 base::Unretained(this)));
skyostild34af142016-06-23 17:19:45116 }
117
118 void OnFirstGetCookieResult(std::unique_ptr<runtime::EvaluateResult> result) {
Alex Clarke1dbb6092017-10-18 16:53:34119 EXPECT_EQ(kMainPageCookie, result->GetResult()->GetValue()->GetString());
skyostild34af142016-06-23 17:19:45120
121 devtools_client2_->GetRuntime()->Evaluate(
122 "document.cookie",
tzikf7adad1a2018-03-10 20:31:01123 base::BindOnce(
skyostild34af142016-06-23 17:19:45124 &HeadlessBrowserContextIsolationTest::OnSecondGetCookieResult,
125 base::Unretained(this)));
126 }
127
128 void OnSecondGetCookieResult(
129 std::unique_ptr<runtime::EvaluateResult> result) {
Alex Clarke1dbb6092017-10-18 16:53:34130 EXPECT_EQ(kIsolatedPageCookie,
131 result->GetResult()->GetValue()->GetString());
skyostild34af142016-06-23 17:19:45132 FinishTest();
133 }
134
135 void FinishTest() {
136 web_contents2_->RemoveObserver(this);
137 web_contents2_->Close();
altiminbf875c92016-08-04 17:09:07138 browser_context_->Close();
skyostild34af142016-06-23 17:19:45139 FinishAsynchronousTest();
140 }
141
142 private:
altiminbf875c92016-08-04 17:09:07143 HeadlessBrowserContext* browser_context_;
skyostild34af142016-06-23 17:19:45144 HeadlessWebContents* web_contents2_;
145 std::unique_ptr<HeadlessDevToolsClient> devtools_client2_;
146 std::unique_ptr<LoadObserver> load_observer_;
147};
148
149HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessBrowserContextIsolationTest);
150
altimin93a02402016-08-03 16:26:43151IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, UserDataDir) {
152 // We do not want to bother with posting tasks to create a temp dir.
153 // Just allow IO from main thread for now.
154 base::ThreadRestrictions::SetIOAllowed(true);
155
156 EXPECT_TRUE(embedded_test_server()->Start());
157
158 base::ScopedTempDir user_data_dir;
159 ASSERT_TRUE(user_data_dir.CreateUniqueTempDir());
160
161 // Newly created temp directory should be empty.
vabr16e5f602016-09-15 18:14:00162 EXPECT_TRUE(base::IsDirectoryEmpty(user_data_dir.GetPath()));
altimin93a02402016-08-03 16:26:43163
altiminbf875c92016-08-04 17:09:07164 HeadlessBrowserContext* browser_context =
altimin93a02402016-08-03 16:26:43165 browser()
166 ->CreateBrowserContextBuilder()
vabr16e5f602016-09-15 18:14:00167 .SetUserDataDir(user_data_dir.GetPath())
altimin1ab631012016-08-04 18:43:45168 .SetIncognitoMode(false)
altimin93a02402016-08-03 16:26:43169 .Build();
170
171 HeadlessWebContents* web_contents =
172 browser_context->CreateWebContentsBuilder()
173 .SetInitialURL(embedded_test_server()->GetURL("/hello.html"))
174 .Build();
175
176 EXPECT_TRUE(WaitForLoad(web_contents));
177
178 // Something should be written to this directory.
179 // If it is not the case, more complex page may be needed.
180 // ServiceWorkers may be a good option.
vabr16e5f602016-09-15 18:14:00181 EXPECT_FALSE(base::IsDirectoryEmpty(user_data_dir.GetPath()));
altimin93a02402016-08-03 16:26:43182}
183
altimin1ab631012016-08-04 18:43:45184IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, IncognitoMode) {
185 // We do not want to bother with posting tasks to create a temp dir.
186 // Just allow IO from main thread for now.
187 base::ThreadRestrictions::SetIOAllowed(true);
188
189 EXPECT_TRUE(embedded_test_server()->Start());
190
191 base::ScopedTempDir user_data_dir;
192 ASSERT_TRUE(user_data_dir.CreateUniqueTempDir());
193
194 // Newly created temp directory should be empty.
vabr16e5f602016-09-15 18:14:00195 EXPECT_TRUE(base::IsDirectoryEmpty(user_data_dir.GetPath()));
altimin1ab631012016-08-04 18:43:45196
197 HeadlessBrowserContext* browser_context =
198 browser()
199 ->CreateBrowserContextBuilder()
vabr16e5f602016-09-15 18:14:00200 .SetUserDataDir(user_data_dir.GetPath())
altimin1ab631012016-08-04 18:43:45201 .SetIncognitoMode(true)
202 .Build();
203
204 HeadlessWebContents* web_contents =
205 browser_context->CreateWebContentsBuilder()
206 .SetInitialURL(embedded_test_server()->GetURL("/hello.html"))
207 .Build();
208
209 EXPECT_TRUE(WaitForLoad(web_contents));
210
211 // Similar to test above, but now we are in incognito mode,
212 // so nothing should be written to this directory.
vabr16e5f602016-09-15 18:14:00213 EXPECT_TRUE(base::IsDirectoryEmpty(user_data_dir.GetPath()));
altimin1ab631012016-08-04 18:43:45214}
215
esecklerd71fc502016-09-30 10:07:59216IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, ContextWebPreferences) {
217 // By default, hide_scrollbars should be false.
218 EXPECT_FALSE(WebPreferences().hide_scrollbars);
219
220 // Set hide_scrollbars preference to true for a new BrowserContext.
221 HeadlessBrowserContext* browser_context =
222 browser()
223 ->CreateBrowserContextBuilder()
224 .SetOverrideWebPreferencesCallback(
Eric Secklerc27d203bae2017-09-27 11:44:57225 base::Bind([](WebPreferences* preferences) {
esecklerd71fc502016-09-30 10:07:59226 preferences->hide_scrollbars = true;
227 }))
228 .Build();
229 HeadlessWebContents* web_contents =
230 browser_context->CreateWebContentsBuilder()
231 .SetInitialURL(GURL("about:blank"))
232 .Build();
233
234 // Verify that the preference takes effect.
235 HeadlessWebContentsImpl* contents_impl =
236 HeadlessWebContentsImpl::From(web_contents);
237 EXPECT_TRUE(contents_impl->web_contents()
238 ->GetRenderViewHost()
239 ->GetWebkitPreferences().hide_scrollbars);
240}
241
skyostild34af142016-06-23 17:19:45242} // namespace headless