Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: chrome/browser/extensions/web_view_browsertest.cc

Issue 11234032: Webview tag creation should be using storage partitions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixes in the test. Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/utf_string_conversions.h"
5 #include "chrome/browser/automation/automation_util.h" 6 #include "chrome/browser/automation/automation_util.h"
6 #include "chrome/browser/extensions/platform_app_browsertest_util.h" 7 #include "chrome/browser/extensions/platform_app_browsertest_util.h"
7 #include "chrome/browser/ui/browser_tabstrip.h" 8 #include "chrome/browser/ui/browser_tabstrip.h"
8 #include "chrome/common/chrome_switches.h" 9 #include "chrome/common/chrome_switches.h"
9 #include "chrome/test/base/ui_test_utils.h" 10 #include "chrome/test/base/ui_test_utils.h"
10 #include "chrome/test/base/test_launcher_utils.h" 11 #include "chrome/test/base/test_launcher_utils.h"
11 #include "content/public/browser/notification_service.h" 12 #include "content/public/browser/notification_service.h"
12 #include "content/public/browser/render_process_host.h" 13 #include "content/public/browser/render_process_host.h"
13 #include "content/public/test/browser_test_utils.h" 14 #include "content/public/test/browser_test_utils.h"
14 #include "ui/compositor/compositor_setup.h" 15 #include "ui/compositor/compositor_setup.h"
15 #include "ui/gl/gl_switches.h" 16 #include "ui/gl/gl_switches.h"
16 17
17 class WebViewTest : public extensions::PlatformAppBrowserTest { 18 class WebViewTest : public extensions::PlatformAppBrowserTest {
18 protected: 19 protected:
19 virtual void SetUpCommandLine(CommandLine* command_line) { 20 virtual void SetUpCommandLine(CommandLine* command_line) {
20 extensions::PlatformAppBrowserTest::SetUpCommandLine(command_line); 21 extensions::PlatformAppBrowserTest::SetUpCommandLine(command_line);
21 // Enable <webview> for running test. 22 // Enable <webview> for running test.
22 command_line->AppendSwitch(switches::kEnableWebView); 23 command_line->AppendSwitch(switches::kEnableWebView);
23 #if !defined(OS_MACOSX) 24 #if !defined(OS_MACOSX)
24 CHECK(test_launcher_utils::OverrideGLImplementation( 25 CHECK(test_launcher_utils::OverrideGLImplementation(
25 command_line, gfx::kGLImplementationOSMesaName)) << 26 command_line, gfx::kGLImplementationOSMesaName)) <<
26 "kUseGL must not be set by test framework code!"; 27 "kUseGL must not be set by test framework code!";
27 #endif 28 #endif
28 ui::DisableTestCompositor(); 29 ui::DisableTestCompositor();
29 } 30 }
31
32 // This method is responsible for initializing a packaged app, which contains
33 // multiple webview tags. The tags have different partition identifiers and
34 // their WebContent objects are returned as output. The method also verifies
35 // the expected process allocation and storage partition assignment.
36 // The |navigate_to_url| paramter is used to navigate the main browser window.
37 void NavigateAndOpenAppForIsolation(
38 GURL navigate_to_url,
39 content::WebContents** contents1,
40 content::WebContents** contents2,
41 content::WebContents** storage_contents1,
42 content::WebContents** storage_contents2) {
43 GURL::Replacements replace_host;
44 std::string host_str("localhost"); // Must stay in scope with replace_host.
45 replace_host.SetHostStr(host_str);
46
47 navigate_to_url = navigate_to_url.ReplaceComponents(replace_host);
48
49 GURL tag_url1 = test_server()->GetURL(
50 "files/extensions/platform_apps/web_view_isolation/cookie.html");
51 tag_url1 = tag_url1.ReplaceComponents(replace_host);
52 GURL tag_url2 = test_server()->GetURL(
53 "files/extensions/platform_apps/web_view_isolation/cookie2.html");
54 tag_url2 = tag_url2.ReplaceComponents(replace_host);
55 GURL tag_url3 = test_server()->GetURL(
56 "files/extensions/platform_apps/web_view_isolation/storage1.html");
57 tag_url3 = tag_url3.ReplaceComponents(replace_host);
58 GURL tag_url4 = test_server()->GetURL(
59 "files/extensions/platform_apps/web_view_isolation/storage2.html");
60 tag_url4 = tag_url4.ReplaceComponents(replace_host);
61
62 ui_test_utils::NavigateToURLWithDisposition(
63 browser(), navigate_to_url, CURRENT_TAB,
64 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
65
66 ui_test_utils::UrlLoadObserver observer1(
67 tag_url1, content::NotificationService::AllSources());
68 ui_test_utils::UrlLoadObserver observer2(
69 tag_url2, content::NotificationService::AllSources());
70 ui_test_utils::UrlLoadObserver observer3(
71 tag_url3, content::NotificationService::AllSources());
72 ui_test_utils::UrlLoadObserver observer4(
73 tag_url4, content::NotificationService::AllSources());
74 LoadAndLaunchPlatformApp("web_view_isolation");
75 observer1.Wait();
76 observer2.Wait();
77 observer3.Wait();
78 observer4.Wait();
79
80 content::Source<content::NavigationController> source1 = observer1.source();
81 EXPECT_TRUE(source1->GetWebContents()->GetRenderProcessHost()->IsGuest());
82 content::Source<content::NavigationController> source2 = observer2.source();
83 EXPECT_TRUE(source2->GetWebContents()->GetRenderProcessHost()->IsGuest());
84 content::Source<content::NavigationController> source3 = observer3.source();
85 EXPECT_TRUE(source3->GetWebContents()->GetRenderProcessHost()->IsGuest());
86 content::Source<content::NavigationController> source4 = observer4.source();
87 EXPECT_TRUE(source4->GetWebContents()->GetRenderProcessHost()->IsGuest());
88
89 // Tags with the same storage partition are not yet combined in the same
90 // process. Check this until http://crbug.com/138296 is fixed.
91 EXPECT_NE(source1->GetWebContents()->GetRenderProcessHost()->GetID(),
92 source2->GetWebContents()->GetRenderProcessHost()->GetID());
93
94 // Check that the storage partitions of the first two tags match and are
95 // different than the other two.
96 EXPECT_EQ(
97 source1->GetWebContents()->GetRenderProcessHost()->
98 GetStoragePartition(),
99 source2->GetWebContents()->GetRenderProcessHost()->
100 GetStoragePartition());
101 EXPECT_EQ(
102 source3->GetWebContents()->GetRenderProcessHost()->
103 GetStoragePartition(),
104 source4->GetWebContents()->GetRenderProcessHost()->
105 GetStoragePartition());
106 EXPECT_NE(
107 source1->GetWebContents()->GetRenderProcessHost()->
108 GetStoragePartition(),
109 source3->GetWebContents()->GetRenderProcessHost()->
110 GetStoragePartition());
111
112 *contents1 = source1->GetWebContents();
113 *contents2 = source2->GetWebContents();
114 *storage_contents1 = source3->GetWebContents();
115 *storage_contents2 = source4->GetWebContents();
116 }
117
118 void ExecuteScriptWaitForTitle(content::WebContents* web_contents,
119 const char* script,
120 const char* title) {
121 std::wstring js_script = ASCIIToWide(script);
122 string16 expected_title(ASCIIToUTF16(title));
123 string16 error_title(ASCIIToUTF16("error"));
124
125 content::TitleWatcher title_watcher(web_contents, expected_title);
126 title_watcher.AlsoWaitForTitle(error_title);
127 EXPECT_TRUE(content::ExecuteJavaScript(web_contents->GetRenderViewHost(),
128 std::wstring(), js_script));
129 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
130 }
30 }; 131 };
31 132
32 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim) { 133 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim) {
33 ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view")) << message_; 134 ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view")) << message_;
34 } 135 }
35 136
36 IN_PROC_BROWSER_TEST_F(WebViewTest, ShimSrcAttribute) { 137 IN_PROC_BROWSER_TEST_F(WebViewTest, ShimSrcAttribute) {
37 ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view_src_attribute")) 138 ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view_src_attribute"))
38 << message_; 139 << message_;
39 } 140 }
40 141
41 IN_PROC_BROWSER_TEST_F(WebViewTest, Isolation) { 142 // This test cookie isolation for packaged apps with webview tags. It navigates
143 // the main browser window to a page that sets a cookie and loads an app with
144 // multiple webview tags. Each tag sets a cookie and the test checks the proper
145 // storage isolation is enforced.
146 IN_PROC_BROWSER_TEST_F(WebViewTest, CookieIsolation) {
42 ASSERT_TRUE(StartTestServer()); 147 ASSERT_TRUE(StartTestServer());
43 const std::wstring kExpire = 148 const std::wstring kExpire =
44 L"var expire = new Date(Date.now() + 24 * 60 * 60 * 1000);"; 149 L"var expire = new Date(Date.now() + 24 * 60 * 60 * 1000);";
45 std::wstring cookie_script1(kExpire); 150 std::wstring cookie_script1(kExpire);
46 cookie_script1.append( 151 cookie_script1.append(
47 L"document.cookie = 'guest1=true; path=/; expires=' + expire + ';';"); 152 L"document.cookie = 'guest1=true; path=/; expires=' + expire + ';';");
48 std::wstring cookie_script2(kExpire); 153 std::wstring cookie_script2(kExpire);
49 cookie_script2.append( 154 cookie_script2.append(
50 L"document.cookie = 'guest2=true; path=/; expires=' + expire + ';';"); 155 L"document.cookie = 'guest2=true; path=/; expires=' + expire + ';';");
51 156
52 GURL::Replacements replace_host; 157 GURL::Replacements replace_host;
53 std::string host_str("localhost"); // Must stay in scope with replace_host. 158 std::string host_str("localhost"); // Must stay in scope with replace_host.
54 replace_host.SetHostStr(host_str); 159 replace_host.SetHostStr(host_str);
55 160
56 GURL set_cookie_url = test_server()->GetURL( 161 GURL set_cookie_url = test_server()->GetURL(
57 "files/extensions/platform_apps/isolation/set_cookie.html"); 162 "files/extensions/platform_apps/isolation/set_cookie.html");
58 set_cookie_url = set_cookie_url.ReplaceComponents(replace_host); 163 set_cookie_url = set_cookie_url.ReplaceComponents(replace_host);
59 GURL tag_url1 = test_server()->GetURL(
60 "files/extensions/platform_apps/web_view_isolation/cookie.html");
61 tag_url1 = tag_url1.ReplaceComponents(replace_host);
62 GURL tag_url2 = test_server()->GetURL(
63 "files/extensions/platform_apps/web_view_isolation/cookie2.html");
64 tag_url2 = tag_url2.ReplaceComponents(replace_host);
65 164
66 // Load a (non-app) page under the "localhost" origin that sets a cookie. 165 content::WebContents* contents1;
67 ui_test_utils::NavigateToURLWithDisposition( 166 content::WebContents* contents2;
68 browser(), set_cookie_url, 167 content::WebContents* contents3;
69 CURRENT_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 168 content::WebContents* contents4;
70 // Make sure the cookie is set. 169
170 NavigateAndOpenAppForIsolation(set_cookie_url, &contents1, &contents2,
171 &contents3, &contents4);
172
173 EXPECT_TRUE(content::ExecuteJavaScript(
174 contents1->GetRenderViewHost(), std::wstring(), cookie_script1));
175 EXPECT_TRUE(content::ExecuteJavaScript(
176 contents2->GetRenderViewHost(), std::wstring(), cookie_script2));
177
71 int cookie_size; 178 int cookie_size;
72 std::string cookie_value; 179 std::string cookie_value;
73 automation_util::GetCookies(set_cookie_url,
74 chrome::GetWebContentsAt(browser(), 0),
75 &cookie_size, &cookie_value);
76 EXPECT_EQ("testCookie=1", cookie_value);
77 180
78 ui_test_utils::UrlLoadObserver observer1( 181 // Test the regular browser context to ensure we have only one cookie.
79 tag_url1, content::NotificationService::AllSources());
80 ui_test_utils::UrlLoadObserver observer2(
81 tag_url2, content::NotificationService::AllSources());
82 LoadAndLaunchPlatformApp("web_view_isolation");
83 observer1.Wait();
84 observer2.Wait();
85
86 content::Source<content::NavigationController> source1 = observer1.source();
87 EXPECT_TRUE(source1->GetWebContents()->GetRenderProcessHost()->IsGuest());
88 content::Source<content::NavigationController> source2 = observer2.source();
89 EXPECT_TRUE(source2->GetWebContents()->GetRenderProcessHost()->IsGuest());
90 EXPECT_NE(source1->GetWebContents()->GetRenderProcessHost()->GetID(),
91 source2->GetWebContents()->GetRenderProcessHost()->GetID());
92
93 EXPECT_TRUE(content::ExecuteJavaScript(
94 source1->GetWebContents()->GetRenderViewHost(), std::wstring(),
95 cookie_script1));
96 EXPECT_TRUE(content::ExecuteJavaScript(
97 source2->GetWebContents()->GetRenderViewHost(), std::wstring(),
98 cookie_script2));
99
100 // Test the regular browser context to ensure we still have only one cookie.
101 automation_util::GetCookies(GURL("http://localhost"), 182 automation_util::GetCookies(GURL("http://localhost"),
102 chrome::GetWebContentsAt(browser(), 0), 183 chrome::GetWebContentsAt(browser(), 0),
103 &cookie_size, &cookie_value); 184 &cookie_size, &cookie_value);
104 EXPECT_EQ("testCookie=1", cookie_value); 185 EXPECT_EQ("testCookie=1", cookie_value);
105 186
106 // The default behavior is to combine webview tags with no explicit partition 187 // The default behavior is to combine webview tags with no explicit partition
107 // declaration into the same in-memory partition. Test the webview tags to 188 // declaration into the same in-memory partition. Test the webview tags to
108 // ensure we have properly set the cookies and we have both cookies in both 189 // ensure we have properly set the cookies and we have both cookies in both
109 // tags. 190 // tags.
110 automation_util::GetCookies(GURL("http://localhost"), 191 automation_util::GetCookies(GURL("http://localhost"),
111 source1->GetWebContents(), 192 contents1,
112 &cookie_size, &cookie_value); 193 &cookie_size, &cookie_value);
113 EXPECT_EQ("guest1=true; guest2=true", cookie_value); 194 EXPECT_EQ("guest1=true; guest2=true", cookie_value);
114 195
115 automation_util::GetCookies(GURL("http://localhost"), 196 automation_util::GetCookies(GURL("http://localhost"),
116 source2->GetWebContents(), 197 contents2,
117 &cookie_size, &cookie_value); 198 &cookie_size, &cookie_value);
118 EXPECT_EQ("guest1=true; guest2=true", cookie_value); 199 EXPECT_EQ("guest1=true; guest2=true", cookie_value);
200
201 // The third tag should not have any cookies as it is in separate partition.
202 automation_util::GetCookies(GURL("http://localhost"),
203 contents3,
204 &cookie_size, &cookie_value);
205 EXPECT_EQ("", cookie_value);
119 } 206 }
207
208 // This test DOM storage isolation for packaged apps with webview tags. It loads
awong 2012/11/05 18:00:33 This test -> This tests
nasko 2012/11/05 18:09:06 Done.
209 // an app with multiple webview tags and each tag sets DOM storage entries,
210 // which the test checks to ensure proper storage isolation is enforced.
211 IN_PROC_BROWSER_TEST_F(WebViewTest, DOMStorageIsolation) {
212 ASSERT_TRUE(StartTestServer());
213 GURL regular_url = test_server()->GetURL("files/title1.html");
214
215 std::string output;
216 std::wstring get_local_storage(L"window.domAutomationController.send("
217 L"window.localStorage.getItem('foo') || 'badval')");
218 std::wstring get_session_storage(L"window.domAutomationController.send("
219 L"window.sessionStorage.getItem('foo') || 'badval')");
220
221 content::WebContents* contents1;
222 content::WebContents* contents2;
223 content::WebContents* storage_contents1;
224 content::WebContents* storage_contents2;
225
226 NavigateAndOpenAppForIsolation(regular_url, &contents1, &contents2,
227 &storage_contents1, &storage_contents2);
228
229 // Initialize the storage for the first of the two tags that share a storage
230 // partition.
231 EXPECT_TRUE(content::ExecuteJavaScript(
232 storage_contents1->GetRenderViewHost(), std::wstring(),
233 L"initDomStorage('page1')"));
234
235 // Let's test the expected values are present in the first tag, as they will
awong 2012/11/05 18:00:33 test the -> test that the
nasko 2012/11/05 18:09:06 Done.
236 // be overwritten once we call the initDomStorage on the second tag.
237 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
238 storage_contents1->GetRenderViewHost(), std::wstring(),
239 get_local_storage.c_str(), &output));
240 EXPECT_STREQ("local-page1", output.c_str());
241 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
242 storage_contents1->GetRenderViewHost(), std::wstring(),
243 get_session_storage.c_str(), &output));
244 EXPECT_STREQ("session-page1", output.c_str());
245
246 // Now, init the storage in the second tag in the same storage partition,
247 // which will overwrite the shared localStorage.
248 EXPECT_TRUE(content::ExecuteJavaScript(
249 storage_contents2->GetRenderViewHost(), std::wstring(),
250 L"initDomStorage('page2')"));
251
252 // The localStorage value now should reflect the one written through the
253 // second tag.
254 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
255 storage_contents1->GetRenderViewHost(), std::wstring(),
256 get_local_storage.c_str(), &output));
257 EXPECT_STREQ("local-page2", output.c_str());
258 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
259 storage_contents2->GetRenderViewHost(), std::wstring(),
260 get_local_storage.c_str(), &output));
261 EXPECT_STREQ("local-page2", output.c_str());
262
263 // Session storage is not shared though, as each webview tag has separate
264 // instance, even if they are in the same storage partition.
265 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
266 storage_contents1->GetRenderViewHost(), std::wstring(),
267 get_session_storage.c_str(), &output));
268 EXPECT_STREQ("session-page1", output.c_str());
269 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
270 storage_contents2->GetRenderViewHost(), std::wstring(),
271 get_session_storage.c_str(), &output));
272 EXPECT_STREQ("session-page2", output.c_str());
273
274 // Also, let's check that the main browser and another tag that doesn't share
275 // the same partition don't have those values stored.
276 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
277 chrome::GetWebContentsAt(browser(), 0)->GetRenderViewHost(),
278 std::wstring(), get_local_storage.c_str(), &output));
279 EXPECT_STREQ("badval", output.c_str());
280 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
281 chrome::GetWebContentsAt(browser(), 0)->GetRenderViewHost(),
282 std::wstring(), get_session_storage.c_str(), &output));
283 EXPECT_STREQ("badval", output.c_str());
284 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
285 contents1->GetRenderViewHost(), std::wstring(),
286 get_local_storage.c_str(), &output));
287 EXPECT_STREQ("badval", output.c_str());
288 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
289 contents1->GetRenderViewHost(), std::wstring(),
290 get_session_storage.c_str(), &output));
291 EXPECT_STREQ("badval", output.c_str());
292 }
293
294 // This test IndexedDB isolation for packaged apps with webview tags. It loads
295 // an app with multiple webview tags and each tag creates IndexedDB record,
awong 2012/11/05 18:00:33 creates -> creates an
nasko 2012/11/05 18:09:06 Done.
296 // which the test checks to ensure proper storage isolation is enforced.
297 IN_PROC_BROWSER_TEST_F(WebViewTest, IndexedDBIsolation) {
298 ASSERT_TRUE(StartTestServer());
299 GURL regular_url = test_server()->GetURL("files/title1.html");
300
301 content::WebContents* contents1;
302 content::WebContents* contents2;
303 content::WebContents* storage_contents1;
304 content::WebContents* storage_contents2;
305
306 NavigateAndOpenAppForIsolation(regular_url, &contents1, &contents2,
307 &storage_contents1, &storage_contents2);
308
309 // Initialize the storage for the first of the two tags that share a storage
310 // partition.
311 ExecuteScriptWaitForTitle(storage_contents1, "initIDB()", "idb created");
312 ExecuteScriptWaitForTitle(storage_contents1, "addItemIDB(7, 'page1')",
313 "addItemIDB complete");
314 ExecuteScriptWaitForTitle(storage_contents1, "readItemIDB(7)",
315 "readItemIDB complete");
316
317 std::string output;
318 std::wstring get_value(
319 L"window.domAutomationController.send(getValueIDB() || 'badval')");
320
321 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
322 storage_contents1->GetRenderViewHost(), std::wstring(),
323 get_value.c_str(), &output));
324 EXPECT_STREQ("page1", output.c_str());
325
326 // Initialize the db in the second tag.
327 ExecuteScriptWaitForTitle(storage_contents2, "initIDB()", "idb open");
328
329 // Since we share a partition, reading the value should return the existing
330 // one.
331 ExecuteScriptWaitForTitle(storage_contents2, "readItemIDB(7)",
332 "readItemIDB complete");
333 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
334 storage_contents2->GetRenderViewHost(), std::wstring(),
335 get_value.c_str(), &output));
336 EXPECT_STREQ("page1", output.c_str());
337
338 // Now write through the second tag and read it back.
339 ExecuteScriptWaitForTitle(storage_contents2, "addItemIDB(7, 'page2')",
340 "addItemIDB complete");
341 ExecuteScriptWaitForTitle(storage_contents2, "readItemIDB(7)",
342 "readItemIDB complete");
343 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
344 storage_contents2->GetRenderViewHost(), std::wstring(),
345 get_value.c_str(), &output));
346 EXPECT_STREQ("page2", output.c_str());
347
348 // Reset the document title, otherwise the next call will not see a change and
349 // will hang waiting for it.
350 EXPECT_TRUE(content::ExecuteJavaScript(
351 storage_contents1->GetRenderViewHost(), std::wstring(),
352 L"document.title = 'foo'"));
353
354 // Read through the first tag to ensure we have the second value.
355 ExecuteScriptWaitForTitle(storage_contents1, "readItemIDB(7)",
356 "readItemIDB complete");
357 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
358 storage_contents1->GetRenderViewHost(), std::wstring(),
359 get_value.c_str(), &output));
360 EXPECT_STREQ("page2", output.c_str());
361
362 // Now, let's confirm there is no database in the main browser and another
363 // tag that doesn't share the same partition. Due to the IndexedDB API design,
364 // open will succeed, but the version will be 1, since it creates the database
365 // if it is not found. The two tags use database version 3, so we avoid
366 // ambiguity.
367 const char* script =
368 "indexedDB.open('isolation').onsuccess = function(e) {"
369 " if (e.target.result.version == 1)"
370 " document.title = 'db not found';"
371 " else "
372 " document.title = 'error';"
373 "}";
374 ExecuteScriptWaitForTitle(chrome::GetWebContentsAt(browser(), 0),
375 script, "db not found");
376 ExecuteScriptWaitForTitle(contents1, script, "db not found");
377 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698