【问题标题】:Error: Unable to capture screenshot - Android hybrid app using Protractor and Appium错误:无法捕获屏幕截图 - 使用 Protractor 和 Appium 的 Android 混合应用程序
【发布时间】:2017-06-09 11:18:59
【问题描述】:

我正在使用 Protractor 进行测试自动化。我使用 Protractor (jasmine) 和 Appium 完美地测试了我的混合 Android 应用程序。但我无法让browser.takeScreenshot() 功能正常工作。所有其他测试都像单击按钮或类似的东西一样完美地工作。 我创建了一个新的空白应用程序以排除插件导致此问题。没有 Cordova 插件会阻止屏幕截图功能,我可以使用 android 设备本身进行屏幕截图。
我尝试了这个StackOverflow 答案(还有更多),但没有成功(似乎没有人遇到过这个问题)。
我还使用protractor-jasmin2-screenshot-reporter 来排除我的截图代码不起作用,但我得到了相同的结果。有趣的是,当我使用 browserName: 'Chrome' 并让测试在我的设备上打开 Chrome 并调用 www.google.com 并让我的代码截屏时,它工作正常。仅在我的混合应用程序中,截屏不起作用。
browser.takeScreenshot().then(function (png) {...代码来自官方量角器页面和其他可靠来源)。

我的规格

  • 量角器:5.0.0
  • Appium(桌面客户端):1.4.16.1(最新版本)
  • Windows 10 企业版 64 位
  • Chrome 驱动程序:2.27(最新版本)
  • 角度:1.5.3
  • Node.js:6.9.1
  • Android:6.0.1 和 4.4.2(Galaxy S6 和 Alcatel Pixi)
  • 科尔多瓦 6.4.0

我的量角器 config.js

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

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)

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)

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\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\error.js:27:5)
        at Object.checkLegacyResponse (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\error.js:505:15)
        at parseHttpResponse (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\http.js:509:13)
        at doSend.then.response (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_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\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\webdriver.js:816:17)
        at WebDriver.takeScreenshot (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\webdriver.js:1092:17)
        at ProtractorBrowser.to.(anonymous function) [as takeScreenshot] (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\lib\browser.ts:94:25)
        at Object.<anonymous> (C:\Projekte\WifiWizardTestApp\tests\browse.spec.js:14:17)
        at C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:98:15
        at new ManagedPromise (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:1067:7)
        at controlFlowExecute (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:87:18)
        at TaskQueue.execute_ (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2970:14)
        at TaskQueue.executeNext_ (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2953:27)
        at asyncRun (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2813:27)
    From: Task: Run it("should be able to take a screenshot") in control flow
        at Object.<anonymous> (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:86:14)
    From asynchronous test:
    Error
        at Suite.<anonymous> (C:\Projekte\WifiWizardTestApp\tests\browse.spec.js:8:5)
        at Object.<anonymous> (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\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\error.js:27:5)
        at Object.checkLegacyResponse (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\error.js:505:15)
        at parseHttpResponse (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\http.js:509:13)
        at doSend.then.response (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_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\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\webdriver.js:816:17)
        at WebDriver.takeScreenshot (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\webdriver.js:1092:17)
        at ProtractorBrowser.to.(anonymous function) [as takeScreenshot] (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\lib\browser.ts:94:25)
        at Object.<anonymous> (C:\Projekte\WifiWizardTestApp\tests\browse.spec.js:26:17)
        at C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:102:25
        at new ManagedPromise (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:1067:7)
        at controlFlowExecute (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:87:18)
        at TaskQueue.execute_ (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2970:14)
        at TaskQueue.executeNext_ (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\selenium-webdriver\lib\promise.js:2953:27)
        at asyncRun (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_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.<anonymous> (C:\Users\mkaiser\AppData\Roaming\npm\node_modules\protractor\node_modules\jasminewd2\index.js:86:14)
    From asynchronous test:
    Error
        at Suite.<anonymous> (C:\Projekte\WifiWizardTestApp\tests\browse.spec.js:24:5)
        at Object.<anonymous> (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

【问题讨论】:

  • 谢谢@SakshiSingla。我已经解决了这个问题。有趣的是,每次我执行测试时,屏幕截图都会失败。我测试了 3 种不同的 Chrome 驱动程序(2.9、2.12、2.27),每次都得到相同的结果:(

标签: javascript android selenium-webdriver protractor appium


【解决方案1】:
    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 日志中获取您的 webview 名称/ID。

【讨论】:

    【解决方案2】:


    wdBrowser.context('NATIVE_APP') 对我不起作用。
    它拍了照片,但之后每个测试用例都失败了。

    我找到了另一种截屏解决方案。
    我用以下代码替换了 takeScreenshots() 方法:

      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. 拉取时截图文件存在,但只拉取0kb文件。 因此,我在截屏和将其拉入计算机之间实现了一秒钟的睡眠。

    【讨论】:

    • 你应该使用“browser.pause()”或“driver.pause()”而不是while块来等待一段时间。
    猜你喜欢
    • 2014-05-31
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 2017-06-25
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    • 2020-12-22
    相关资源
    最近更新 更多