Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <string> | |
| 6 | |
| 5 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/stl_util.h" | |
| 6 #include "base/strings/string_piece.h" | 9 #include "base/strings/string_piece.h" |
| 7 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| 8 #include "chrome/browser/ui/browser.h" | 11 #include "chrome/browser/ui/browser.h" |
| 12 #include "chrome/browser/ui/browser_window.h" | |
| 9 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 13 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 10 #include "chrome/common/chrome_switches.h" | 14 #include "chrome/common/chrome_switches.h" |
| 11 #include "chrome/test/base/in_process_browser_test.h" | 15 #include "chrome/test/base/in_process_browser_test.h" |
| 16 #include "chrome/test/base/test_switches.h" | |
| 12 #include "chrome/test/base/ui_test_utils.h" | 17 #include "chrome/test/base/ui_test_utils.h" |
| 13 #include "components/ui/zoom/zoom_controller.h" | 18 #include "components/ui/zoom/zoom_controller.h" |
| 19 #include "content/public/browser/readback_types.h" | |
| 20 #include "content/public/browser/render_frame_host.h" | |
| 21 #include "content/public/browser/render_view_host.h" | |
| 22 #include "content/public/browser/render_widget_host.h" | |
| 14 #include "content/public/common/content_switches.h" | 23 #include "content/public/common/content_switches.h" |
| 15 #include "content/public/test/browser_test_utils.h" | 24 #include "content/public/test/browser_test_utils.h" |
| 16 #include "content/public/test/ppapi_test_utils.h" | 25 #include "content/public/test/ppapi_test_utils.h" |
| 17 #include "net/test/embedded_test_server/embedded_test_server.h" | 26 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 18 #include "net/test/embedded_test_server/http_request.h" | 27 #include "net/test/embedded_test_server/http_request.h" |
| 19 #include "net/test/embedded_test_server/http_response.h" | 28 #include "net/test/embedded_test_server/http_response.h" |
| 20 #include "ppapi/shared_impl/ppapi_switches.h" | 29 #include "ppapi/shared_impl/ppapi_switches.h" |
| 21 #include "third_party/WebKit/public/web/WebInputEvent.h" | 30 #include "third_party/WebKit/public/web/WebInputEvent.h" |
| 31 #include "third_party/skia/include/core/SkBitmap.h" | |
| 22 #include "ui/base/window_open_disposition.h" | 32 #include "ui/base/window_open_disposition.h" |
| 33 #include "ui/gfx/codec/png_codec.h" | |
| 23 #include "ui/gfx/geometry/point.h" | 34 #include "ui/gfx/geometry/point.h" |
| 35 #include "ui/gfx/screen.h" | |
| 24 | 36 |
| 25 namespace { | 37 namespace { |
| 26 | 38 |
| 39 // Use fixed browser dimensions for pixel tests. | |
| 40 const int kBrowserWidth = 600; | |
| 41 const int kBrowserHeight = 700; | |
| 42 | |
| 43 // Compare only a portion of the snapshots, as different platforms will | |
| 44 // capture different sized snapshots (due to differences in browser chrome). | |
| 45 const int kComparisonWidth = 500; | |
| 46 const int kComparisonHeight = 600; | |
| 47 | |
| 48 // Different platforms have slightly different pixel output, due to different | |
| 49 // graphics implementations. Slightly different pixels (in BGR space) are still | |
| 50 // counted as a matching pixel by this simple manhattan distance threshold. | |
| 51 const int kPixelManhattanDistanceTolerance = 8; | |
| 52 | |
| 27 std::string RunTestScript(base::StringPiece test_script, | 53 std::string RunTestScript(base::StringPiece test_script, |
| 28 content::WebContents* contents, | 54 content::WebContents* contents, |
| 29 const std::string& element_id) { | 55 const std::string& element_id) { |
| 30 std::string script = base::StringPrintf( | 56 std::string script = base::StringPrintf( |
| 31 "var plugin = window.document.getElementById('%s');" | 57 "var plugin = window.document.getElementById('%s');" |
| 32 "if (plugin === undefined ||" | 58 "if (plugin === undefined ||" |
| 33 " (plugin.nodeName !== 'OBJECT' && plugin.nodeName !== 'EMBED')) {" | 59 " (plugin.nodeName !== 'OBJECT' && plugin.nodeName !== 'EMBED')) {" |
| 34 " window.domAutomationController.send('error');" | 60 " window.domAutomationController.send('error');" |
| 35 "} else {" | 61 "} else {" |
| 36 " %s" | 62 " %s" |
| 37 "}", | 63 "}", |
| 38 element_id.c_str(), test_script.data()); | 64 element_id.c_str(), test_script.data()); |
| 39 std::string result; | 65 std::string result; |
| 40 EXPECT_TRUE( | 66 EXPECT_TRUE( |
| 41 content::ExecuteScriptAndExtractString(contents, script, &result)); | 67 content::ExecuteScriptAndExtractString(contents, script, &result)); |
| 42 return result; | 68 return result; |
| 43 } | 69 } |
| 44 | 70 |
| 45 // This also tests that we have JavaScript access to the underlying plugin. | 71 // This also tests that we have JavaScript access to the underlying plugin. |
| 46 bool PluginLoaded(content::WebContents* contents, const char* element_id) { | 72 bool PluginLoaded(content::WebContents* contents, |
| 73 const std::string& element_id) { | |
| 47 std::string result = RunTestScript( | 74 std::string result = RunTestScript( |
| 48 "if (plugin.postMessage === undefined) {" | 75 "if (plugin.postMessage === undefined) {" |
| 49 " window.domAutomationController.send('poster_only');" | 76 " window.domAutomationController.send('poster_only');" |
| 50 "} else {" | 77 "} else {" |
| 51 " window.domAutomationController.send('plugin_loaded');" | 78 " window.domAutomationController.send('plugin_loaded');" |
| 52 "}", | 79 "}", |
| 53 contents, element_id); | 80 contents, element_id); |
| 54 EXPECT_NE("error", result); | 81 EXPECT_NE("error", result); |
| 55 return result == "plugin_loaded"; | 82 return result == "plugin_loaded"; |
| 56 } | 83 } |
| 57 | 84 |
| 85 // Blocks until the placeholder is ready. | |
| 86 void WaitForPlaceholderReady(content::WebContents* contents, | |
| 87 const std::string& element_id) { | |
| 88 std::string result = RunTestScript( | |
| 89 "function handleEvent(event) {" | |
| 90 " if (event.data === 'placeholderReady') {" | |
| 91 " window.domAutomationController.send('ready');" | |
| 92 " plugin.removeEventListener('message', handleEvent);" | |
| 93 " }" | |
| 94 "}" | |
| 95 "plugin.addEventListener('message', handleEvent);" | |
| 96 "if (plugin.hasAttribute('placeholderReady')) {" | |
| 97 " window.domAutomationController.send('ready');" | |
| 98 " plugin.removeEventListener('message', handleEvent);" | |
| 99 "}", | |
| 100 contents, element_id); | |
| 101 ASSERT_EQ("ready", result); | |
| 102 } | |
| 103 | |
| 58 // Also waits for the placeholder UI overlay to finish loading. | 104 // Also waits for the placeholder UI overlay to finish loading. |
| 59 void VerifyPluginIsThrottled(content::WebContents* contents, | 105 void VerifyPluginIsThrottled(content::WebContents* contents, |
| 60 const char* element_id) { | 106 const std::string& element_id) { |
| 61 std::string result = RunTestScript( | 107 std::string result = RunTestScript( |
| 62 "function handleEvent(event) {" | 108 "function handleEvent(event) {" |
| 63 " if (event.data.isPeripheral && event.data.isThrottled && " | 109 " if (event.data.isPeripheral && event.data.isThrottled && " |
| 64 " event.data.isHiddenForPlaceholder) {" | 110 " event.data.isHiddenForPlaceholder) {" |
| 65 " window.domAutomationController.send('throttled');" | 111 " window.domAutomationController.send('throttled');" |
| 66 " plugin.removeEventListener('message', handleEvent);" | 112 " plugin.removeEventListener('message', handleEvent);" |
| 67 " }" | 113 " }" |
| 68 "}" | 114 "}" |
| 69 "plugin.addEventListener('message', handleEvent);" | 115 "plugin.addEventListener('message', handleEvent);" |
| 70 "if (plugin.postMessage !== undefined) {" | 116 "if (plugin.postMessage !== undefined) {" |
| 71 " plugin.postMessage('getPowerSaverStatus');" | 117 " plugin.postMessage('getPowerSaverStatus');" |
| 72 "}", | 118 "}", |
| 73 contents, element_id); | 119 contents, element_id); |
| 74 EXPECT_EQ("throttled", result); | 120 EXPECT_EQ("throttled", result); |
| 75 | 121 |
| 76 // Page should continue to have JavaScript access to all throttled plugins. | 122 // Page should continue to have JavaScript access to all throttled plugins. |
| 77 EXPECT_TRUE(PluginLoaded(contents, element_id)); | 123 EXPECT_TRUE(PluginLoaded(contents, element_id)); |
| 124 | |
| 125 WaitForPlaceholderReady(contents, element_id); | |
| 78 } | 126 } |
| 79 | 127 |
| 80 void VerifyPluginMarkedEssential(content::WebContents* contents, | 128 void VerifyPluginMarkedEssential(content::WebContents* contents, |
| 81 const char* element_id) { | 129 const std::string& element_id) { |
| 82 std::string result = RunTestScript( | 130 std::string result = RunTestScript( |
| 83 "function handleEvent(event) {" | 131 "function handleEvent(event) {" |
| 84 " if (event.data.isPeripheral === false) {" | 132 " if (event.data.isPeripheral === false) {" |
| 85 " window.domAutomationController.send('essential');" | 133 " window.domAutomationController.send('essential');" |
| 86 " plugin.removeEventListener('message', handleEvent);" | 134 " plugin.removeEventListener('message', handleEvent);" |
| 87 " }" | 135 " }" |
| 88 "}" | 136 "}" |
| 89 "plugin.addEventListener('message', handleEvent);" | 137 "plugin.addEventListener('message', handleEvent);" |
| 90 "if (plugin.postMessage !== undefined) {" | 138 "if (plugin.postMessage !== undefined) {" |
| 91 " plugin.postMessage('getPowerSaverStatus');" | 139 " plugin.postMessage('getPowerSaverStatus');" |
| 92 "}", | 140 "}", |
| 93 contents, element_id); | 141 contents, element_id); |
| 94 EXPECT_EQ("essential", result); | 142 EXPECT_EQ("essential", result); |
| 95 EXPECT_TRUE(PluginLoaded(contents, element_id)); | 143 EXPECT_TRUE(PluginLoaded(contents, element_id)); |
| 96 } | 144 } |
| 97 | 145 |
| 98 scoped_ptr<net::test_server::HttpResponse> RespondWithHTML( | 146 scoped_ptr<net::test_server::HttpResponse> RespondWithHTML( |
| 99 const std::string& html, | 147 const std::string& html, |
| 100 const net::test_server::HttpRequest& request) { | 148 const net::test_server::HttpRequest& request) { |
| 101 scoped_ptr<net::test_server::BasicHttpResponse> response( | 149 scoped_ptr<net::test_server::BasicHttpResponse> response( |
| 102 new net::test_server::BasicHttpResponse()); | 150 new net::test_server::BasicHttpResponse()); |
| 103 response->set_content_type("text/html"); | 151 response->set_content_type("text/html"); |
| 104 response->set_content(html); | 152 response->set_content(html); |
| 105 return response.Pass(); | 153 return response.Pass(); |
| 106 } | 154 } |
| 107 | 155 |
| 156 void VerifyVisualStateUpdated(const base::Closure& done_cb, | |
| 157 bool visual_state_updated) { | |
| 158 ASSERT_TRUE(visual_state_updated); | |
| 159 done_cb.Run(); | |
| 160 } | |
| 161 | |
| 162 bool SnapshotMatches(const base::FilePath& reference, const SkBitmap& bitmap) { | |
| 163 if (bitmap.width() < kComparisonWidth || | |
| 164 bitmap.height() < kComparisonHeight) { | |
| 165 return false; | |
| 166 } | |
| 167 | |
| 168 std::string reference_data; | |
| 169 if (!base::ReadFileToString(reference, &reference_data)) | |
| 170 return false; | |
| 171 | |
| 172 int w = 0; | |
| 173 int h = 0; | |
| 174 std::vector<unsigned char> decoded; | |
| 175 if (!gfx::PNGCodec::Decode( | |
| 176 reinterpret_cast<unsigned char*>(string_as_array(&reference_data)), | |
| 177 reference_data.size(), gfx::PNGCodec::FORMAT_BGRA, &decoded, &w, | |
| 178 &h)) { | |
| 179 return false; | |
| 180 } | |
| 181 | |
| 182 if (w < kComparisonWidth || h < kComparisonHeight) | |
| 183 return false; | |
| 184 | |
| 185 int32_t* ref_pixels = reinterpret_cast<int32_t*>(vector_as_array(&decoded)); | |
| 186 SkAutoLockPixels lock_image(bitmap); | |
| 187 int32_t* pixels = static_cast<int32_t*>(bitmap.getPixels()); | |
| 188 | |
| 189 int stride = bitmap.rowBytes(); | |
| 190 for (int y = 0; y < kComparisonHeight; ++y) { | |
| 191 for (int x = 0; x < kComparisonWidth; ++x) { | |
| 192 int32_t pixel = pixels[y * stride / sizeof(int32_t) + x]; | |
| 193 int pixel_b = pixel & 0xFF; | |
| 194 int pixel_g = (pixel >> 8) & 0xFF; | |
| 195 int pixel_r = (pixel >> 16) & 0xFF; | |
| 196 | |
| 197 int32_t ref_pixel = ref_pixels[y * w + x]; | |
| 198 int ref_pixel_b = ref_pixel & 0xFF; | |
| 199 int ref_pixel_g = (ref_pixel >> 8) & 0xFF; | |
| 200 int ref_pixel_r = (ref_pixel >> 16) & 0xFF; | |
| 201 | |
| 202 int manhattan_distance = abs(pixel_b - ref_pixel_b) + | |
| 203 abs(pixel_g - ref_pixel_g) + | |
| 204 abs(pixel_r - ref_pixel_r); | |
| 205 | |
| 206 if (manhattan_distance > kPixelManhattanDistanceTolerance) | |
| 207 return false; | |
| 208 } | |
| 209 } | |
| 210 | |
| 211 return true; | |
| 212 } | |
| 213 | |
| 214 // |snapshot_matches| is set to true if the snapshot matches the reference and | |
| 215 // the test passes. Otherwise, set to false. | |
| 216 void CompareSnapshotToReference(const base::FilePath& reference, | |
| 217 bool* snapshot_matches, | |
| 218 const base::Closure& done_cb, | |
| 219 const SkBitmap& bitmap, | |
| 220 content::ReadbackResponse response) { | |
| 221 DCHECK(snapshot_matches); | |
| 222 if (response != content::READBACK_SUCCESS) { | |
| 223 *snapshot_matches = false; | |
| 224 done_cb.Run(); | |
| 225 return; | |
| 226 } | |
| 227 | |
| 228 *snapshot_matches = SnapshotMatches(reference, bitmap); | |
| 229 | |
| 230 // When rebaselining the pixel test, the test will fail, and we will | |
| 231 // overwrite the reference file. On the next try through, the test will then | |
| 232 // pass, since we just overwrote the reference file. A bit wonky. | |
| 233 if (!(*snapshot_matches) && | |
| 234 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 235 switches::kRebaselinePixelTests)) { | |
| 236 SkBitmap clipped_bitmap; | |
| 237 bitmap.extractSubset(&clipped_bitmap, | |
| 238 SkIRect::MakeWH(kComparisonWidth, kComparisonHeight)); | |
| 239 std::vector<unsigned char> png_data; | |
| 240 gfx::PNGCodec::EncodeBGRASkBitmap(clipped_bitmap, false, &png_data); | |
|
Lei Zhang
2015/10/26 23:15:47
Check return result?
tommycli
2015/10/26 23:29:51
Done.
| |
| 241 base::WriteFile(reference, | |
|
Lei Zhang
2015/10/26 23:15:47
Also check return result?
tommycli
2015/10/26 23:29:51
Done.
| |
| 242 reinterpret_cast<const char*>(vector_as_array(&png_data)), | |
| 243 png_data.size()); | |
| 244 } | |
| 245 | |
| 246 done_cb.Run(); | |
| 247 } | |
| 248 | |
| 108 } // namespace | 249 } // namespace |
| 109 | 250 |
| 110 class PluginPowerSaverBrowserTest : public InProcessBrowserTest { | 251 class PluginPowerSaverBrowserTest : public InProcessBrowserTest { |
| 111 public: | 252 public: |
| 253 void SetUp() override { | |
| 254 EnablePixelOutput(); | |
| 255 InProcessBrowserTest::SetUp(); | |
| 256 } | |
| 257 | |
| 112 void SetUpOnMainThread() override { | 258 void SetUpOnMainThread() override { |
| 113 InProcessBrowserTest::SetUpOnMainThread(); | 259 InProcessBrowserTest::SetUpOnMainThread(); |
| 114 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | 260 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
| 261 | |
| 262 embedded_test_server()->ServeFilesFromDirectory( | |
| 263 ui_test_utils::GetTestFilePath( | |
| 264 base::FilePath(FILE_PATH_LITERAL("plugin_power_saver")), | |
| 265 base::FilePath())); | |
| 115 } | 266 } |
| 116 | 267 |
| 117 void SetUpCommandLine(base::CommandLine* command_line) override { | 268 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 118 command_line->AppendSwitch(switches::kEnablePluginPowerSaver); | 269 command_line->AppendSwitch(switches::kEnablePluginPowerSaver); |
| 119 command_line->AppendSwitch(switches::kEnablePepperTesting); | 270 command_line->AppendSwitch(switches::kEnablePepperTesting); |
| 120 command_line->AppendSwitch(switches::kEnablePluginPlaceholderTesting); | 271 command_line->AppendSwitch(switches::kEnablePluginPlaceholderTesting); |
| 121 command_line->AppendSwitchASCII( | 272 command_line->AppendSwitchASCII( |
| 122 switches::kOverridePluginPowerSaverForTesting, "ignore-list"); | 273 switches::kOverridePluginPowerSaverForTesting, "ignore-list"); |
| 123 | 274 |
| 124 ASSERT_TRUE(ppapi::RegisterPowerSaverTestPlugin(command_line)); | 275 ASSERT_TRUE(ppapi::RegisterPowerSaverTestPlugin(command_line)); |
| 125 } | 276 } |
| 126 | 277 |
| 127 protected: | 278 protected: |
| 128 void LoadHTML(const std::string& html) { | 279 void LoadHTML(const std::string& html) { |
| 280 gfx::Rect bounds(gfx::Rect(0, 0, kBrowserWidth, kBrowserHeight)); | |
| 281 gfx::Rect screen_bounds = | |
| 282 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().bounds(); | |
| 283 ASSERT_GT(screen_bounds.width(), kBrowserWidth); | |
| 284 ASSERT_GT(screen_bounds.height(), kBrowserHeight); | |
| 285 browser()->window()->SetBounds(bounds); | |
| 286 | |
| 129 ASSERT_TRUE(embedded_test_server()->Started()); | 287 ASSERT_TRUE(embedded_test_server()->Started()); |
| 130 embedded_test_server()->RegisterRequestHandler( | 288 embedded_test_server()->RegisterRequestHandler( |
| 131 base::Bind(&RespondWithHTML, html)); | 289 base::Bind(&RespondWithHTML, html)); |
| 132 ui_test_utils::NavigateToURL(browser(), embedded_test_server()->base_url()); | 290 ui_test_utils::NavigateToURL(browser(), embedded_test_server()->base_url()); |
| 133 EXPECT_TRUE(content::WaitForRenderFrameReady( | 291 EXPECT_TRUE(content::WaitForRenderFrameReady( |
| 134 GetActiveWebContents()->GetMainFrame())); | 292 GetActiveWebContents()->GetMainFrame())); |
| 135 } | 293 } |
| 136 | 294 |
| 137 content::WebContents* GetActiveWebContents() { | 295 content::WebContents* GetActiveWebContents() { |
| 138 return browser()->tab_strip_model()->GetActiveWebContents(); | 296 return browser()->tab_strip_model()->GetActiveWebContents(); |
| 139 } | 297 } |
| 140 | 298 |
| 141 // This sends a simulated click at |point| and waits for test plugin to send | 299 // This sends a simulated click at |point| and waits for test plugin to send |
| 142 // a status message indicating that it is essential. The test plugin sends a | 300 // a status message indicating that it is essential. The test plugin sends a |
| 143 // status message during: | 301 // status message during: |
| 144 // - Plugin creation, to handle a plugin freshly created from a poster. | 302 // - Plugin creation, to handle a plugin freshly created from a poster. |
| 145 // - Peripheral status change. | 303 // - Peripheral status change. |
| 146 // - In response to the explicit 'getPowerSaverStatus' request, in case the | 304 // - In response to the explicit 'getPowerSaverStatus' request, in case the |
| 147 // test has missed the above two events. | 305 // test has missed the above two events. |
| 148 void SimulateClickAndAwaitMarkedEssential(const char* element_id, | 306 void SimulateClickAndAwaitMarkedEssential(const std::string& element_id, |
| 149 const gfx::Point& point) { | 307 const gfx::Point& point) { |
| 150 // Waits for the placeholder to be ready to be clicked first. | 308 WaitForPlaceholderReady(GetActiveWebContents(), element_id); |
| 151 std::string result = RunTestScript( | |
| 152 "function handleEvent(event) {" | |
| 153 " if (event.data === 'placeholderLoaded') {" | |
| 154 " window.domAutomationController.send('ready');" | |
| 155 " plugin.removeEventListener('message', handleEvent);" | |
| 156 " }" | |
| 157 "}" | |
| 158 "plugin.addEventListener('message', handleEvent);" | |
| 159 "if (plugin.hasAttribute('placeholderLoaded')) {" | |
| 160 " window.domAutomationController.send('ready');" | |
| 161 " plugin.removeEventListener('message', handleEvent);" | |
| 162 "}", | |
| 163 GetActiveWebContents(), element_id); | |
| 164 ASSERT_EQ("ready", result); | |
| 165 | |
| 166 content::SimulateMouseClickAt(GetActiveWebContents(), 0 /* modifiers */, | 309 content::SimulateMouseClickAt(GetActiveWebContents(), 0 /* modifiers */, |
| 167 blink::WebMouseEvent::ButtonLeft, point); | 310 blink::WebMouseEvent::ButtonLeft, point); |
| 168 | 311 |
| 169 VerifyPluginMarkedEssential(GetActiveWebContents(), element_id); | 312 VerifyPluginMarkedEssential(GetActiveWebContents(), element_id); |
| 170 } | 313 } |
| 314 | |
| 315 // |element_id| must be an element on the foreground tab. | |
| 316 void VerifyPluginIsPosterOnly(const std::string& element_id) { | |
| 317 EXPECT_FALSE(PluginLoaded(GetActiveWebContents(), element_id)); | |
| 318 WaitForPlaceholderReady(GetActiveWebContents(), element_id); | |
| 319 } | |
| 320 | |
| 321 bool VerifySnapshot(const base::FilePath::StringType& expected_filename) { | |
| 322 base::FilePath reference = ui_test_utils::GetTestFilePath( | |
| 323 base::FilePath(FILE_PATH_LITERAL("plugin_power_saver")), | |
| 324 base::FilePath().Append(expected_filename)); | |
|
Lei Zhang
2015/10/26 23:15:47
Can't this be base::FilePath(expected_filename) no
tommycli
2015/10/26 23:29:51
Done.
| |
| 325 | |
| 326 GetActiveWebContents()->GetMainFrame()->InsertVisualStateCallback( | |
| 327 base::Bind(&VerifyVisualStateUpdated, | |
| 328 base::MessageLoop::QuitWhenIdleClosure())); | |
| 329 content::RunMessageLoop(); | |
| 330 | |
| 331 content::RenderWidgetHost* rwh = | |
| 332 GetActiveWebContents()->GetRenderViewHost()->GetWidget(); | |
| 333 | |
| 334 // When a widget is first shown, it can take some time before it is ready | |
| 335 // for copying from its backing store. This is a transient condition, and | |
| 336 // so it is not being treated as a test failure. | |
| 337 if (!rwh->CanCopyFromBackingStore()) | |
| 338 return false; | |
| 339 | |
| 340 bool snapshot_matches = false; | |
| 341 rwh->CopyFromBackingStore( | |
| 342 gfx::Rect(), gfx::Size(), | |
| 343 base::Bind(&CompareSnapshotToReference, reference, &snapshot_matches, | |
| 344 base::MessageLoop::QuitWhenIdleClosure()), | |
| 345 kN32_SkColorType); | |
| 346 | |
| 347 content::RunMessageLoop(); | |
| 348 | |
| 349 return snapshot_matches; | |
| 350 } | |
| 171 }; | 351 }; |
| 172 | 352 |
| 173 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, SmallSameOrigin) { | 353 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, SmallSameOrigin) { |
| 174 LoadHTML( | 354 LoadHTML( |
| 175 "<object id='plugin' data='fake.swf' " | 355 "<object id='plugin' data='fake.swf' " |
| 176 " type='application/x-ppapi-tests' width='400' height='100'>" | 356 " type='application/x-ppapi-tests' width='400' height='100'>" |
| 177 "</object>"); | 357 "</object>"); |
| 178 VerifyPluginMarkedEssential(GetActiveWebContents(), "plugin"); | 358 VerifyPluginMarkedEssential(GetActiveWebContents(), "plugin"); |
| 179 } | 359 } |
| 180 | 360 |
| 181 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, SmallCrossOrigin) { | 361 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, SmallCrossOrigin) { |
| 182 LoadHTML( | 362 LoadHTML( |
| 183 "<object id='plugin' data='http://otherorigin.com/fake.swf' " | 363 "<object id='plugin' data='http://otherorigin.com/fake.swf' " |
| 184 " type='application/x-ppapi-tests' width='400' height='100'>" | 364 " type='application/x-ppapi-tests' width='400' height='100'>" |
| 365 "</object>" | |
| 366 "<br>" | |
| 367 "<object id='plugin_poster' data='http://otherorigin.com/fake.swf' " | |
| 368 " type='application/x-ppapi-tests' width='400' height='100' " | |
| 369 " poster='click_me.png'>" | |
| 185 "</object>"); | 370 "</object>"); |
| 371 | |
| 186 VerifyPluginIsThrottled(GetActiveWebContents(), "plugin"); | 372 VerifyPluginIsThrottled(GetActiveWebContents(), "plugin"); |
| 373 VerifyPluginIsPosterOnly("plugin_poster"); | |
| 374 | |
| 375 EXPECT_TRUE( | |
| 376 VerifySnapshot(FILE_PATH_LITERAL("small_cross_origin_expected.png"))); | |
| 187 | 377 |
| 188 SimulateClickAndAwaitMarkedEssential("plugin", gfx::Point(50, 50)); | 378 SimulateClickAndAwaitMarkedEssential("plugin", gfx::Point(50, 50)); |
| 379 SimulateClickAndAwaitMarkedEssential("plugin_poster", gfx::Point(50, 150)); | |
| 189 } | 380 } |
| 190 | 381 |
| 191 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, LargeCrossOrigin) { | 382 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, LargeCrossOrigin) { |
| 192 LoadHTML( | 383 LoadHTML( |
| 193 "<object id='large' data='http://otherorigin.com/fake.swf' " | 384 "<object id='large' data='http://otherorigin.com/fake.swf' " |
| 194 " type='application/x-ppapi-tests' width='400' height='500'>" | 385 " type='application/x-ppapi-tests' width='400' height='500'>" |
| 195 "</object>" | 386 "</object>" |
| 196 "<object id='medium_16_9' data='http://otherorigin.com/fake.swf' " | 387 "<object id='medium_16_9' data='http://otherorigin.com/fake.swf' " |
| 197 " type='application/x-ppapi-tests' width='480' height='270'>" | 388 " type='application/x-ppapi-tests' width='480' height='270'>" |
| 198 "</object>"); | 389 "</object>"); |
| 199 VerifyPluginMarkedEssential(GetActiveWebContents(), "large"); | 390 VerifyPluginMarkedEssential(GetActiveWebContents(), "large"); |
| 200 VerifyPluginMarkedEssential(GetActiveWebContents(), "medium_16_9"); | 391 VerifyPluginMarkedEssential(GetActiveWebContents(), "medium_16_9"); |
| 201 } | 392 } |
| 202 | 393 |
| 203 // Test extremely flaky, see https://crbug.com/547224 | 394 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, SmallerThanPlayIcon) { |
|
Lei Zhang
2015/10/26 23:15:47
So the flakiness should be fixed by this too?
tommycli
2015/10/26 23:29:51
Broken out into separate patch here: https://coder
| |
| 204 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, | 395 LoadHTML( |
| 205 DISABLED_LargePluginsPeripheralWhenPosterSpecified) { | 396 "<object id='plugin_16' type='application/x-ppapi-tests' " |
| 397 " width='16' height='16'></object>" | |
| 398 "<object id='plugin_32' type='application/x-ppapi-tests' " | |
| 399 " width='32' height='32'></object>" | |
| 400 "<object id='plugin_16_64' type='application/x-ppapi-tests' " | |
| 401 " width='16' height='64'></object>" | |
| 402 "<object id='plugin_64_16' type='application/x-ppapi-tests' " | |
| 403 " width='64' height='16'></object>"); | |
| 404 | |
| 405 VerifyPluginIsThrottled(GetActiveWebContents(), "plugin_16"); | |
| 406 VerifyPluginIsThrottled(GetActiveWebContents(), "plugin_32"); | |
| 407 VerifyPluginIsThrottled(GetActiveWebContents(), "plugin_16_64"); | |
| 408 VerifyPluginIsThrottled(GetActiveWebContents(), "plugin_64_16"); | |
| 409 | |
| 410 EXPECT_TRUE( | |
| 411 VerifySnapshot(FILE_PATH_LITERAL("smaller_than_play_icon_expected.png"))); | |
| 412 } | |
| 413 | |
| 414 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, PosterTests) { | |
| 415 // This test simultaneously verifies the varied supported poster syntaxes, | |
| 416 // as well as verifies that the poster is rendered correctly with various | |
| 417 // mismatched aspect ratios and sizes, following the same rules as VIDEO. | |
| 206 LoadHTML( | 418 LoadHTML( |
| 207 "<object id='plugin_src' type='application/x-ppapi-tests' " | 419 "<object id='plugin_src' type='application/x-ppapi-tests' " |
| 208 " width='400' height='500' poster='snapshot1x.png'></object>" | 420 " width='100' height='100' poster='click_me.png'></object>" |
| 209 "<object id='plugin_srcset' type='application/x-ppapi-tests' " | 421 "<object id='plugin_srcset' type='application/x-ppapi-tests' " |
| 210 " width='400' height='500' " | 422 " width='100' height='100' " |
| 211 " poster='snapshot1x.png 1x, snapshot2x.png 2x'></object>" | 423 " poster='click_me.png 1x, click_me.png 2x'></object>" |
| 212 "<object id='plugin_legacy_syntax' type='application/x-ppapi-tests' " | 424 "<br>" |
| 213 " width='400' height='500'>" | 425 |
| 214 " <param name='poster' value='snapshot1x.png 1x, snapshot2x.png 2x'>" | 426 "<object id='plugin_poster_param' type='application/x-ppapi-tests' " |
| 427 " width='100' height='100'>" | |
| 428 " <param name='poster' value='click_me.png 1x, click_me.png 2x'>" | |
| 215 "</object>" | 429 "</object>" |
| 216 "<embed id='plugin_embed_src' type='application/x-ppapi-tests' " | 430 "<embed id='plugin_embed_src' type='application/x-ppapi-tests' " |
| 217 " width='400' height='500' poster='snapshot1x.png'></embed>" | 431 " width='100' height='100' poster='click_me.png'></embed>" |
| 218 "<embed id='plugin_embed_srcset' type='application/x-ppapi-tests' " | 432 "<embed id='plugin_embed_srcset' type='application/x-ppapi-tests' " |
| 219 " width='400' height='500'" | 433 " width='100' height='100'" |
| 220 " poster='snapshot1x.png 1x, snapshot2x.png 2x'></embed>"); | 434 " poster='click_me.png 1x, click_me.png 2x'></embed>" |
| 435 "<br>" | |
| 221 | 436 |
| 222 EXPECT_FALSE(PluginLoaded(GetActiveWebContents(), "plugin_src")); | 437 "<object id='poster_missing' type='application/x-ppapi-tests' " |
| 223 EXPECT_FALSE(PluginLoaded(GetActiveWebContents(), "plugin_srcset")); | 438 " width='100' height='100' poster='missing.png'></object>" |
| 224 EXPECT_FALSE(PluginLoaded(GetActiveWebContents(), "plugin_legacy_syntax")); | 439 "<object id='poster_too_small' type='application/x-ppapi-tests' " |
| 225 EXPECT_FALSE(PluginLoaded(GetActiveWebContents(), "plugin_embed_src")); | 440 " width='100' height='50' poster='click_me.png'></object>" |
| 226 EXPECT_FALSE(PluginLoaded(GetActiveWebContents(), "plugin_embed_srcset")); | 441 "<object id='poster_too_big' type='application/x-ppapi-tests' " |
| 442 " width='100' height='150' poster='click_me.png'></object>" | |
| 443 "<br>" | |
| 444 | |
| 445 "<object id='poster_16' type='application/x-ppapi-tests' " | |
| 446 " width='16' height='16' poster='click_me.png'></object>" | |
| 447 "<object id='poster_32' type='application/x-ppapi-tests' " | |
| 448 " width='32' height='32' poster='click_me.png'></object>" | |
| 449 "<object id='poster_16_64' type='application/x-ppapi-tests' " | |
| 450 " width='16' height='64' poster='click_me.png'></object>" | |
| 451 "<object id='poster_64_16' type='application/x-ppapi-tests' " | |
| 452 " width='64' height='16' poster='click_me.png'></object>" | |
| 453 "<br>" | |
| 454 | |
| 455 "<div id='container' " | |
| 456 " style='width: 400px; height: 100px; overflow: hidden;'>" | |
| 457 " <object id='poster_obscured' data='http://otherorigin.com/fake.swf' " | |
| 458 " type='application/x-ppapi-tests' width='400' height='500' " | |
| 459 " poster='click_me.png'>" | |
| 460 " </object>" | |
| 461 "</div>"); | |
| 462 | |
| 463 VerifyPluginIsPosterOnly("plugin_src"); | |
| 464 VerifyPluginIsPosterOnly("plugin_srcset"); | |
| 465 | |
| 466 VerifyPluginIsPosterOnly("plugin_poster_param"); | |
| 467 VerifyPluginIsPosterOnly("plugin_embed_src"); | |
| 468 VerifyPluginIsPosterOnly("plugin_embed_srcset"); | |
| 469 | |
| 470 VerifyPluginIsPosterOnly("poster_missing"); | |
| 471 VerifyPluginIsPosterOnly("poster_too_small"); | |
| 472 VerifyPluginIsPosterOnly("poster_too_big"); | |
| 473 | |
| 474 VerifyPluginIsPosterOnly("poster_16"); | |
| 475 VerifyPluginIsPosterOnly("poster_32"); | |
| 476 VerifyPluginIsPosterOnly("poster_16_64"); | |
| 477 VerifyPluginIsPosterOnly("poster_64_16"); | |
| 478 | |
| 479 VerifyPluginIsPosterOnly("poster_obscured"); | |
| 480 | |
| 481 EXPECT_TRUE(VerifySnapshot(FILE_PATH_LITERAL("poster_tests_expected.png"))); | |
| 227 } | 482 } |
| 228 | 483 |
| 229 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, LargePostersNotThrottled) { | 484 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, LargePostersNotThrottled) { |
| 230 // This test verifies that small posters are throttled, large posters are not, | 485 // This test verifies that small posters are throttled, large posters are not, |
| 231 // and that large posters can whitelist origins for other plugins. | 486 // and that large posters can whitelist origins for other plugins. |
| 232 LoadHTML( | 487 LoadHTML( |
| 233 "<object id='poster_small' data='http://a.com/fake.swf' " | 488 "<object id='poster_small' data='http://a.com/fake.swf' " |
| 234 " type='application/x-ppapi-tests' width='50' height='50' " | 489 " type='application/x-ppapi-tests' width='50' height='50' " |
| 235 " poster='click_me.png'></object>" | 490 " poster='click_me.png'></object>" |
| 236 "<object id='poster_whitelisted_origin' data='http://b.com/fake.swf' " | 491 "<object id='poster_whitelisted_origin' data='http://b.com/fake.swf' " |
| 237 " type='application/x-ppapi-tests' width='50' height='50' " | 492 " type='application/x-ppapi-tests' width='50' height='50' " |
| 238 " poster='click_me.png'></object>" | 493 " poster='click_me.png'></object>" |
| 239 "<object id='plugin_whitelisted_origin' data='http://b.com/fake.swf' " | 494 "<object id='plugin_whitelisted_origin' data='http://b.com/fake.swf' " |
| 240 " type='application/x-ppapi-tests' width='50' height='50'></object>" | 495 " type='application/x-ppapi-tests' width='50' height='50'></object>" |
| 241 "<br>" | 496 "<br>" |
| 242 "<object id='poster_large' data='http://b.com/fake.swf' " | 497 "<object id='poster_large' data='http://b.com/fake.swf' " |
| 243 " type='application/x-ppapi-tests' width='400' height='300' " | 498 " type='application/x-ppapi-tests' width='400' height='300' " |
| 244 " poster='click_me.png'></object>"); | 499 " poster='click_me.png'></object>"); |
| 245 | 500 |
| 246 EXPECT_FALSE(PluginLoaded(GetActiveWebContents(), "poster_small")); | 501 VerifyPluginIsPosterOnly("poster_small"); |
| 247 VerifyPluginMarkedEssential(GetActiveWebContents(), | 502 VerifyPluginMarkedEssential(GetActiveWebContents(), |
| 248 "plugin_whitelisted_origin"); | 503 "plugin_whitelisted_origin"); |
| 249 VerifyPluginMarkedEssential(GetActiveWebContents(), "poster_large"); | 504 VerifyPluginMarkedEssential(GetActiveWebContents(), "poster_large"); |
| 250 } | 505 } |
| 251 | 506 |
| 252 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, | 507 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, |
| 253 PluginMarkedEssentialAfterPosterClicked) { | 508 PluginMarkedEssentialAfterPosterClicked) { |
| 254 LoadHTML( | 509 LoadHTML( |
| 255 "<object id='plugin' type='application/x-ppapi-tests' " | 510 "<object id='plugin' type='application/x-ppapi-tests' " |
| 256 " width='400' height='100' poster='snapshot1x.png'></object>"); | 511 " width='400' height='100' poster='snapshot1x.png'></object>"); |
| 257 EXPECT_FALSE(PluginLoaded(GetActiveWebContents(), "plugin")); | 512 VerifyPluginIsPosterOnly("plugin"); |
| 258 | 513 |
| 259 SimulateClickAndAwaitMarkedEssential("plugin", gfx::Point(50, 50)); | 514 SimulateClickAndAwaitMarkedEssential("plugin", gfx::Point(50, 50)); |
| 260 } | 515 } |
| 261 | 516 |
| 262 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, OriginWhitelisting) { | 517 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, OriginWhitelisting) { |
| 263 LoadHTML( | 518 LoadHTML( |
| 264 "<object id='plugin_small' data='http://a.com/fake1.swf' " | 519 "<object id='plugin_small' data='http://a.com/fake1.swf' " |
| 265 " type='application/x-ppapi-tests' width='100' height='100'></object>" | 520 " type='application/x-ppapi-tests' width='100' height='100'></object>" |
| 266 "<object id='plugin_small_poster' data='http://a.com/fake1.swf' " | 521 "<object id='plugin_small_poster' data='http://a.com/fake1.swf' " |
| 267 " type='application/x-ppapi-tests' width='100' height='100' " | 522 " type='application/x-ppapi-tests' width='100' height='100' " |
| 268 " poster='click_me.png'></object>" | 523 " poster='click_me.png'></object>" |
| 269 "<object id='plugin_large' data='http://a.com/fake2.swf' " | 524 "<object id='plugin_large' data='http://a.com/fake2.swf' " |
| 270 " type='application/x-ppapi-tests' width='400' height='500'>" | 525 " type='application/x-ppapi-tests' width='400' height='500'>" |
| 271 "</object>"); | 526 "</object>"); |
| 272 VerifyPluginMarkedEssential(GetActiveWebContents(), "plugin_small"); | 527 VerifyPluginMarkedEssential(GetActiveWebContents(), "plugin_small"); |
| 273 VerifyPluginMarkedEssential(GetActiveWebContents(), "plugin_small_poster"); | 528 VerifyPluginMarkedEssential(GetActiveWebContents(), "plugin_small_poster"); |
| 274 VerifyPluginMarkedEssential(GetActiveWebContents(), "plugin_large"); | 529 VerifyPluginMarkedEssential(GetActiveWebContents(), "plugin_large"); |
| 275 } | 530 } |
| 276 | 531 |
| 277 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, LargeCrossOriginObscured) { | 532 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, LargeCrossOriginObscured) { |
| 278 LoadHTML( | 533 LoadHTML( |
| 279 "<div id='container' " | 534 "<div id='container' " |
| 280 " style='width: 400px; height: 100px; overflow: hidden;'>" | 535 " style='width: 100px; height: 400px; overflow: hidden;'>" |
| 281 " <object id='plugin' data='http://otherorigin.com/fake.swf' " | 536 " <object id='plugin' data='http://otherorigin.com/fake.swf' " |
| 282 " type='application/x-ppapi-tests' width='400' height='500'>" | 537 " type='application/x-ppapi-tests' width='400' height='500' " |
| 538 " style='float: right;'>" | |
| 283 " </object>" | 539 " </object>" |
| 284 "</div>"); | 540 "</div>"); |
| 285 VerifyPluginIsThrottled(GetActiveWebContents(), "plugin"); | 541 VerifyPluginIsThrottled(GetActiveWebContents(), "plugin"); |
| 542 EXPECT_TRUE(VerifySnapshot( | |
| 543 FILE_PATH_LITERAL("large_cross_origin_obscured_expected.png"))); | |
| 286 | 544 |
| 287 // Test that's unthrottled if it is unobscured. | 545 // Test that's unthrottled if it is unobscured. |
| 288 std::string script = | 546 std::string script = |
| 289 "var container = window.document.getElementById('container');" | 547 "var container = window.document.getElementById('container');" |
| 290 "container.setAttribute('style', 'width: 400px; height: 400px;');"; | 548 "container.setAttribute('style', 'width: 400px; height: 400px;');"; |
| 291 ASSERT_TRUE(content::ExecuteScript(GetActiveWebContents(), script)); | 549 ASSERT_TRUE(content::ExecuteScript(GetActiveWebContents(), script)); |
| 292 VerifyPluginMarkedEssential(GetActiveWebContents(), "plugin"); | 550 VerifyPluginMarkedEssential(GetActiveWebContents(), "plugin"); |
| 293 } | 551 } |
| 294 | 552 |
| 295 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, ExpandingSmallPlugin) { | 553 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, ExpandingSmallPlugin) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 | 591 |
| 334 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, ZoomIndependent) { | 592 IN_PROC_BROWSER_TEST_F(PluginPowerSaverBrowserTest, ZoomIndependent) { |
| 335 ui_zoom::ZoomController::FromWebContents(GetActiveWebContents()) | 593 ui_zoom::ZoomController::FromWebContents(GetActiveWebContents()) |
| 336 ->SetZoomLevel(4.0); | 594 ->SetZoomLevel(4.0); |
| 337 LoadHTML( | 595 LoadHTML( |
| 338 "<object id='plugin' data='http://otherorigin.com/fake.swf' " | 596 "<object id='plugin' data='http://otherorigin.com/fake.swf' " |
| 339 " type='application/x-ppapi-tests' width='400' height='200'>" | 597 " type='application/x-ppapi-tests' width='400' height='200'>" |
| 340 "</object>"); | 598 "</object>"); |
| 341 VerifyPluginIsThrottled(GetActiveWebContents(), "plugin"); | 599 VerifyPluginIsThrottled(GetActiveWebContents(), "plugin"); |
| 342 } | 600 } |
| OLD | NEW |