OLD | NEW |
1 // tabs api test | 1 // tabs api test |
2 // browser_tests.exe --gtest_filter=ExtensionApiTest.CaptureVisibleTab | 2 // browser_tests.exe --gtest_filter=ExtensionApiTest.CaptureVisibleTab |
3 | 3 |
4 var pass = chrome.test.callbackPass; | 4 var pass = chrome.test.callbackPass; |
5 var assertEq = chrome.test.assertEq; | 5 var assertEq = chrome.test.assertEq; |
6 var assertTrue = chrome.test.assertTrue; | 6 var assertTrue = chrome.test.assertTrue; |
7 | 7 |
8 var kWidth = 400; | 8 var kWidth = 400; |
9 var kHeight = 400; | 9 var kHeight = 400; |
10 | 10 |
11 function pageUrl(base) { | 11 function pageUrl(base) { |
12 return chrome.extension.getURL(base + ".html"); | 12 return chrome.extension.getURL(base + '.html'); |
13 } | 13 } |
14 | 14 |
15 function testAllPixelsAreExpectedColor(imgUrl, color) { | 15 function getAllPixels(imgUrl, callbackFn) { |
16 assertEq("string", typeof(imgUrl)); | 16 assertEq('string', typeof(imgUrl)); |
17 var img = new Image(); | 17 var img = new Image(); |
18 img.width = kWidth; | 18 img.width = kWidth; |
19 img.height = kHeight; | 19 img.height = kHeight; |
20 img.src = imgUrl; | 20 img.src = imgUrl; |
21 img.onload = pass(function() { | 21 img.onload = pass(function() { |
22 var canvas = document.createElement("canvas"); | 22 var canvas = document.createElement('canvas'); |
23 | 23 |
24 // Comparing pixels is slow enough to hit timeouts. Compare | 24 // Comparing pixels is slow enough to hit timeouts. Compare |
25 // a 10x10 region. | 25 // a 10x10 region. |
26 canvas.setAttribute('width', 10); | 26 canvas.setAttribute('width', 10); |
27 canvas.setAttribute('height', 10); | 27 canvas.setAttribute('height', 10); |
28 var context = canvas.getContext('2d'); | 28 var context = canvas.getContext('2d'); |
29 context.drawImage(img, 0, 0, 10, 10); | 29 context.drawImage(img, 0, 0, 10, 10); |
30 | 30 |
31 var imageData = context.getImageData(1, 1, 9, 9).data; | 31 var imageData = context.getImageData(1, 1, 9, 9).data; |
32 | 32 |
| 33 var pixelColors = []; |
| 34 for (var i = 0, n = imageData.length; i < n; i += 4) { |
| 35 pixelColors.push([imageData[i+0], |
| 36 imageData[i+1], |
| 37 imageData[i+2], |
| 38 imageData[i+3]].join(',')); |
| 39 } |
| 40 |
| 41 callbackFn(pixelColors); |
| 42 }); |
| 43 } |
| 44 |
| 45 function testAllPixelsAreExpectedColor(imgUrl, expectedColor) { |
| 46 getAllPixels(imgUrl, function(pixelColors) { |
33 var badPixels = []; | 47 var badPixels = []; |
34 | 48 for (var i = 0, ie = pixelColors.length; i < ie; ++i) { |
35 for (var i = 0, n = imageData.length; i < n; i += 4) { | 49 if (pixelColors[i] != expectedColor) { |
36 if (color[0] != imageData[i+0] || | 50 badPixels.push({'i': i, |
37 color[1] != imageData[i+1] || | 51 'color': pixelColors[i] |
38 color[2] != imageData[i+2] || | |
39 color[3] != imageData[i+3] ) { | |
40 badPixels.push({"i": i, | |
41 "color": [imageData[i+0], imageData[i+1], | |
42 imageData[i+2], imageData[i+3]] | |
43 }); | 52 }); |
44 } | 53 } |
45 } | 54 } |
46 assertEq("[]", JSON.stringify(badPixels, null, 2)) | 55 assertEq('[]', JSON.stringify(badPixels, null, 2)); |
47 }); | 56 }); |
48 } | 57 } |
49 | 58 |
| 59 // Build a count of the number of times the colors in |
| 60 // |expectedColors| occur in the image at |imgUrl|. |
| 61 function countPixelsWithColors(imgUrl, expectedColors, callback) { |
| 62 colorCounts = new Array(expectedColors.length); |
| 63 for (var i = 0; i < expectedColors.length; ++i) { |
| 64 colorCounts[i] = 0; |
| 65 } |
| 66 |
| 67 getAllPixels(imgUrl, function(pixelColors) { |
| 68 for (var i = 0, ie = pixelColors.length; i < ie; ++i) { |
| 69 var colorIdx = expectedColors.indexOf(pixelColors[i]); |
| 70 if (colorIdx != -1) |
| 71 colorCounts[colorIdx]++; |
| 72 } |
| 73 callback(colorCounts, // Mapping from color to # pixels. |
| 74 pixelColors.length); // Total pixels examined. |
| 75 }); |
| 76 } |
| 77 |
50 // Globals used to allow a test to read data from a previous test. | 78 // Globals used to allow a test to read data from a previous test. |
51 var blackImageUrl; | 79 var blackImageUrl; |
52 var whiteImageUrl; | 80 var whiteImageUrl; |
53 | 81 |
54 chrome.test.runTests([ | 82 chrome.test.runTests([ |
55 // Open a window with one tab, take a snapshot. | 83 // Open a window with one tab, take a snapshot. |
56 function captureVisibleTabWhiteImage() { | 84 function captureVisibleTabWhiteImage() { |
57 // Keep the resulting image small by making the window small. | 85 // Keep the resulting image small by making the window small. |
58 createWindow([pageUrl("white")], {"width": kWidth, "height": kHeight}, | 86 createWindow([pageUrl('white')], {'width': kWidth, 'height': kHeight}, |
59 pass(function(winId, tabIds) { | 87 pass(function(winId, tabIds) { |
60 waitForAllTabs(pass(function() { | 88 waitForAllTabs(pass(function() { |
61 chrome.tabs.getSelected(winId, pass(function(tab) { | 89 chrome.tabs.getSelected(winId, pass(function(tab) { |
62 assertEq('complete', tab.status); // waitForAllTabs ensures this. | 90 assertEq('complete', tab.status); // waitForAllTabs ensures this. |
63 chrome.tabs.captureVisibleTab(winId, pass(function(imgDataUrl) { | 91 chrome.tabs.captureVisibleTab(winId, pass(function(imgDataUrl) { |
64 // The URL should be a data URL with has a JPEG mime type. | 92 // The URL should be a data URL with has a JPEG mime type. |
65 assertEq("string", typeof(imgDataUrl)); | 93 assertEq('string', typeof(imgDataUrl)); |
66 assertEq('data:image/jpg;base64,', imgDataUrl.substr(0,22)); | 94 assertEq('data:image/jpg;base64,', imgDataUrl.substr(0,22)); |
67 whiteImageUrl = imgDataUrl; | 95 whiteImageUrl = imgDataUrl; |
68 | 96 |
69 testAllPixelsAreExpectedColor(whiteImageUrl, | 97 testAllPixelsAreExpectedColor(whiteImageUrl, |
70 [255, 255, 255, 255]); // White. | 98 '255,255,255,255'); // White. |
71 })); | 99 })); |
72 })); | 100 })); |
73 })); | 101 })); |
74 })); | 102 })); |
75 }, | 103 }, |
76 | 104 |
77 function captureVisibleTabBlackImage() { | 105 function captureVisibleTabBlackImage() { |
78 // Keep the resulting image small by making the window small. | 106 // Keep the resulting image small by making the window small. |
79 createWindow([pageUrl("black")], {"width": kWidth, "height": kHeight}, | 107 createWindow([pageUrl('black')], {'width': kWidth, 'height': kHeight}, |
80 pass(function(winId, tabIds) { | 108 pass(function(winId, tabIds) { |
81 waitForAllTabs(pass(function() { | 109 waitForAllTabs(pass(function() { |
82 chrome.tabs.getSelected(winId, pass(function(tab) { | 110 chrome.tabs.getSelected(winId, pass(function(tab) { |
83 assertEq('complete', tab.status); // waitForAllTabs ensures this. | 111 assertEq('complete', tab.status); // waitForAllTabs ensures this. |
84 chrome.tabs.captureVisibleTab(winId, pass(function(imgDataUrl) { | 112 chrome.tabs.captureVisibleTab(winId, pass(function(imgDataUrl) { |
85 // The URL should be a data URL with has a JPEG mime type. | 113 // The URL should be a data URL with has a JPEG mime type. |
86 assertEq("string", typeof(imgDataUrl)); | 114 assertEq('string', typeof(imgDataUrl)); |
87 assertEq('data:image/jpg;base64,', imgDataUrl.substr(0,22)); | 115 assertEq('data:image/jpg;base64,', imgDataUrl.substr(0,22)); |
88 blackImageUrl = imgDataUrl; | 116 blackImageUrl = imgDataUrl; |
89 | 117 |
90 // Check that previous capture was done. | 118 // Check that previous capture was done. |
91 assertEq('string', typeof(whiteImageUrl)); | 119 assertEq('string', typeof(whiteImageUrl)); |
92 | 120 |
93 assertTrue(whiteImageUrl != blackImageUrl); | 121 assertTrue(whiteImageUrl != blackImageUrl); |
94 | 122 |
95 testAllPixelsAreExpectedColor(blackImageUrl, | 123 testAllPixelsAreExpectedColor(blackImageUrl, |
96 [0, 0, 0, 255]); // Black. | 124 '0,0,0,255'); // Black. |
97 })); | 125 })); |
98 })); | 126 })); |
99 })); | 127 })); |
100 })); | 128 })); |
101 }, | 129 }, |
102 | 130 |
103 function captureVisibleTabRedPng() { | 131 function captureVisibleTabText() { |
104 // Keep the resulting image small by making the window small. | 132 // Keep the resulting image small by making the window small. |
105 createWindow([pageUrl("red")], {"width": kWidth, "height": kHeight}, | 133 createWindow([pageUrl('text')], {'width': kWidth, 'height': kHeight}, |
106 pass(function(winId, tabIds) { | 134 pass(function(winId, tabIds) { |
107 waitForAllTabs(pass(function() { | 135 waitForAllTabs(pass(function() { |
108 chrome.tabs.getSelected(winId, pass(function(tab) { | 136 chrome.tabs.getSelected(winId, pass(function(tab) { |
109 assertEq('complete', tab.status); // waitForAllTabs ensures this. | 137 assertEq('complete', tab.status); // waitForAllTabs ensures this. |
110 chrome.tabs.captureVisibleTab(winId, | 138 chrome.tabs.captureVisibleTab(winId, |
111 {"format": "png"}, | 139 {'format': 'png'}, |
112 pass(function(imgDataUrl) { | 140 pass(function(imgDataUrl) { |
113 // The URL should be a data URL with has a PNG mime type. | 141 // The URL should be a data URL with has a PNG mime type. |
114 assertEq("string", typeof(imgDataUrl)); | 142 assertEq('string', typeof(imgDataUrl)); |
115 assertEq('data:image/png;base64,', imgDataUrl.substr(0,22)); | 143 assertEq('data:image/png;base64,', imgDataUrl.substr(0,22)); |
116 | 144 |
117 // TODO(skerner): The pixel comparison test fails on XP. | 145 countPixelsWithColors( |
118 // Find out why. | 146 imgDataUrl, |
119 //testAllPixelsAreExpectedColor(imgDataUrl, | 147 ['255,255,255,255'], |
120 // [255, 0, 0, 255]); // Red. | 148 pass(function(colorCounts, totalPixelsChecked) { |
| 149 // Some pixels should not be white, because the text |
| 150 // is not white. Can't test for black because |
| 151 // antialiasing makes the pixels slightly different |
| 152 // on each display setting. |
| 153 |
| 154 // chrome.test.log(totalPixelsChecked); |
| 155 // chrome.test.log(colorCounts[0]); |
| 156 assertTrue(totalPixelsChecked != colorCounts[0]); |
| 157 })); |
121 })); | 158 })); |
122 })); | 159 })); |
123 })); | 160 })); |
124 })); | 161 })); |
125 } | 162 } |
126 ]); | 163 ]); |
OLD | NEW |