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

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: Added IndexedDB 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 void NavigateAndOpenAppForIsolation(
awong 2012/11/02 21:56:13 FYI, if you do this kind of pattern in the future,
nasko 2012/11/05 17:37:11 Yes, you've pointed it out in the past. The main g
33 GURL navigate_to_url,
34 content::WebContents** contents1,
35 content::WebContents** contents2,
36 content::WebContents** storage_contents1,
37 content::WebContents** storage_contents2) {
awong 2012/11/02 21:56:13 Function needs top level comment.
nasko 2012/11/05 17:37:11 Done.
38 GURL::Replacements replace_host;
39 std::string host_str("localhost"); // Must stay in scope with replace_host.
40 replace_host.SetHostStr(host_str);
41
42 navigate_to_url = navigate_to_url.ReplaceComponents(replace_host);
43
44 GURL tag_url1 = test_server()->GetURL(
45 "files/extensions/platform_apps/web_view_isolation/cookie.html");
46 tag_url1 = tag_url1.ReplaceComponents(replace_host);
47 GURL tag_url2 = test_server()->GetURL(
48 "files/extensions/platform_apps/web_view_isolation/cookie2.html");
49 tag_url2 = tag_url2.ReplaceComponents(replace_host);
50 GURL tag_url3 = test_server()->GetURL(
51 "files/extensions/platform_apps/web_view_isolation/storage1.html");
52 tag_url3 = tag_url3.ReplaceComponents(replace_host);
53 GURL tag_url4 = test_server()->GetURL(
54 "files/extensions/platform_apps/web_view_isolation/storage2.html");
55 tag_url4 = tag_url4.ReplaceComponents(replace_host);
56
57 ui_test_utils::NavigateToURLWithDisposition(
58 browser(), navigate_to_url, CURRENT_TAB,
59 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
60
61 ui_test_utils::UrlLoadObserver observer1(
62 tag_url1, content::NotificationService::AllSources());
63 ui_test_utils::UrlLoadObserver observer2(
64 tag_url2, content::NotificationService::AllSources());
65 ui_test_utils::UrlLoadObserver observer3(
66 tag_url3, content::NotificationService::AllSources());
67 ui_test_utils::UrlLoadObserver observer4(
68 tag_url4, content::NotificationService::AllSources());
69 LoadAndLaunchPlatformApp("web_view_isolation");
70 observer1.Wait();
71 observer2.Wait();
72 observer3.Wait();
73 observer4.Wait();
74
75 content::Source<content::NavigationController> source1 = observer1.source();
76 EXPECT_TRUE(source1->GetWebContents()->GetRenderProcessHost()->IsGuest());
77 content::Source<content::NavigationController> source2 = observer2.source();
78 EXPECT_TRUE(source2->GetWebContents()->GetRenderProcessHost()->IsGuest());
79 content::Source<content::NavigationController> source3 = observer3.source();
80 EXPECT_TRUE(source3->GetWebContents()->GetRenderProcessHost()->IsGuest());
81 content::Source<content::NavigationController> source4 = observer4.source();
82 EXPECT_TRUE(source4->GetWebContents()->GetRenderProcessHost()->IsGuest());
83
84 // Tags with the same storage partition are not yet combined in the same
85 // process. Check this until http://crbug.com/138296 is fixed.
86 EXPECT_NE(source1->GetWebContents()->GetRenderProcessHost()->GetID(),
87 source2->GetWebContents()->GetRenderProcessHost()->GetID());
88
89 // Check that the storage partitions of the first two tags match and are
90 // different than the other two.
91 EXPECT_EQ(
92 source1->GetWebContents()->GetRenderProcessHost()->
93 GetStoragePartition(),
94 source2->GetWebContents()->GetRenderProcessHost()->
95 GetStoragePartition());
96 EXPECT_EQ(
97 source3->GetWebContents()->GetRenderProcessHost()->
98 GetStoragePartition(),
99 source4->GetWebContents()->GetRenderProcessHost()->
100 GetStoragePartition());
101 EXPECT_NE(
102 source1->GetWebContents()->GetRenderProcessHost()->
103 GetStoragePartition(),
104 source3->GetWebContents()->GetRenderProcessHost()->
105 GetStoragePartition());
106
awong 2012/11/02 21:56:13 one newline is enough
nasko 2012/11/03 00:36:24 Done.
107
108 *contents1 = source1->GetWebContents();
109 *contents2 = source2->GetWebContents();
110 *storage_contents1 = source3->GetWebContents();
111 *storage_contents2 = source4->GetWebContents();
112 }
113
114 void ExecuteScriptWaitForTitle(content::WebContents* web_contents,
115 const char* script,
116 const char* title) {
117 std::wstring js_script(L"window.domAutomationController.send(" +
118 ASCIIToWide(script) + L")");
119 string16 expected_title(ASCIIToUTF16(title));
120 string16 error_title(ASCIIToUTF16("error"));
121 content::TitleWatcher title_watcher(web_contents, expected_title);
122 title_watcher.AlsoWaitForTitle(error_title);
123 EXPECT_TRUE(content::ExecuteJavaScript(web_contents->GetRenderViewHost(),
awong 2012/11/02 21:56:13 IIRC, ExecuteJavaScript() doesn't need the domAuto
nasko 2012/11/05 17:37:11 Done.
124 std::wstring(), js_script));
125 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
126 }
30 }; 127 };
31 128
32 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim) { 129 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim) {
33 ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view")) << message_; 130 ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view")) << message_;
34 } 131 }
35 132
36 IN_PROC_BROWSER_TEST_F(WebViewTest, ShimSrcAttribute) { 133 IN_PROC_BROWSER_TEST_F(WebViewTest, ShimSrcAttribute) {
37 ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view_src_attribute")) 134 ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view_src_attribute"))
38 << message_; 135 << message_;
39 } 136 }
40 137
41 IN_PROC_BROWSER_TEST_F(WebViewTest, Isolation) { 138 IN_PROC_BROWSER_TEST_F(WebViewTest, CookieIsolation) {
42 ASSERT_TRUE(StartTestServer()); 139 ASSERT_TRUE(StartTestServer());
43 const std::wstring kExpire = 140 const std::wstring kExpire =
44 L"var expire = new Date(Date.now() + 24 * 60 * 60 * 1000);"; 141 L"var expire = new Date(Date.now() + 24 * 60 * 60 * 1000);";
45 std::wstring cookie_script1(kExpire); 142 std::wstring cookie_script1(kExpire);
46 cookie_script1.append( 143 cookie_script1.append(
47 L"document.cookie = 'guest1=true; path=/; expires=' + expire + ';';"); 144 L"document.cookie = 'guest1=true; path=/; expires=' + expire + ';';");
48 std::wstring cookie_script2(kExpire); 145 std::wstring cookie_script2(kExpire);
49 cookie_script2.append( 146 cookie_script2.append(
50 L"document.cookie = 'guest2=true; path=/; expires=' + expire + ';';"); 147 L"document.cookie = 'guest2=true; path=/; expires=' + expire + ';';");
51 148
52 GURL::Replacements replace_host; 149 GURL::Replacements replace_host;
53 std::string host_str("localhost"); // Must stay in scope with replace_host. 150 std::string host_str("localhost"); // Must stay in scope with replace_host.
54 replace_host.SetHostStr(host_str); 151 replace_host.SetHostStr(host_str);
55 152
56 GURL set_cookie_url = test_server()->GetURL( 153 GURL set_cookie_url = test_server()->GetURL(
57 "files/extensions/platform_apps/isolation/set_cookie.html"); 154 "files/extensions/platform_apps/isolation/set_cookie.html");
58 set_cookie_url = set_cookie_url.ReplaceComponents(replace_host); 155 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 156
66 // Load a (non-app) page under the "localhost" origin that sets a cookie. 157 content::WebContents* contents1;
67 ui_test_utils::NavigateToURLWithDisposition( 158 content::WebContents* contents2;
68 browser(), set_cookie_url, 159 content::WebContents* contents3;
69 CURRENT_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); 160 content::WebContents* contents4;
70 // Make sure the cookie is set. 161
162 NavigateAndOpenAppForIsolation(set_cookie_url, &contents1, &contents2,
163 &contents3, &contents4);
164
165 EXPECT_TRUE(content::ExecuteJavaScript(
166 contents1->GetRenderViewHost(), std::wstring(), cookie_script1));
167 EXPECT_TRUE(content::ExecuteJavaScript(
168 contents2->GetRenderViewHost(), std::wstring(), cookie_script2));
169
71 int cookie_size; 170 int cookie_size;
72 std::string cookie_value; 171 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 172
78 ui_test_utils::UrlLoadObserver observer1( 173 // 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"), 174 automation_util::GetCookies(GURL("http://localhost"),
102 chrome::GetWebContentsAt(browser(), 0), 175 chrome::GetWebContentsAt(browser(), 0),
103 &cookie_size, &cookie_value); 176 &cookie_size, &cookie_value);
104 EXPECT_EQ("testCookie=1", cookie_value); 177 EXPECT_EQ("testCookie=1", cookie_value);
105 178
106 // The default behavior is to combine webview tags with no explicit partition 179 // 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 180 // 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 181 // ensure we have properly set the cookies and we have both cookies in both
109 // tags. 182 // tags.
110 automation_util::GetCookies(GURL("http://localhost"), 183 automation_util::GetCookies(GURL("http://localhost"),
111 source1->GetWebContents(), 184 contents1,
112 &cookie_size, &cookie_value); 185 &cookie_size, &cookie_value);
113 EXPECT_EQ("guest1=true; guest2=true", cookie_value); 186 EXPECT_EQ("guest1=true; guest2=true", cookie_value);
114 187
115 automation_util::GetCookies(GURL("http://localhost"), 188 automation_util::GetCookies(GURL("http://localhost"),
116 source2->GetWebContents(), 189 contents2,
117 &cookie_size, &cookie_value); 190 &cookie_size, &cookie_value);
118 EXPECT_EQ("guest1=true; guest2=true", cookie_value); 191 EXPECT_EQ("guest1=true; guest2=true", cookie_value);
192
193 // The third tag should not have any cookies, as it is in separate partition.
awong 2012/11/02 21:56:13 s/,//
nasko 2012/11/03 00:36:24 Done.
194 automation_util::GetCookies(GURL("http://localhost"),
195 contents3,
196 &cookie_size, &cookie_value);
197 EXPECT_EQ("", cookie_value);
119 } 198 }
199
200 IN_PROC_BROWSER_TEST_F(WebViewTest, DOMStorageIsolation) {
201 ASSERT_TRUE(StartTestServer());
202 GURL regular_url = test_server()->GetURL("files/title1.html");
203
204 std::string output;
205 std::wstring get_local_storage(L"window.domAutomationController.send("
206 L"window.localStorage.getItem('foo') || 'badval')");
207 std::wstring get_session_storage(L"window.domAutomationController.send("
208 L"window.sessionStorage.getItem('foo') || 'badval')");
209
210 content::WebContents* contents1;
211 content::WebContents* contents2;
212 content::WebContents* storage_contents1;
213 content::WebContents* storage_contents2;
214
215 NavigateAndOpenAppForIsolation(regular_url, &contents1, &contents2,
216 &storage_contents1, &storage_contents2);
217
218 // Initialize the storage for the first of the two tags that share a storage
219 // partition.
220 EXPECT_TRUE(content::ExecuteJavaScript(
awong 2012/11/02 21:56:13 Same comment about domAutomationController(). Som
nasko 2012/11/05 17:37:11 This one doesn't use domAutomationController, does
awong 2012/11/05 18:00:33 Oh right...I misread.
221 storage_contents1->GetRenderViewHost(), std::wstring(),
222 L"initDomStorage('page1')"));
223
224 // Let's test the expected values are present.
awong 2012/11/02 21:56:13 Useless comment. Describe why not what or don't de
nasko 2012/11/05 17:37:11 Done.
225 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
226 storage_contents1->GetRenderViewHost(), std::wstring(),
227 get_local_storage.c_str(), &output));
228 EXPECT_STREQ("local-page1", output.c_str());
229
230 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
231 storage_contents1->GetRenderViewHost(), std::wstring(),
232 get_session_storage.c_str(), &output));
233 EXPECT_STREQ("session-page1", output.c_str());
234
awong 2012/11/02 21:56:13 This vertical spacing makes it really hard for me
nasko 2012/11/05 17:37:11 Done.
235 // Now, init the storage in the second tag in the same storage partition.
236 EXPECT_TRUE(content::ExecuteJavaScript(
237 storage_contents2->GetRenderViewHost(), std::wstring(),
238 L"initDomStorage('page2')"));
239
240 // The values now should reflect the second tag.
241 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
242 storage_contents1->GetRenderViewHost(), std::wstring(),
243 get_local_storage.c_str(), &output));
244 EXPECT_STREQ("local-page2", output.c_str());
245
246 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
247 storage_contents2->GetRenderViewHost(), std::wstring(),
248 get_local_storage.c_str(), &output));
249 EXPECT_STREQ("local-page2", output.c_str());
250
251 // Session storage is not shared though, as each webview tag has separate
252 // instance, even if they are in the same storage partition.
253 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
254 storage_contents1->GetRenderViewHost(), std::wstring(),
255 get_session_storage.c_str(), &output));
256 EXPECT_STREQ("session-page1", output.c_str());
257
258 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
259 storage_contents2->GetRenderViewHost(), std::wstring(),
260 get_session_storage.c_str(), &output));
261 EXPECT_STREQ("session-page2", output.c_str());
262
263 // Also, let's check that the main browser and another tag that doesn't share
264 // the same partition don't have those values stored.
265 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
266 chrome::GetWebContentsAt(browser(), 0)->GetRenderViewHost(),
267 std::wstring(), get_local_storage.c_str(), &output));
268 EXPECT_STREQ("badval", output.c_str());
269 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
270 chrome::GetWebContentsAt(browser(), 0)->GetRenderViewHost(),
271 std::wstring(), get_session_storage.c_str(), &output));
272 EXPECT_STREQ("badval", output.c_str());
awong 2012/11/02 21:56:13 This particular test is really hard to undersatnd
nasko 2012/11/05 17:37:11 Tried to bundle things together with comments a bi
273
274 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
275 contents1->GetRenderViewHost(), std::wstring(),
276 get_local_storage.c_str(), &output));
277 EXPECT_STREQ("badval", output.c_str());
278 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
279 contents1->GetRenderViewHost(), std::wstring(),
280 get_session_storage.c_str(), &output));
281 EXPECT_STREQ("badval", output.c_str());
282 }
283
284 IN_PROC_BROWSER_TEST_F(WebViewTest, IndexedDBIsolation) {
285 ASSERT_TRUE(StartTestServer());
286 GURL regular_url = test_server()->GetURL("files/title1.html");
287
288 content::WebContents* contents1;
289 content::WebContents* contents2;
290 content::WebContents* storage_contents1;
291 content::WebContents* storage_contents2;
292
293 NavigateAndOpenAppForIsolation(regular_url, &contents1, &contents2,
294 &storage_contents1, &storage_contents2);
295
296 // Initialize the storage for the first of the two tags that share a storage
297 // partition.
298 ExecuteScriptWaitForTitle(storage_contents1, "initIDB()", "idb created");
299 ExecuteScriptWaitForTitle(storage_contents1, "addItemIDB(7, 'page1')",
300 "addItemIDB complete");
301 ExecuteScriptWaitForTitle(storage_contents1, "readItemIDB(7)",
302 "readItemIDB complete");
303
304 std::string output;
305 std::wstring get_value(
306 L"window.domAutomationController.send(getValueIDB() || 'badval')");
307
308 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
309 storage_contents1->GetRenderViewHost(), std::wstring(),
310 get_value.c_str(), &output));
311 EXPECT_STREQ("page1", output.c_str());
312
313 // Initialize the db in the second tag.
314 ExecuteScriptWaitForTitle(storage_contents2, "initIDB()", "idb open");
315
316 // Since we share a partition, reading the value should return the existing
317 // one.
318 ExecuteScriptWaitForTitle(storage_contents2, "readItemIDB(7)",
319 "readItemIDB complete");
320 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
321 storage_contents2->GetRenderViewHost(), std::wstring(),
322 get_value.c_str(), &output));
323 EXPECT_STREQ("page1", output.c_str());
324
325 // Now write through the second tag and read it back.
326 ExecuteScriptWaitForTitle(storage_contents2, "addItemIDB(7, 'page2')",
327 "addItemIDB complete");
328 ExecuteScriptWaitForTitle(storage_contents2, "readItemIDB(7)",
329 "readItemIDB complete");
330 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
331 storage_contents2->GetRenderViewHost(), std::wstring(),
332 get_value.c_str(), &output));
333 EXPECT_STREQ("page2", output.c_str());
334
335 // Reset the document title, otherwise the next call will not see a change and
336 // will hang waiting for it.
337 EXPECT_TRUE(content::ExecuteJavaScript(
338 storage_contents1->GetRenderViewHost(), std::wstring(),
339 L"document.title = 'foo'"));
340
341 // Read through the first tag to ensure we have the second value.
342 ExecuteScriptWaitForTitle(storage_contents1, "readItemIDB(7)",
343 "readItemIDB complete");
344 EXPECT_TRUE(ExecuteJavaScriptAndExtractString(
345 storage_contents1->GetRenderViewHost(), std::wstring(),
346 get_value.c_str(), &output));
347 EXPECT_STREQ("page2", output.c_str());
348
349 // Now, let's confirm there is no database in the main browser and another
350 // tag that doesn't share the same partition. Due to the IndexedDB API design,
351 // open will succeed, but the version will be 1, since it creates the database
352 // if it is not found. The two tags use database version 3, so we avoid
353 // ambiguity.
354 const char* script =
355 "indexedDB.open('isolation').onsuccess = function(e) {"
356 " if (e.target.result.version == 1)"
357 " document.title = 'db not found';"
358 " else "
359 " document.title = 'error';"
360 "}";
361 ExecuteScriptWaitForTitle(chrome::GetWebContentsAt(browser(), 0),
362 script, "db not found");
363 ExecuteScriptWaitForTitle(contents1, script, "db not found");
364 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698