14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/extension_install_prompt.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/tab_helper.h" 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/webstore_inline_installer.h" 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/webstore_inline_installer_factory.h" 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/webstore_installer_test.h" 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/extensions/webstore_standalone_installer.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/browser.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/test/base/ui_test_utils.h" 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/web_contents.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "url/gurl.h" 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using content::WebContents; 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace extensions { 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kWebstoreDomain[] = "cws.com"; 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kAppDomain[] = "app.com"; 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kNonAppDomain[] = "nonapp.com"; 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kTestExtensionId[] = "ecglahbcnmdpdciemllbhojghbkagdje"; 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kTestDataPath[] = "extensions/api_test/webstore_inline_install"; 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kCrxFilename[] = "extension.crx"; 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class WebstoreInlineInstallerTest : public WebstoreInstallerTest { 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebstoreInlineInstallerTest() 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : WebstoreInstallerTest( 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) kWebstoreDomain, 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) kTestDataPath, 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) kCrxFilename, 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) kAppDomain, 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) kNonAppDomain) {} 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class ProgrammableInstallPrompt : public ExtensionInstallPrompt { 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) explicit ProgrammableInstallPrompt(WebContents* contents) 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : ExtensionInstallPrompt(contents) 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) {} 514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual ~ProgrammableInstallPrompt() {} 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void ConfirmStandaloneInstall( 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Delegate* delegate, 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const Extension* extension, 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SkBitmap* icon, 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_refptr<ExtensionInstallPrompt::Prompt> prompt) OVERRIDE { 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) delegate_ = delegate; 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static bool Ready() { 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return delegate_ != NULL; 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static void Accept() { 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) delegate_->InstallUIProceed(); 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static void Reject() { 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) delegate_->InstallUIAbort(true); 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static Delegate* delegate_; 764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)ExtensionInstallPrompt::Delegate* ProgrammableInstallPrompt::delegate_; 794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Fake inline installer which creates a programmable prompt in place of 814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// the normal dialog UI. 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class WebstoreInlineInstallerForTest : public WebstoreInlineInstaller { 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebstoreInlineInstallerForTest(WebContents* contents, 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& extension_id, 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const GURL& requestor_url, 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const Callback& callback) 884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : WebstoreInlineInstaller( 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) contents, 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) kTestExtensionId, 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) requestor_url, 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(DummyCallback)), 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) programmable_prompt_(NULL) { 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual scoped_ptr<ExtensionInstallPrompt> CreateInstallUI() OVERRIDE { 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) programmable_prompt_ = new ProgrammableInstallPrompt(web_contents()); 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return make_scoped_ptr(programmable_prompt_). 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) PassAs<ExtensionInstallPrompt>(); 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual ~WebstoreInlineInstallerForTest() {} 1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) friend class base::RefCountedThreadSafe<WebstoreStandaloneInstaller>; 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static void DummyCallback(bool success, 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& error, 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) webstore_install::Result result) { 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ProgrammableInstallPrompt* programmable_prompt_; 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class WebstoreInlineInstallerForTestFactory : 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public WebstoreInlineInstallerFactory { 1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual ~WebstoreInlineInstallerForTestFactory() {} 1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual WebstoreInlineInstaller* CreateInstaller( 1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebContents* contents, 1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& webstore_item_id, 1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const GURL& requestor_url, 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const WebstoreStandaloneInstaller::Callback& callback) OVERRIDE { 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return new WebstoreInlineInstallerForTest( 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) contents, webstore_item_id, requestor_url, callback); 1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest, 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CloseTabBeforeInstallConfirmation) { 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GURL install_url = GenerateTestServerUrl(kAppDomain, "install.html"); 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ui_test_utils::NavigateToURL(browser(), install_url); 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WebContents* web_contents = 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents(); 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) TabHelper* tab_helper = TabHelper::FromWebContents(web_contents); 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) tab_helper->SetWebstoreInlineInstallerFactoryForTests( 1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new WebstoreInlineInstallerForTestFactory()); 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) RunTestAsync("runTest"); 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) while (!ProgrammableInstallPrompt::Ready()) 1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) web_contents->Close(); 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ProgrammableInstallPrompt::Accept(); 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Ensure that inline-installing a disabled extension simply re-enables it. 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerTest, 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ReinstallDisabledExtension) { 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Install an extension via inline install, and confirm it is successful. 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionInstallPrompt::g_auto_confirm_for_tests = 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionInstallPrompt::ACCEPT; 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui_test_utils::NavigateToURL( 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) browser(), GenerateTestServerUrl(kAppDomain, "install.html")); 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunTest("runTest"); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionService* extension_service = 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionSystem::Get(browser()->profile())->extension_service(); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(extension_service->GetExtensionById(kTestExtensionId, false)); 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Disable the extension. 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_service->DisableExtension(kTestExtensionId, 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Extension::DISABLE_USER_ACTION); 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_FALSE(extension_service->IsExtensionEnabled(kTestExtensionId)); 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Revisit the inline install site and reinstall the extension. It should 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // simply be re-enabled, rather than try to install again. 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ui_test_utils::NavigateToURL( 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) browser(), GenerateTestServerUrl(kAppDomain, "install.html")); 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RunTest("runTest"); 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ASSERT_TRUE(extension_service->IsExtensionEnabled(kTestExtensionId)); 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochclass WebstoreInlineInstallerListenerTest : public WebstoreInlineInstallerTest { 171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch public: 172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch WebstoreInlineInstallerListenerTest() {} 173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual ~WebstoreInlineInstallerListenerTest() {} 174effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch protected: 176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void RunTest(const std::string& file_name) { 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionInstallPrompt::g_auto_confirm_for_tests = 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ExtensionInstallPrompt::ACCEPT; 179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ui_test_utils::NavigateToURL(browser(), 180effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch GenerateTestServerUrl(kAppDomain, file_name)); 181effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch WebstoreInstallerTest::RunTest("runTest"); 182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}; 184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 185effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochIN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest, 186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch InstallStageListenerTest) { 187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RunTest("install_stage_listener.html"); 188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 189effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 190effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochIN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest, 191effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DownloadProgressListenerTest) { 192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RunTest("download_progress_listener.html"); 193effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 195effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochIN_PROC_BROWSER_TEST_F(WebstoreInlineInstallerListenerTest, BothListenersTest) { 196effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch RunTest("both_listeners.html"); 197effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 198effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace extensions 200