Issue: Unable to take screenshot - Android application with Protractor and Appium

I have been utilizing Protractor for my test automation needs. Despite successfully testing my hybrid Android application with Protractor (jasmine) and Appium, I am facing challenges with the browser.takeScreenshot() function. Interestingly, all other tests such as button clicks are functioning properly. To rule out any potential plugin-related issues, I created a new blank app. However, even without any Cordova Plugins, the screenshot feature is not working. Surprisingly, I can take screenshots using the device itself.
I have attempted various solutions from platforms like StackOverflow, but none of them have resolved the issue (and it appears that very few people have encountered this problem).
Furthermore, I employed the protractor-jasmin2-screenshot-reporter to check if there was an issue with the screenshot code in my tests, but the result remains consistent. Strangely, when running tests on Chrome by setting browserName: 'Chrome' and navigating to a webpage like www.google.com to capture a screenshot, it works perfectly fine. The problem only arises within my hybrid app environment.
(The

browser.takeScreenshot().then(function (png) {...
code is sourced from official protractor documents and other reputable sources).

Specifications

  • Protractor: 5.0.0
  • Appium (Desktop Client): 1.4.16.1 (latest version)
  • Windows 10 Enterprise 64 Bit
  • Chromedriver: 2.27 (latest version)
  • Angular: 1.5.3
  • Node.js: 6.9.1
  • Android: 6.0.1 and 4.4.2 (Galaxy S6 and Alcatel Pixi)
  • Cordova 6.4.0

Protractor Configuration (config.js)

exports.config = {

    seleniumAddress : 'http://localhost:4723/wd/hub',

    capabilities : {
        platformVersion : '',
        platformName : '',
        deviceName : '',
        browserName : '',
        autoWebview : true,
        app : 'C:/Projekte/WifiWizardTestApp/platforms/android/build/outputs/apk/android-debug.apk',
        newCommandTimeout : 60
    },

    baseUrl : 'http://localhost:8080',

    onPrepare : function () {
        var wd = require('wd');
        var protractor = require('protractor');
        var wdBridge = require('wd-bridge')(protractor, wd);
        wdBridge.initFromProtractor(exports.config);
    },
};

Sample Test Script (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 another 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();
        });
    });
});

Console Output (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.
...

Console Output (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"}
...

Answer №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);
             });
        })
    });

If you are facing issues with taking screenshots without any error message, make sure to check the global variable set by wdBridge, which is wdBrowser in this case.

To resolve similar issues, ensure that you correctly specify your webview name/id, which can be obtained from the appium logs.

Answer №2


After encountering issues with the wdBrowser.context('NATIVE_APP') method, I had to find an alternative way to capture screenshots successfully.
I decided to replace the takeScreenshots() function with the following code snippet:

  var exec = require('child_process').exec;
  exec('adb shell /system/bin/screencap -p /sdcard/' + filename); // Capturing a screenshot and saving it on the device.

  // Waiting for the screenshot to be generated 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) {  // Transferring the screenshot from the device to the 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);
      }
  });

I faced the following issues:

  1. The screenshot was not being saved in time for pulling.
  2. When attempting to pull the screenshot, only 0kb files were retrieved despite their existence on the device. To resolve this, I added a one-second delay between capturing and transferring the screenshot to the computer.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Managing user sessions for a mobile app login in PHP: Best practices

As a professional PHP programmer, my expertise lies in web development and I have limited knowledge about coding for iOS and Android platforms. Currently, I have created RESTful APIs for two mobile apps, one for iOS and the other for Android, which replic ...

What is the best way to structure a query condition within an update method to prevent duplicate entries?

Is there a way to create a conditional query in mongodb or mongoose to prevent redundancy? If a "User" with the same name is already present in the collection, how can I avoid executing the code below without using middleware? Middleware directly skips th ...

utilizing a pair of API requests within a personalized Alexa skill

I posted a question about integrating Alexa with the Steam custom skill API here, but I realize it might be too detailed for some to read through. In essence, my main question is: Can you make two separate API calls within the same block of JS code while ...

Troubleshooting Issues with Retrieving Android Data from MySQL Database using PHP and JSON

Even though I have encountered this question multiple times on stack overflow, I have tried all the solutions provided and none of them seem to work for me. I am attempting to display data in a List View. The data is stored in JSON format and it appears t ...

Receive the values starting from the second one, onwards

Looking for help with a problem that I posted on Stack Overflow Although the issue has been resolved, I am now wondering how to extract the second or third value from it. With multiple tables in the sheet, I will eventually need totals for each of them. A ...

Removing all Null Form Inputs from the Document Object Model upon Submission utilizing JavaScript

I am currently working on a conditional Shopify form that was passed down to me from another developer. The form utilizes JavaScript/Jquery for field validation, ensuring that all mandatory fields are completed before proceeding to the next step. After mak ...

Mastering React children: A guide to correctly defining TypeScript types

I'm having trouble defining the children prop in TypeScript for a small React Component where the child is a function. class ClickOutside extends React.PureComponent<Props, {}> { render() { const { children } = this.props; return chi ...

Error: The parameter "q" provided in the Google Maps Embed API is

Currently, I am developing a Web Application using NodeJs, Express, and Pug/Jade. The pug code below is functional: iframe#map(width="100%", height="600", frameborder="0", style="border:0" src='https://www.google.com/maps/embed/v1/place?' + ...

The connection to host 127.0.0.1 on port 7055 timed out after 45000 milliseconds using Firefox version 26.0 and Selenium standalone jar 2.39

I am having trouble connecting to selenium 2.30 with FF version 26.0 on my AWS unix machine. Every time I try to start both the client accessing selenium, I encounter the following error. Interestingly, when I switch to using selenium standalone jar 2.38. ...

Enhance Your R Shiny Leaflet with JavaScript Addons for Stunning Heat

I am currently exploring the use of a javascript addon for leaflet called the heatmap functionality, which can be found at https://github.com/Leaflet/Leaflet.heat. My goal is to integrate this feature into Shiny, however, it seems that the leaflet package ...

The element is hidden from view at the moment

Currently, I am using selenium in an attempt to log into MyBB for a website where I have membership. Specifically, I am focusing on creating a shout box bot, with full permission to do so. However, I am facing an issue where the element I need to send da ...

Tips for managing asynchronous REST errors in unit tests with Jest

Below is the code snippet for my Node.js test file. This unit test case is failing, here are the details of the code and error message: jest.unmock('./utils.js'); describe('test', () => { it('test', async (done) => ...

Running Python script in Node.js and pausing until completion

I am currently working on an API-Rest project using Node.js, where I need to run a python script that will create a .json file and store it in a specific directory. My goal is to wait for the python script to finish executing so that Node.js can access the ...

Encountering a runtime error in React while making an async call on a NextJS 13 page

I am currently working on implementing async calls using the new app layout in NextJS 13. I have been referring to the latest documentation page. However, I have encountered an error that I can't seem to resolve. https://i.sstatic.net/CpNmu.png Belo ...

What is the best way to use JavaScript to conceal all div elements?

Can someone please provide a JavaScript solution to hide all divs on a web page without using jQuery? I am looking for a method that does not involve using the arrays that are associated with document.getElementByTag. If this is not possible, could you p ...

Error: TurboModuleRegistry.getEnforcing(…) is throwing an error because it cannot locate 'NativeReanimated'

In my React Native project, I have successfully installed React Navigation Stack and everything is working perfectly. However, when I try to implement Drawer Navigation, I encounter an error that I cannot seem to troubleshoot. I have attempted various sol ...

Having issues with my CodePen React code and its ability to display my gradient background

I will provide detailed descriptions to help explain my issue. Link to CodePen: https://codepen.io/Yosharu/pen/morErw The problem I am facing is that my background (and some other CSS elements) are not loading properly in my code, resulting in a white bac ...

App crashes in Kotlin when handling onActivityResult

I have been working on a simple meme generator app and I am encountering difficulties in returning the edited text to the main activity. Currently, when I run the application, clicking the edit icon directs me to the SelectionScreen activity. In this scree ...

Unlocking the power of module augmentation in Typescript: Enhancing library models within your app domain

I currently work with two applications that share the same code base for their models. I am interested in developing and sharing a library model using inheritance in TypeScript. For instance, Pet extends Author. In my current Angular application, I need ...

Transmit the data.json file to a node.js server using Postman

Hi there, I have a file named data.json saved on my desktop that I want to send to a node.js function. The contents of my data.json file are structured as follows: [{"key":"value"}, {same key value structure for 8000 entries}] This fil ...