关于javascript:错误:无法捕获屏幕截图-使用protractor和Appium的Android混合应用

Error: Unable to capture screenshot - Android hybrid app using Protractor and Appium

我正在使用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) {...代码来自官方protractor页面和其他可靠来源)。

我的规格

  • 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


wdBrowser.context('NATIVE_APP')对我不起作用。
拍了照片,但随后每个测试用例都失败了。
我找到了截屏的另一种解决方案。
我用以下代码替换了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);
      }
  });

我遇到以下问题:

  • 在我想将其截图之前,尚未创建该屏幕截图。
  • 屏幕快照文件在提取期间存在,但仅提取了0kb文件。
    因此,在抓取屏幕截图并将其拉到计算机之间,我实现了一秒钟的睡眠。

  • 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。