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 3 // found in the LICENSE file. 4 5 #include "base/command_line.h" 6 #include "base/path_service.h" 7 #include "base/strings/utf_string_conversions.h" 8 #include "chrome/browser/chrome_notification_types.h" 9 #include "chrome/browser/infobars/confirm_infobar_delegate.h" 10 #include "chrome/browser/infobars/infobar_service.h" 11 #include "chrome/browser/ui/browser.h" 12 #include "chrome/browser/ui/browser_commands.h" 13 #include "chrome/browser/ui/browser_navigator.h" 14 #include "chrome/browser/ui/tabs/tab_strip_model.h" 15 #include "chrome/common/chrome_paths.h" 16 #include "chrome/common/chrome_switches.h" 17 #include "chrome/common/url_constants.h" 18 #include "chrome/test/base/in_process_browser_test.h" 19 #include "chrome/test/base/test_launcher_utils.h" 20 #include "chrome/test/base/test_switches.h" 21 #include "chrome/test/base/ui_test_utils.h" 22 #include "content/public/browser/gpu_data_manager.h" 23 #include "content/public/browser/notification_service.h" 24 #include "content/public/browser/notification_types.h" 25 #include "content/public/common/content_paths.h" 26 #include "content/public/common/page_transition_types.h" 27 #include "content/public/test/browser_test_utils.h" 28 #include "gpu/config/gpu_test_config.h" 29 #include "testing/gtest/include/gtest/gtest.h" 30 #include "ui/gl/gl_implementation.h" 31 32 namespace { 33 34 void SimulateGPUCrash(Browser* browser) { 35 // None of the ui_test_utils entry points supports what we need to 36 // do here: navigate with the PAGE_TRANSITION_FROM_ADDRESS_BAR flag, 37 // without waiting for the navigation. It would be painful to change 38 // either of the NavigateToURL entry points to support these two 39 // constraints, so we use chrome::Navigate directly. 40 chrome::NavigateParams params( 41 browser, 42 GURL(content::kChromeUIGpuCrashURL), 43 static_cast<content::PageTransition>( 44 content::PAGE_TRANSITION_TYPED | 45 content::PAGE_TRANSITION_FROM_ADDRESS_BAR)); 46 params.disposition = NEW_BACKGROUND_TAB; 47 chrome::Navigate(¶ms); 48 } 49 50 } // namespace 51 52 class WebGLInfobarTest : public InProcessBrowserTest { 53 protected: 54 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 55 base::FilePath test_dir; 56 ASSERT_TRUE(PathService::Get(content::DIR_TEST_DATA, &test_dir)); 57 gpu_test_dir_ = test_dir.AppendASCII("gpu"); 58 } 59 base::FilePath gpu_test_dir_; 60 }; 61 62 IN_PROC_BROWSER_TEST_F(WebGLInfobarTest, ContextLossRaisesInfobar) { 63 #if defined(OS_WIN) && defined(USE_ASH) 64 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 65 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 66 return; 67 #endif 68 69 if (gpu::GPUTestBotConfig::CurrentConfigMatches("XP")) 70 return; 71 72 // Load page and wait for it to load. 73 content::WindowedNotificationObserver observer( 74 content::NOTIFICATION_LOAD_STOP, 75 content::NotificationService::AllSources()); 76 ui_test_utils::NavigateToURL( 77 browser(), 78 content::GetFileUrlWithQuery( 79 gpu_test_dir_.AppendASCII("webgl.html"), "query=kill")); 80 observer.Wait(); 81 82 content::WindowedNotificationObserver infobar_added( 83 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED, 84 content::NotificationService::AllSources()); 85 SimulateGPUCrash(browser()); 86 infobar_added.Wait(); 87 EXPECT_EQ(1u, 88 InfoBarService::FromWebContents( 89 browser()->tab_strip_model()->GetActiveWebContents())-> 90 infobar_count()); 91 } 92 93 IN_PROC_BROWSER_TEST_F(WebGLInfobarTest, ContextLossInfobarReload) { 94 #if defined(OS_WIN) && defined(USE_ASH) 95 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 96 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 97 return; 98 #endif 99 100 if (gpu::GPUTestBotConfig::CurrentConfigMatches("XP")) 101 return; 102 103 content::DOMMessageQueue message_queue; 104 105 // Load page and wait for it to load. 106 content::WindowedNotificationObserver observer( 107 content::NOTIFICATION_LOAD_STOP, 108 content::NotificationService::AllSources()); 109 ui_test_utils::NavigateToURL( 110 browser(), 111 content::GetFileUrlWithQuery( 112 gpu_test_dir_.AppendASCII("webgl.html"), 113 "query=kill_after_notification")); 114 observer.Wait(); 115 116 std::string m; 117 ASSERT_TRUE(message_queue.WaitForMessage(&m)); 118 EXPECT_EQ("\"LOADED\"", m); 119 120 message_queue.ClearQueue(); 121 122 content::WindowedNotificationObserver infobar_added( 123 chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED, 124 content::NotificationService::AllSources()); 125 SimulateGPUCrash(browser()); 126 infobar_added.Wait(); 127 InfoBarService* infobar_service = InfoBarService::FromWebContents( 128 browser()->tab_strip_model()->GetActiveWebContents()); 129 ASSERT_EQ(1u, infobar_service->infobar_count()); 130 InfoBarDelegate* delegate = infobar_service->infobar_at(0); 131 ASSERT_TRUE(delegate->AsThreeDAPIInfoBarDelegate()); 132 delegate->AsConfirmInfoBarDelegate()->Cancel(); 133 134 // The page should reload and another message sent to the 135 // DomAutomationController. 136 m.clear(); 137 ASSERT_TRUE(message_queue.WaitForMessage(&m)); 138 EXPECT_EQ("\"LOADED\"", m); 139 } 140 141 // There isn't any point in adding a test which calls Accept() on the 142 // ThreeDAPIInfoBarDelegate; doing so doesn't remove the infobar, and 143 // there's no concrete event that could be observed in response. 144