44 * You can obtain one at https://mozilla.org/MPL/2.0/. */
55
66#include " brave/browser/ui/browser_commands.h"
7- #include " brave/components/containers/core /browser/storage_partition_constants .h"
7+ #include " brave/components/containers/content /browser/storage_partition_utils .h"
88#include " brave/components/containers/core/common/features.h"
99#include " brave/components/containers/core/mojom/containers.mojom.h"
1010#include " chrome/browser/profiles/profile.h"
@@ -243,7 +243,7 @@ IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, IsolateCookiesAndStorage) {
243243 NavigateParams params (browser (), url, ui::PAGE_TRANSITION_LINK);
244244 params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
245245 params.storage_partition_config = content::StoragePartitionConfig::Create (
246- browser ()->profile (), " default " , " container-a" ,
246+ browser ()->profile (), kContainersStoragePartitionDomain , " container-a" ,
247247 browser ()->profile ()->IsOffTheRecord ());
248248 ui_test_utils::NavigateToURL (¶ms);
249249
@@ -306,7 +306,7 @@ IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, IsolateCookiesAndStorage) {
306306 NavigateParams params_b (browser (), url, ui::PAGE_TRANSITION_LINK);
307307 params_b.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
308308 params_b.storage_partition_config = content::StoragePartitionConfig::Create (
309- browser ()->profile (), " default " , " container-b" ,
309+ browser ()->profile (), kContainersStoragePartitionDomain , " container-b" ,
310310 browser ()->profile ()->IsOffTheRecord ());
311311 ui_test_utils::NavigateToURL (¶ms_b);
312312
@@ -328,7 +328,164 @@ IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, IsolateCookiesAndStorage) {
328328 GetIndexedDBJS (" test_key" )));
329329}
330330
331- IN_PROC_BROWSER_TEST_F (ContainersBrowserTest, IsolateServiceWorkers) {
331+ IN_PROC_BROWSER_TEST_F (ContainersBrowserTest,
332+ PRE_StoragePersistenceAcrossSessions) {
333+ const GURL url (" https://a.test/simple.html" );
334+
335+ // Navigate to the page
336+ NavigateParams params (browser (), url, ui::PAGE_TRANSITION_LINK);
337+ params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
338+ params.storage_partition_config = content::StoragePartitionConfig::Create (
339+ browser ()->profile (), kContainersStoragePartitionDomain , " container" ,
340+ browser ()->profile ()->IsOffTheRecord ());
341+ ui_test_utils::NavigateToURL (¶ms);
342+
343+ content::WebContents* web_contents =
344+ browser ()->tab_strip_model ()->GetActiveWebContents ();
345+ ASSERT_TRUE (web_contents);
346+
347+ // Set persistent storage data
348+ EXPECT_TRUE (content::ExecJs (
349+ web_contents, SetCookieJS (" persistent_cookie" , " persistent_value" )));
350+ EXPECT_TRUE (content::ExecJs (
351+ web_contents, SetLocalStorageJS (" persistent_key" , " persistent_value" )));
352+
353+ EXPECT_TRUE (content::ExecJs (
354+ web_contents, SetIndexedDBJS (" persistent_key" , " persistent_value" )));
355+
356+ // Verify data is set
357+ content::EvalJsResult cookie_result =
358+ content::EvalJs (web_contents, GetCookiesJS ());
359+ EXPECT_TRUE (cookie_result.ExtractString ().find (
360+ " persistent_cookie=persistent_value" ) != std::string::npos);
361+
362+ EXPECT_EQ (" persistent_value" ,
363+ content::EvalJs (web_contents, GetLocalStorageJS (" persistent_key" )));
364+ EXPECT_EQ (" persistent_value" ,
365+ content::EvalJs (web_contents, GetIndexedDBJS (" persistent_key" )));
366+ }
367+
368+ IN_PROC_BROWSER_TEST_F (ContainersBrowserTest,
369+ StoragePersistenceAcrossSessions) {
370+ const GURL url (" https://a.test/simple.html" );
371+
372+ // Navigate to the page
373+ NavigateParams params (browser (), url, ui::PAGE_TRANSITION_LINK);
374+ params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
375+ params.storage_partition_config = content::StoragePartitionConfig::Create (
376+ browser ()->profile (), kContainersStoragePartitionDomain , " container" ,
377+ browser ()->profile ()->IsOffTheRecord ());
378+ ui_test_utils::NavigateToURL (¶ms);
379+
380+ content::WebContents* web_contents_reloaded =
381+ browser ()->tab_strip_model ()->GetActiveWebContents ();
382+ ASSERT_TRUE (web_contents_reloaded);
383+
384+ // Verify persistent data is still available after reload
385+ content::EvalJsResult cookie_result_reloaded =
386+ content::EvalJs (web_contents_reloaded, GetCookiesJS ());
387+ EXPECT_TRUE (cookie_result_reloaded.ExtractString ().find (
388+ " persistent_cookie=persistent_value" ) != std::string::npos);
389+
390+ EXPECT_EQ (" persistent_value" ,
391+ content::EvalJs (web_contents_reloaded,
392+ GetLocalStorageJS (" persistent_key" )));
393+ EXPECT_EQ (
394+ " persistent_value" ,
395+ content::EvalJs (web_contents_reloaded, GetIndexedDBJS (" persistent_key" )));
396+ }
397+
398+ IN_PROC_BROWSER_TEST_F (ContainersBrowserTest,
399+ LinkNavigationInheritsContainerStoragePartition) {
400+ const GURL url (" https://a.test/simple.html" );
401+
402+ // Navigate to base URL with a container
403+ NavigateParams params (browser (), url, ui::PAGE_TRANSITION_LINK);
404+ params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
405+ params.storage_partition_config = content::StoragePartitionConfig::Create (
406+ browser ()->profile (), kContainersStoragePartitionDomain ,
407+ " container-for-links" , browser ()->profile ()->IsOffTheRecord ());
408+ ui_test_utils::NavigateToURL (¶ms);
409+
410+ content::WebContents* container_web_contents =
411+ browser ()->tab_strip_model ()->GetActiveWebContents ();
412+ ASSERT_TRUE (container_web_contents);
413+
414+ EXPECT_TRUE (
415+ content::ExecJs (container_web_contents,
416+ SetCookieJS (" container_cookie" , " container_value" )));
417+ EXPECT_TRUE (
418+ content::ExecJs (container_web_contents,
419+ SetLocalStorageJS (" container_key" , " container_value" )));
420+ EXPECT_TRUE (
421+ content::ExecJs (container_web_contents,
422+ SetSessionStorageJS (" container_key" , " container_value" )));
423+ EXPECT_TRUE (
424+ content::ExecJs (container_web_contents,
425+ SetIndexedDBJS (" container_key" , " container_value" )));
426+
427+ // Inject a link that opens in new tab
428+ std::string inject_new_tab_link_js = content::JsReplace (
429+ " const link = document.createElement('a');"
430+ " link.href = $1;"
431+ " link.textContent = 'New Tab Link';"
432+ " link.id = 'new-tab-link';"
433+ " link.target = '_blank';"
434+ " document.body.appendChild(link);"
435+ " link.click();" ,
436+ url);
437+
438+ content::WebContentsAddedObserver new_tab_observer;
439+ EXPECT_TRUE (content::ExecJs (container_web_contents, inject_new_tab_link_js));
440+ content::WebContents* new_tab_contents = new_tab_observer.GetWebContents ();
441+ ASSERT_TRUE (new_tab_contents);
442+
443+ ASSERT_NE (new_tab_contents, container_web_contents);
444+
445+ // Wait for the new tab to load
446+ EXPECT_TRUE (content::WaitForLoadStop (new_tab_contents));
447+
448+ // Verify the new tab is on the correct URL
449+ EXPECT_EQ (url, new_tab_contents->GetLastCommittedURL ());
450+
451+ // Verify the new tab has access to the same container storage partition
452+ content::EvalJsResult cookie_result =
453+ content::EvalJs (new_tab_contents, GetCookiesJS ());
454+ EXPECT_TRUE (cookie_result.ExtractString ().find (
455+ " container_cookie=container_value" ) != std::string::npos);
456+ EXPECT_EQ (
457+ " container_value" ,
458+ content::EvalJs (new_tab_contents, GetLocalStorageJS (" container_key" )));
459+ EXPECT_EQ (
460+ base::Value (),
461+ content::EvalJs (new_tab_contents, GetSessionStorageJS (" container_key" )));
462+ EXPECT_EQ (" container_value" ,
463+ content::EvalJs (new_tab_contents, GetIndexedDBJS (" container_key" )));
464+
465+ // Verify that setting storage in the new tab affects the container
466+ EXPECT_TRUE (content::ExecJs (new_tab_contents,
467+ SetCookieJS (" new_tab_cookie" , " new_tab_value" )));
468+ EXPECT_TRUE (content::ExecJs (
469+ new_tab_contents, SetLocalStorageJS (" new_tab_key" , " new_tab_value" )));
470+ EXPECT_TRUE (content::ExecJs (
471+ new_tab_contents, SetSessionStorageJS (" new_tab_key" , " new_tab_value" )));
472+ EXPECT_TRUE (content::ExecJs (new_tab_contents,
473+ SetIndexedDBJS (" new_tab_key" , " new_tab_value" )));
474+
475+ // Verify the original container tab can see the new storage
476+ cookie_result = content::EvalJs (container_web_contents, GetCookiesJS ());
477+ EXPECT_TRUE (cookie_result.ExtractString ().find (
478+ " new_tab_cookie=new_tab_value" ) != std::string::npos);
479+ EXPECT_EQ (" new_tab_value" , content::EvalJs (container_web_contents,
480+ GetLocalStorageJS (" new_tab_key" )));
481+ EXPECT_EQ (base::Value (), content::EvalJs (container_web_contents,
482+ GetSessionStorageJS (" new_tab_key" )));
483+ EXPECT_EQ (" new_tab_value" , content::EvalJs (container_web_contents,
484+ GetIndexedDBJS (" new_tab_key" )));
485+ }
486+
487+ IN_PROC_BROWSER_TEST_F (ContainersBrowserTest,
488+ IsolateServiceWorkersBetweenContainers) {
332489 const GURL url (" https://a.test/containers/container_test.html" );
333490 const GURL worker_url (" https://a.test/containers/container_worker.js" );
334491 const std::string scope = " https://a.test/containers/" ;
@@ -352,11 +509,11 @@ IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, IsolateServiceWorkers) {
352509 EXPECT_EQ (1 , content::EvalJs (web_contents_default,
353510 GetServiceWorkerRegistrationCountJS ()));
354511
355- // Open a new tab with a different storage partition (container-a )
512+ // Open a new tab with a different storage partition (container_a )
356513 NavigateParams params (browser (), url, ui::PAGE_TRANSITION_LINK);
357514 params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
358515 params.storage_partition_config = content::StoragePartitionConfig::Create (
359- browser ()->profile (), " default " , " container-a" ,
516+ browser ()->profile (), kContainersStoragePartitionDomain , " container-a" ,
360517 browser ()->profile ()->IsOffTheRecord ());
361518 ui_test_utils::NavigateToURL (¶ms);
362519
@@ -397,11 +554,11 @@ IN_PROC_BROWSER_TEST_F(ContainersBrowserTest, IsolateServiceWorkers) {
397554 EXPECT_EQ (1 , content::EvalJs (web_contents_default,
398555 GetServiceWorkerRegistrationCountJS ()));
399556
400- // Open another container (container-b )
557+ // Open another container (container_b )
401558 NavigateParams params_b (browser (), url, ui::PAGE_TRANSITION_LINK);
402559 params_b.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
403560 params_b.storage_partition_config = content::StoragePartitionConfig::Create (
404- browser ()->profile (), " default " , " container-b" ,
561+ browser ()->profile (), kContainersStoragePartitionDomain , " container-b" ,
405562 browser ()->profile ()->IsOffTheRecord ());
406563 ui_test_utils::NavigateToURL (¶ms_b);
407564
@@ -762,4 +919,70 @@ IN_PROC_BROWSER_TEST_F(ContainersBrowserTest,
762919 // container
763920}
764921
922+ IN_PROC_BROWSER_TEST_F (ContainersBrowserTest,
923+ PRE_ServiceWorkerPersistenceAcrossSessions) {
924+ const GURL url (" https://a.test/containers/container_test.html" );
925+ const GURL worker_url (" https://a.test/containers/container_worker.js" );
926+ const std::string scope = " https://a.test/containers/" ;
927+
928+ // Navigate to the page with a container
929+ NavigateParams params (browser (), url, ui::PAGE_TRANSITION_LINK);
930+ params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
931+ params.storage_partition_config = content::StoragePartitionConfig::Create (
932+ browser ()->profile (), kContainersStoragePartitionDomain ,
933+ " persistent-container" , browser ()->profile ()->IsOffTheRecord ());
934+ ui_test_utils::NavigateToURL (¶ms);
935+
936+ content::WebContents* web_contents =
937+ browser ()->tab_strip_model ()->GetActiveWebContents ();
938+ ASSERT_TRUE (web_contents);
939+
940+ // Register service worker
941+ EXPECT_TRUE (content::ExecJs (
942+ web_contents, RegisterServiceWorkerJS (worker_url.spec (), scope)));
943+
944+ // Verify service worker is registered
945+ EXPECT_EQ (
946+ " registered" ,
947+ content::EvalJs (web_contents, CheckServiceWorkerRegisteredJS (scope)));
948+
949+ // Set some persistent storage data that the service worker might use
950+ EXPECT_TRUE (content::ExecJs (
951+ web_contents, SetLocalStorageJS (" sw_data" , " persistent_value" )));
952+ EXPECT_TRUE (content::ExecJs (web_contents,
953+ SetCookieJS (" sw_cookie" , " persistent_cookie" )));
954+ }
955+
956+ IN_PROC_BROWSER_TEST_F (ContainersBrowserTest,
957+ ServiceWorkerPersistenceAcrossSessions) {
958+ const GURL url (" https://a.test/containers/container_test.html" );
959+ const std::string scope = " https://a.test/containers/" ;
960+
961+ // Navigate to the page with the same container
962+ NavigateParams params (browser (), url, ui::PAGE_TRANSITION_LINK);
963+ params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
964+ params.storage_partition_config = content::StoragePartitionConfig::Create (
965+ browser ()->profile (), kContainersStoragePartitionDomain ,
966+ " persistent-container" , browser ()->profile ()->IsOffTheRecord ());
967+ ui_test_utils::NavigateToURL (¶ms);
968+
969+ content::WebContents* web_contents_reloaded =
970+ browser ()->tab_strip_model ()->GetActiveWebContents ();
971+ ASSERT_TRUE (web_contents_reloaded);
972+
973+ // Verify service worker is still registered after browser restart
974+ EXPECT_EQ (" registered" ,
975+ content::EvalJs (web_contents_reloaded,
976+ CheckServiceWorkerRegisteredJS (scope)));
977+
978+ // Verify persistent storage data is still available
979+ EXPECT_EQ (" persistent_value" , content::EvalJs (web_contents_reloaded,
980+ GetLocalStorageJS (" sw_data" )));
981+
982+ content::EvalJsResult cookie_result =
983+ content::EvalJs (web_contents_reloaded, GetCookiesJS ());
984+ EXPECT_TRUE (cookie_result.ExtractString ().find (
985+ " sw_cookie=persistent_cookie" ) != std::string::npos);
986+ }
987+
765988} // namespace containers
0 commit comments