| Index: chrome/browser/installable/installable_manager_browsertest.cc
|
| diff --git a/chrome/browser/installable/installable_manager_browsertest.cc b/chrome/browser/installable/installable_manager_browsertest.cc
|
| index 58cabb85b4996b4dd1ff2f2960ffff70113aa860..d7c9b70e0d6f3e498cd070234f3bf85e69fcf551 100644
|
| --- a/chrome/browser/installable/installable_manager_browsertest.cc
|
| +++ b/chrome/browser/installable/installable_manager_browsertest.cc
|
| @@ -5,6 +5,7 @@
|
| #include "chrome/browser/installable/installable_manager.h"
|
|
|
| #include "base/command_line.h"
|
| +#include "base/memory/ptr_util.h"
|
| #include "base/run_loop.h"
|
| #include "base/threading/thread_task_runner_handle.h"
|
| #include "chrome/browser/ui/browser.h"
|
| @@ -12,6 +13,7 @@
|
| #include "chrome/common/chrome_switches.h"
|
| #include "chrome/test/base/in_process_browser_test.h"
|
| #include "chrome/test/base/ui_test_utils.h"
|
| +#include "content/public/test/browser_test_utils.h"
|
| #include "net/test/embedded_test_server/embedded_test_server.h"
|
|
|
| using IconPurpose = content::Manifest::Icon::IconPurpose;
|
| @@ -58,6 +60,25 @@ InstallableParams GetPrimaryIconAndBadgeIconParams() {
|
|
|
| } // anonymous namespace
|
|
|
| +// Used only for testing pages with no service workers. This class will dispatch
|
| +// a RunLoop::QuitClosure when it begins waiting for a service worker to be
|
| +// registered.
|
| +class LazyWorkerInstallableManager : public InstallableManager {
|
| + public:
|
| + LazyWorkerInstallableManager(content::WebContents* web_contents,
|
| + base::Closure quit_closure)
|
| + : InstallableManager(web_contents), quit_closure_(quit_closure) {}
|
| + ~LazyWorkerInstallableManager() override {}
|
| +
|
| + protected:
|
| + void OnWaitingForServiceWorker() override {
|
| + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, quit_closure_);
|
| + };
|
| +
|
| + private:
|
| + base::Closure quit_closure_;
|
| +};
|
| +
|
| class CallbackTester {
|
| public:
|
| explicit CallbackTester(base::Closure quit_closure)
|
| @@ -214,7 +235,8 @@ IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest,
|
| EXPECT_FALSE(manager->is_installable());
|
|
|
| EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error());
|
| - EXPECT_EQ(NO_ERROR_DETECTED, manager->installable_error());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error());
|
| EXPECT_TRUE(manager->tasks_.empty());
|
| }
|
|
|
| @@ -543,7 +565,8 @@ IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest, CheckWebapp) {
|
| EXPECT_FALSE((manager->icon_url(kPrimaryIconParams).is_empty()));
|
| EXPECT_NE(nullptr, (manager->icon(kPrimaryIconParams)));
|
| EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error());
|
| - EXPECT_EQ(NO_ERROR_DETECTED, manager->installable_error());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error());
|
| EXPECT_EQ(NO_ERROR_DETECTED, (manager->icon_error(kPrimaryIconParams)));
|
| EXPECT_TRUE(manager->tasks_.empty());
|
| }
|
| @@ -579,7 +602,8 @@ IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest, CheckWebapp) {
|
| EXPECT_FALSE((manager->icon_url(kPrimaryIconParams).is_empty()));
|
| EXPECT_NE(nullptr, (manager->icon(kPrimaryIconParams)));
|
| EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error());
|
| - EXPECT_EQ(NO_ERROR_DETECTED, manager->installable_error());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error());
|
| EXPECT_EQ(NO_ERROR_DETECTED, (manager->icon_error(kPrimaryIconParams)));
|
| EXPECT_TRUE(manager->tasks_.empty());
|
| }
|
| @@ -594,7 +618,8 @@ IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest, CheckWebapp) {
|
| EXPECT_FALSE(manager->is_installable());
|
| EXPECT_TRUE(manager->icons_.empty());
|
| EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error());
|
| - EXPECT_EQ(NO_ERROR_DETECTED, manager->installable_error());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error());
|
| EXPECT_TRUE(manager->tasks_.empty());
|
| }
|
| }
|
| @@ -647,13 +672,15 @@ IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest,
|
| EXPECT_EQ(GetStatus(), InstallabilityCheckStatus::NOT_COMPLETED);
|
| }
|
|
|
| - // Fetch the full criteria should fail.
|
| + // Fetching the full criteria should fail if we don't wait for the worker.
|
| {
|
| base::RunLoop run_loop;
|
| std::unique_ptr<CallbackTester> tester(
|
| new CallbackTester(run_loop.QuitClosure()));
|
|
|
| - RunInstallableManager(tester.get(), GetWebAppParams());
|
| + InstallableParams params = GetWebAppParams();
|
| + params.wait_for_worker = false;
|
| + RunInstallableManager(tester.get(), params);
|
| run_loop.Run();
|
|
|
| EXPECT_FALSE(tester->manifest().IsEmpty());
|
| @@ -670,6 +697,175 @@ IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest,
|
| }
|
| }
|
|
|
| +IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest,
|
| + CheckLazyServiceWorkerPassesWhenWaiting) {
|
| + base::RunLoop tester_run_loop, sw_run_loop;
|
| + std::unique_ptr<CallbackTester> tester(
|
| + new CallbackTester(tester_run_loop.QuitClosure()));
|
| +
|
| + content::WebContents* web_contents =
|
| + browser()->tab_strip_model()->GetActiveWebContents();
|
| + auto manager = base::MakeUnique<LazyWorkerInstallableManager>(
|
| + web_contents, sw_run_loop.QuitClosure());
|
| +
|
| + // Load a URL with no service worker.
|
| + GURL test_url = embedded_test_server()->GetURL(
|
| + "/banners/manifest_no_service_worker.html");
|
| + ui_test_utils::NavigateToURL(browser(), test_url);
|
| +
|
| + // Kick off fetching the data. This should block on waiting for a worker.
|
| + manager->GetData(GetWebAppParams(),
|
| + base::Bind(&CallbackTester::OnDidFinishInstallableCheck,
|
| + base::Unretained(tester.get())));
|
| + sw_run_loop.Run();
|
| +
|
| + // We should now be waiting for the service worker.
|
| + EXPECT_FALSE(manager->manifest().IsEmpty());
|
| + EXPECT_FALSE(manager->manifest_url().is_empty());
|
| + EXPECT_FALSE(manager->is_installable());
|
| + EXPECT_EQ(1u, manager->icons_.size());
|
| + EXPECT_FALSE((manager->icon_url(kPrimaryIconParams).is_empty()));
|
| + EXPECT_NE(nullptr, (manager->icon(kPrimaryIconParams)));
|
| + EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, (manager->icon_error(kPrimaryIconParams)));
|
| + EXPECT_TRUE(manager->worker_waiting());
|
| + EXPECT_FALSE(manager->tasks_.empty());
|
| +
|
| + // Load the service worker.
|
| + EXPECT_TRUE(content::ExecuteScript(
|
| + web_contents, "navigator.serviceWorker.register('service_worker.js');"));
|
| + tester_run_loop.Run();
|
| +
|
| + // We should have passed now.
|
| + EXPECT_FALSE(tester->manifest().IsEmpty());
|
| + EXPECT_FALSE(tester->manifest_url().is_empty());
|
| + EXPECT_FALSE(tester->primary_icon_url().is_empty());
|
| + EXPECT_NE(nullptr, tester->primary_icon());
|
| + EXPECT_TRUE(tester->is_installable());
|
| + EXPECT_TRUE(tester->badge_icon_url().is_empty());
|
| + EXPECT_EQ(nullptr, tester->badge_icon());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, tester->error_code());
|
| + EXPECT_EQ(manager->page_status_,
|
| + InstallabilityCheckStatus::COMPLETE_PROGRESSIVE_WEB_APP);
|
| +
|
| + // Verify internal state.
|
| + EXPECT_FALSE(manager->manifest().IsEmpty());
|
| + EXPECT_FALSE(manager->manifest_url().is_empty());
|
| + EXPECT_TRUE(manager->is_installable());
|
| + EXPECT_EQ(1u, manager->icons_.size());
|
| + EXPECT_FALSE((manager->icon_url(kPrimaryIconParams).is_empty()));
|
| + EXPECT_NE(nullptr, (manager->icon(kPrimaryIconParams)));
|
| + EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, (manager->icon_error(kPrimaryIconParams)));
|
| + EXPECT_FALSE(manager->worker_waiting());
|
| + EXPECT_TRUE(manager->tasks_.empty());
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest,
|
| + CheckLazyServiceWorkerNoFetchHandlerFails) {
|
| + base::RunLoop tester_run_loop, sw_run_loop;
|
| + std::unique_ptr<CallbackTester> tester(
|
| + new CallbackTester(tester_run_loop.QuitClosure()));
|
| +
|
| + content::WebContents* web_contents =
|
| + browser()->tab_strip_model()->GetActiveWebContents();
|
| + auto manager = base::MakeUnique<LazyWorkerInstallableManager>(
|
| + web_contents, sw_run_loop.QuitClosure());
|
| +
|
| + // Load a URL with no service worker.
|
| + GURL test_url = embedded_test_server()->GetURL(
|
| + "/banners/manifest_no_service_worker.html");
|
| + ui_test_utils::NavigateToURL(browser(), test_url);
|
| +
|
| + // Kick off fetching the data. This should block on waiting for a worker.
|
| + manager->GetData(GetWebAppParams(),
|
| + base::Bind(&CallbackTester::OnDidFinishInstallableCheck,
|
| + base::Unretained(tester.get())));
|
| + sw_run_loop.Run();
|
| +
|
| + // We should now be waiting for the service worker.
|
| + EXPECT_TRUE(manager->worker_waiting());
|
| + EXPECT_FALSE(manager->tasks_.empty());
|
| +
|
| + // Load the service worker with no fetch handler.
|
| + EXPECT_TRUE(content::ExecuteScript(web_contents,
|
| + "navigator.serviceWorker.register('"
|
| + "service_worker_no_fetch_handler.js');"));
|
| + tester_run_loop.Run();
|
| +
|
| + // We should fail the check.
|
| + EXPECT_FALSE(tester->manifest().IsEmpty());
|
| + EXPECT_FALSE(tester->manifest_url().is_empty());
|
| + EXPECT_FALSE(tester->primary_icon_url().is_empty());
|
| + EXPECT_NE(nullptr, tester->primary_icon());
|
| + EXPECT_FALSE(tester->is_installable());
|
| + EXPECT_TRUE(tester->badge_icon_url().is_empty());
|
| + EXPECT_EQ(nullptr, tester->badge_icon());
|
| + EXPECT_EQ(NOT_OFFLINE_CAPABLE, tester->error_code());
|
| + EXPECT_FALSE(manager->worker_waiting());
|
| + EXPECT_EQ(manager->page_status_,
|
| + InstallabilityCheckStatus::COMPLETE_NON_PROGRESSIVE_WEB_APP);
|
| +}
|
| +
|
| +IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest,
|
| + CheckServiceWorkerErrorIsNotCached) {
|
| + content::WebContents* web_contents =
|
| + browser()->tab_strip_model()->GetActiveWebContents();
|
| + base::RunLoop sw_run_loop;
|
| + auto manager = base::MakeUnique<LazyWorkerInstallableManager>(
|
| + web_contents, sw_run_loop.QuitClosure());
|
| +
|
| + // Load a URL with no service worker.
|
| + GURL test_url = embedded_test_server()->GetURL(
|
| + "/banners/manifest_no_service_worker.html");
|
| + ui_test_utils::NavigateToURL(browser(), test_url);
|
| +
|
| + {
|
| + base::RunLoop tester_run_loop;
|
| + std::unique_ptr<CallbackTester> tester(
|
| + new CallbackTester(tester_run_loop.QuitClosure()));
|
| +
|
| + InstallableParams params = GetWebAppParams();
|
| + params.wait_for_worker = false;
|
| + manager->GetData(params,
|
| + base::Bind(&CallbackTester::OnDidFinishInstallableCheck,
|
| + base::Unretained(tester.get())));
|
| + tester_run_loop.Run();
|
| +
|
| + // We should have returned with an error.
|
| + EXPECT_FALSE(tester->manifest().IsEmpty());
|
| + EXPECT_FALSE(tester->is_installable());
|
| + EXPECT_EQ(NO_MATCHING_SERVICE_WORKER, tester->error_code());
|
| + }
|
| +
|
| + {
|
| + base::RunLoop tester_run_loop;
|
| + std::unique_ptr<CallbackTester> tester(
|
| + new CallbackTester(tester_run_loop.QuitClosure()));
|
| +
|
| + InstallableParams params = GetWebAppParams();
|
| + params.wait_for_worker = true;
|
| + manager->GetData(params,
|
| + base::Bind(&CallbackTester::OnDidFinishInstallableCheck,
|
| + base::Unretained(tester.get())));
|
| + sw_run_loop.Run();
|
| +
|
| + EXPECT_TRUE(content::ExecuteScript(
|
| + web_contents,
|
| + "navigator.serviceWorker.register('service_worker.js');"));
|
| + tester_run_loop.Run();
|
| +
|
| + // The callback should tell us that the page is installable
|
| + EXPECT_FALSE(tester->manifest().IsEmpty());
|
| + EXPECT_TRUE(tester->is_installable());
|
| + EXPECT_EQ(NO_ERROR_DETECTED, tester->error_code());
|
| + }
|
| +}
|
| +
|
| IN_PROC_BROWSER_TEST_F(InstallableManagerBrowserTest,
|
| CheckPageWithNoServiceWorkerFetchHandler) {
|
| base::RunLoop run_loop;
|
|
|