Skip to content

Commit

Permalink
refactor: Remove idevicescreenshot since don't need it (#1022)
Browse files Browse the repository at this point in the history
  • Loading branch information
umutuzgur committed Aug 2, 2019
1 parent a5d996b commit fe9f6e2
Show file tree
Hide file tree
Showing 4 changed files with 1 addition and 175 deletions.
1 change: 0 additions & 1 deletion README.md
Expand Up @@ -166,7 +166,6 @@ Differences are noted here:
|`simpleIsVisibleCheck`|Use native methods for determining visibility of elements. In some cases this takes a long time. Setting this capability to `false` will cause the system to use the position and size of elements to make sure they are visible on the screen. This can, however, lead to false results in some situations. Defaults to `false`, except iOS 9.3, where it defaults to `true`.|e.g., `true`, `false`|
|`absoluteWebLocations`|This capability will direct the `Get Element Location` command, when used within webviews, to return coordinates which are relative to the origin of the page, rather than relative to the current scroll offset. This capability has no effect outside of webviews. Default `false`.|e.g., `true`|
|`useJSONSource`|Get JSON source from WDA and parse into XML on Appium server. This can be much faster, especially on large devices. Defaults to `false`.|e.g., `true`|
|`realDeviceScreenshotter`|Name of the alternative screenshot system to use for real devices. Defaults to the XCUITest screenshot functionality through WebDriverAgent. Possible value is `idevicescreenshot` to use the screenshot program from libimobiledevice.|e.g., `idevicescreenshot`|
|`mjpegServerPort`|The port number on which WDA broadcasts screenshots stream encoded into MJPEG format from the device under test. It might be necessary to change this value if the default port is busy because of other tests running in parallel. Default value: `9100`|e.g. `12000`|
|`waitForQuiescence`| It allows to turn on/off waiting for application quiescence in WebDriverAgent, while performing queries. The default value is `true`. You can avoid [this kind of issues](https://github.com/appium/appium/issues/11132) if you turn it off. |e.g `false`|
|`screenshotQuality`| Changes the quality of phone display screenshots following [xctest/xctimagequality](https://developer.apple.com/documentation/xctest/xctimagequality?language=objc) Default value is `1`. `0` is the highest and `2` is the lowest quality. You can also change it via [settings](https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/settings.md) command. `0` might cause OutOfMemory crash on high-resolution devices like iPad Pro. | e.g. `0`, `1`, `2` |
Expand Down
63 changes: 1 addition & 62 deletions lib/commands/screenshots.js
@@ -1,52 +1,12 @@
import { retryInterval } from 'asyncbox';
import _ from 'lodash';
import { getScreenshot as simctlGetScreenshot } from 'node-simctl';
import { exec } from 'teen_process';
import log from '../logger';
import { fs, tempDir, util, imageUtil } from 'appium-support';
import jimp from 'jimp';
import { util, imageUtil } from 'appium-support';

let commands = {};

async function getScreenshotWithIdevicelib (udid, isLandscape) {
const pathToResultPng = await tempDir.path({prefix: `screenshot-${udid}`, suffix: '.png'});
await fs.rimraf(pathToResultPng);
try {
try {
await exec('idevicescreenshot', ['-u', udid, pathToResultPng]);
} catch (e) {
throw new Error(`Cannot take a screenshot from the device '${udid}' using ` +
`idevicescreenshot. Original error: ${e.message}`);
}
const data = await fs.readFile(pathToResultPng);
if (!isLandscape) {
return data.toString('base64');
}
const image = await jimp.read(data);
const buffer = await image.rotate(90).getBufferAsync(jimp.MIME_PNG);
return buffer.toString('base64');
} finally {
await fs.rimraf(pathToResultPng);
}
}

async function verifyIdeviceScreenshotAvailable () {
try {
await fs.which('idevicescreenshot');
} catch (err) {
throw new Error(`No 'idevicescreenshot' program found. To use, install ` +
`using 'brew install --HEAD libimobiledevice'`);
}
}

commands.getScreenshot = async function getScreenshot () {
const getScreenshotFromIDS = async () => {
log.debug(`Taking screenshot with 'idevicescreenshot'`);
await verifyIdeviceScreenshotAvailable();
const orientation = await this.proxyCommand('/orientation', 'GET');
return await getScreenshotWithIdevicelib(this.opts.udid, orientation === 'LANDSCAPE');
};

const getScreenshotFromWDA = async () => {
log.debug(`Taking screenshot with WDA`);
const data = await this.proxyCommand('/screenshot', 'GET');
Expand All @@ -56,13 +16,6 @@ commands.getScreenshot = async function getScreenshot () {
return data;
};

// ensure the user doesn't try to use 2 specialty screenshot caps
if (this.opts.realDeviceScreenshotter && this.mjpegStream) {
log.warn("You've specified screenshot retrieval via both MJpeg server " +
'and a real device screenshot utility. Please use one or the ' +
'other! Choosing MJPEG server');
}

// if we've specified an mjpeg server, use that
if (this.mjpegStrem) {
const data = await this.mjpegStream.lastChunkPNGBase64();
Expand All @@ -73,12 +26,6 @@ commands.getScreenshot = async function getScreenshot () {
'was no data yet. Falling back to regular screenshot methods.');
}

// otherwise use the real device screenshotter as specified
const useIdeviceScreenshot = _.lowerCase(this.opts.realDeviceScreenshotter) === 'idevicescreenshot';
if (useIdeviceScreenshot) {
return await getScreenshotFromIDS();
}

try {
return await getScreenshotFromWDA();
} catch (err) {
Expand All @@ -91,14 +38,6 @@ commands.getScreenshot = async function getScreenshot () {
return await simctlGetScreenshot(this.opts.udid);
}

// all simulator scenarios are finished
// real device, so try idevicescreenshot if possible
try {
return await getScreenshotFromIDS();
} catch (err) {
log.warn(`Error getting screenshot through 'idevicescreenshot': ${err.message}`);
}

// Retry for real devices only. Fail fast on Simulator if simctl does not work as expected
return await retryInterval(2, 1000, getScreenshotFromWDA);
};
Expand Down
5 changes: 0 additions & 5 deletions lib/desired-caps.js
Expand Up @@ -141,11 +141,6 @@ let desiredCapConstraints = _.defaults({
keychainsExcludePatterns: {
isString: true
},
realDeviceScreenshotter: {
isString: true,
presence: false,
inclusionCaseInsensitive: ['idevicescreenshot']
},
showSafariConsoleLog: {
isBoolean: true
},
Expand Down
107 changes: 0 additions & 107 deletions test/unit/commands/screenshots-specs.js
@@ -1,17 +1,13 @@
import path from 'path';
import sinon from 'sinon';
import XCUITestDriver from '../../..';
import { fs, tempDir } from 'appium-support';

const simctlModule = require('node-simctl');
const teenProcessModule = require('teen_process');

describe('screenshots commands', function () {
let driver;
let proxyStub;

const base64PortraitResponse = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
const base64LandscapeResponse = 'iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAD0lEQVR4AWNgqGeoZ0AGAA70AP/hygDpAAAAAElFTkSuQmCC';

beforeEach(function () {
driver = new XCUITestDriver();
Expand Down Expand Up @@ -69,109 +65,6 @@ describe('screenshots commands', function () {
proxyStub.firstCall.args[0].should.eql('/screenshot');
proxyStub.firstCall.args[1].should.eql('GET');
});

describe('idevicescreenshot', function () {
const pngPath = '/some/file.png';
const udid = '1234';
const toolName = 'idevicescreenshot';
const file = path.resolve(__dirname, '..', '..', '..', '..', 'test', 'assets', 'test.png');
let pngFileContent;

let fsExistsStub;
let fsWhichStub;
let fsRimRafStub;
let fsReadFileStub;
let execStub;
let pathStub;

before(async function () {
pngFileContent = await fs.readFile(file);
});

beforeEach(function () {
driver.opts.realDevice = true;
driver.opts.udid = udid;
});
afterEach(function () {
for (const stub of [fsExistsStub, fsWhichStub, fsReadFileStub, fsRimRafStub, execStub, pathStub]) {
if (stub) {
stub.restore();
}
}
});

describe('success', function () {
beforeEach(function () {
fsExistsStub = sinon.stub(fs, 'exists');
fsExistsStub.returns(true);

fsWhichStub = sinon.stub(fs, 'which');
fsWhichStub.returns(toolName);

fsRimRafStub = sinon.stub(fs, 'rimraf');

fsReadFileStub = sinon.stub(fs, 'readFile');
fsReadFileStub.returns(pngFileContent);

execStub = sinon.stub(teenProcessModule, 'exec');

pathStub = sinon.stub(tempDir, 'path');
pathStub.withArgs({prefix: `screenshot-${udid}`, suffix: '.png'}).returns(pngPath);
});
afterEach(function () {
fsWhichStub.calledOnce.should.be.true;
fsWhichStub.firstCall.args[0].should.eql(toolName);

execStub.calledOnce.should.be.true;
execStub.firstCall.args[0].should.eql(toolName);
execStub.firstCall.args[1].should.eql(['-u', udid, pngPath]);

fsRimRafStub.callCount.should.eql(2);

fsReadFileStub.calledOnce.should.be.true;
fsReadFileStub.firstCall.args[0].should.eql(pngPath);

pathStub.calledOnce.should.be.true;
});

it('should use idevicescreenshot if WDA fails', async function () {
proxyStub.onFirstCall().returns(null);
proxyStub.onSecondCall().returns('PORTRAIT');

(await driver.getScreenshot()).should.eql(pngFileContent.toString('base64'));

proxyStub.callCount.should.eql(2);
proxyStub.firstCall.args.should.eql(['/screenshot', 'GET']);
proxyStub.secondCall.args.should.eql(['/orientation', 'GET']);
});
it('should use idevicescreenshot if specified in realDeviceScreenshotter cap', async function () {
proxyStub.onFirstCall().returns('LANDSCAPE');
driver.opts.realDeviceScreenshotter = 'idevicescreenshot';

(await driver.getScreenshot()).should.eql(base64LandscapeResponse);

proxyStub.callCount.should.eql(1);
});
});
describe('failure', function () {
beforeEach(function () {

proxyStub.onFirstCall().returns(null);

fsWhichStub = sinon.stub(fs, 'which');
fsWhichStub.throws(new Error('No program found'));
});
afterEach(function () {
fsWhichStub.calledOnce.should.be.true;
fsWhichStub.firstCall.args[0].should.eql(toolName);
});

it('should throw an error if idevicescreenshot is not available and realDeviceScreenshotter set', async function () {
driver.opts.realDeviceScreenshotter = 'idevicescreenshot';
await driver.getScreenshot().should.eventually.be.rejectedWith(/No 'idevicescreenshot' program found/);
});
});
});
});
});
});

0 comments on commit fe9f6e2

Please sign in to comment.