Error: Unable to capture screenshot - Android hybrid app using Protractor and Appium
我正在使用protractor进行自动化测试。我使用protractor(jasmine)和Appium完美地测试了我的混合Android应用程序。但是我不能使
我创建了一个新的空白应用程序,以排除导致该问题的插件。没有Cordova插件可以阻止屏幕截图功能,并且我能够使用android设备本身进行屏幕截图。
我尝试了这个StackOverflow答案(还有更多),但是没有成功(似乎没有人遇到过这个问题)。
我还使用了protractor-jasmin2-screenshot-reporter来排除,我截屏的代码无法正常工作,但是得到了相同的结果。有趣的是,当我使用browserName:'Chrome'并让测试在设备上打开Chrome并调用www.google.com并让我的代码截图时,它可以正常工作。仅在我的混合应用程序中,截屏不起作用。
(
我的规格
- protractor:5.0.0
- Appium(台式机客户端):1.4.16.1(最新版本)
- Windows 10企业版64位
- Chromedriver:2.27(最新版本)
- angular:1.5.3
- Node.js:6.9.1
- Android:6.0.1和4.4.2(Galaxy S6和Alcatel Pixi)
- 科尔多瓦6.4.0
我的protractorconfig.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | exports.config = { seleniumAddress : 'http://localhost:4723/wd/hub', // Reference: https://github.com/appium/sample-code/blob/master/sample-code/examples/node/helpers/caps.js capabilities : { // needed by local appium platformVersion : '', platformName : '', deviceName : '', // needed by protractor browserName : '', autoWebview : true, // CHANGE THIS TO YOUR ABSOLUTE PATH OR SET IT IN APPIUM CLIENT app : 'C:/Projekte/WifiWizardTestApp/platforms/android/build/outputs/apk/android-debug.apk', newCommandTimeout : 60 }, //needed for local appium baseUrl : 'http://localhost:8080', //configuring wd in onPrepare //wdBridge helps to bridge wd driver with other selenium clients //See https://github.com/sebv/wd-bridge/blob/master/README.md onPrepare : function () { var wd = require('wd'); var protractor = require('protractor'); var wdBridge = require('wd-bridge')(protractor, wd); wdBridge.initFromProtractor(exports.config); }, }; |
我的test.spec.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | var fs = require('fs'); describe('Testing the browse state', function () { it('should be able to take a screenshot', function (done) { browser.sleep(2000); browser.takeScreenshot().then(function (png) { console.log('browser.takeScreenshot()'); var stream = fs.createWriteStream('screenshot.png'); stream.write(new Buffer(png, 'base64')); stream.end(); done(); }); }); it('should be able to take an other screenshot', function () { browser.takeScreenshot().then(function (png) { console.log('browser.takeScreenshot()'); var stream = fs.createWriteStream('screenshot2.png'); stream.write(new Buffer(png, 'base64')); stream.end(); }); }); }); |
我的控制台输出(Android 6.0.1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | C:\\Projekte\\WifiWizardTestApp>protractor protractor.config.js --specs tests/browse.spec.js [09:27:44] I/hosted - Using the selenium server at http://localhost:4723/wd/hub [09:27:44] I/launcher - Running 1 instances of WebDriver Started A Jasmine spec timed out. Resetting the WebDriver Control Flow. FA Jasmine spec timed out. Resetting the WebDriver Control Flow. F Failures: 1) Testing the browse state should be able to take a screenshot Message: Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. Stack: Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. at ontimeout (timers.js:365:14) at tryOnTimeout (timers.js:237:5) at Timer.listOnTimeout (timers.js:207:5) 2) Testing the browse state should be able to take an other screenshot Message: Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. Stack: Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL. at ontimeout (timers.js:365:14) at tryOnTimeout (timers.js:237:5) at Timer.listOnTimeout (timers.js:207:5) 2 specs, 2 failures Finished in 60.04 seconds |
我的控制台输出(Android 4.4.2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | C:\\Projekte\\WifiWizardTestApp>protractor protractor.config.js --specs tests/browse.spec.js [15:15:49] I/hosted - Using the selenium server at http://localhost:4723/wd/hub [15:15:49] I/launcher - Running 1 instances of WebDriver Started FF Failures: 1) Testing the browse state should be able to take a screenshot Message: Failed: unknown error: unhandled inspector error: {"code":-32603,"message":"Unable to capture screenshot"} (Session info: webview=30.0.0.0) (Driver info: chromedriver=2.27.440174 (e97a722caafc2d3a8b807ee115bfb307f7d2cfd9),platform=Windows NT 10.0.10586 x86_64) Stack: WebDriverError: unknown error: unhandled inspector error: {"code":-32603,"message":"Unable to capture screenshot"} (Session info: webview=30.0.0.0) (Driver info: chromedriver=2.27.440174 (e97a722caafc2d3a8b807ee115bfb307f7d2cfd9),platform=Windows NT 10.0.10586 x86_64) at WebDriverError (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\error.js:27:5) at Object.checkLegacyResponse (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\error.js:505:15) at parseHttpResponse (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\http.js:509:13) at doSend.then.response (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\http.js:440:13) at process._tickCallback (internal/process/next_tick.js:103:7) From: Task: WebDriver.takeScreenshot() at WebDriver.schedule (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\webdriver.js:816:17) at WebDriver.takeScreenshot (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\webdriver.js:1092:17) at ProtractorBrowser.to.(anonymous function) [as takeScreenshot] (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\\lib\\browser.ts:94:25) at Object. (C:\\Projekte\\WifiWizardTestApp\\tests\\browse.spec.js:14:17) at C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\jasminewd2\\index.js:98:15 at new ManagedPromise (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\promise.js:1067:7) at controlFlowExecute (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\jasminewd2\\index.js:87:18) at TaskQueue.execute_ (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\promise.js:2970:14) at TaskQueue.executeNext_ (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\promise.js:2953:27) at asyncRun (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\promise.js:2813:27) From: Task: Run it("should be able to take a screenshot") in control flow at Object. (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\jasminewd2\\index.js:86:14) From asynchronous test: Error at Suite. (C:\\Projekte\\WifiWizardTestApp\\tests\\browse.spec.js:8:5) at Object. (C:\\Projekte\\WifiWizardTestApp\\tests\\browse.spec.js:4:1) at Module._compile (module.js:570:32) at Object.Module._extensions..js (module.js:579:10) at Module.load (module.js:487:32) at tryModuleLoad (module.js:446:12) 2) Testing the browse state should be able to take an other screenshot Message: Failed: unknown error: unhandled inspector error: {"code":-32603,"message":"Unable to capture screenshot"} (Session info: webview=30.0.0.0) (Driver info: chromedriver=2.27.440174 (e97a722caafc2d3a8b807ee115bfb307f7d2cfd9),platform=Windows NT 10.0.10586 x86_64) Stack: WebDriverError: unknown error: unhandled inspector error: {"code":-32603,"message":"Unable to capture screenshot"} (Session info: webview=30.0.0.0) (Driver info: chromedriver=2.27.440174 (e97a722caafc2d3a8b807ee115bfb307f7d2cfd9),platform=Windows NT 10.0.10586 x86_64) at WebDriverError (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\error.js:27:5) at Object.checkLegacyResponse (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\error.js:505:15) at parseHttpResponse (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\http.js:509:13) at doSend.then.response (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\http.js:440:13) at process._tickCallback (internal/process/next_tick.js:103:7) From: Task: WebDriver.takeScreenshot() at WebDriver.schedule (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\webdriver.js:816:17) at WebDriver.takeScreenshot (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\webdriver.js:1092:17) at ProtractorBrowser.to.(anonymous function) [as takeScreenshot] (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\\lib\\browser.ts:94:25) at Object. (C:\\Projekte\\WifiWizardTestApp\\tests\\browse.spec.js:26:17) at C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\jasminewd2\\index.js:102:25 at new ManagedPromise (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\promise.js:1067:7) at controlFlowExecute (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\jasminewd2\\index.js:87:18) at TaskQueue.execute_ (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\promise.js:2970:14) at TaskQueue.executeNext_ (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\promise.js:2953:27) at asyncRun (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\selenium-webdriver\\lib\\promise.js:2860:25) From: Task: Run it("should be able to take an other screenshot") in control flow at Object. (C:\\Users\\mkaiser\\AppData\ oaming\ pm\ ode_modules\\protractor\ ode_modules\\jasminewd2\\index.js:86:14) From asynchronous test: Error at Suite. (C:\\Projekte\\WifiWizardTestApp\\tests\\browse.spec.js:24:5) at Object. (C:\\Projekte\\WifiWizardTestApp\\tests\\browse.spec.js:4:1) at Module._compile (module.js:570:32) at Object.Module._extensions..js (module.js:579:10) at Module.load (module.js:487:32) at tryModuleLoad (module.js:446:12) 2 specs, 2 failures Finished in 2.258 seconds [15:17:49] I/launcher - 0 instance(s) of WebDriver still running [15:17:49] I/launcher - #01 failed 2 test(s) [15:17:49] I/launcher - overall: 2 failed spec(s) [15:17:49] E/launcher - Process exited with error code 1 |
拍了照片,但随后每个测试用例都失败了。
我找到了截屏的另一种解决方案。
我用以下代码替换了takeScreenshots()方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | var exec = require('child_process').exec; exec('adb shell /system/bin/screencap -p /sdcard/' + filename); // Take a screenshot and store it on the internal storage. // Wait until the screenshot is created on android var date = new Date(); var curDate = null; do { curDate = new Date(); } while (curDate - date < 1000); var command = 'adb pull /sdcard/'+ filename + ' ' + screenshotPath; exec(command, function (err, stdout, stderr) { // Copy the screenshot from the internal storage to the local computer. if(err){ console.error('The screenshot could not be copied from the ANDROID device: ' + stdout); console.log('The screenshot is stored on the ANDROID device with the name: ' + filename); } }); |
我遇到以下问题:
因此,在抓取屏幕截图并将其拉到计算机之间,我实现了一秒钟的睡眠。
1 2 3 4 5 6 7 8 9 10 | wdBrowser.context('NATIVE_APP').then(() => { browser.takeScreenshot().then(function (png) { console.log('browser.takeScreenshot()'); var stream = fs.createWriteStream('screenshot.png'); stream.write(new Buffer(png, 'base64')); stream.end(function(){ wdBrowser.context(<Your webview>).then(done); }); }) }); |
其中wdBrowser是由wdBridge设置的全局变量。应该可以工作-遇到类似的问题(无法拍摄屏幕截图,但没有像您一样的错误消息)
您可以从appium日志中获取您的网络视图名称/ id。