Skip to content

fix: remove duplicated property #243

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 27 additions & 7 deletions lib/appium-driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import { LogType } from "./log-types";
import { screencapture } from "./helpers/screenshot-manager";
import { LogImageType } from "./enums/log-image-type";
import { DeviceOrientation } from "./enums/device-orientation";
import { NsCapabilities } from "./ns-capabilities";

export class AppiumDriver {
private _defaultWaitTime: number = 5000;
Expand Down Expand Up @@ -546,13 +547,32 @@ export class AppiumDriver {
logInfo(`Set device orientation: ${orientation}`)
await this._driver.setOrientation(orientation);

if (orientation === DeviceOrientation.LANDSCAPE) {
this.imageHelper.imageCropRect.x = this._imageHelper.options.cropRectangle.x;
this.imageHelper.imageCropRect.y = this._imageHelper.options.cropRectangle.y;
this.imageHelper.imageCropRect.width = this._imageHelper.options.cropRectangle.height;
this.imageHelper.imageCropRect.height = this._imageHelper.options.cropRectangle.width;
} else {
this.imageHelper.imageCropRect = undefined;
if (orientation === DeviceOrientation.LANDSCAPE && this.isAndroid) {
if ((<NsCapabilities>this.nsCapabilities).tryGetApiLevel() < 6.0) {
// HACK since the image is rotated and action bar is on the bottom of the image, it is needed to exclude action bar from bottom.
const height = this._imageHelper.options.cropRectangle.width - this._imageHelper.options.cropRectangle.y;
const width = this._imageHelper.options.cropRectangle.height + this._imageHelper.options.cropRectangle.y;
this.imageHelper.options.cropRectangle.y = 0;
this.imageHelper.options.cropRectangle.width = width;
this.imageHelper.options.cropRectangle.height = height;
} else if ((<NsCapabilities>this.nsCapabilities).tryGetApiLevel() >= 6.0) {
const height = this._imageHelper.options.cropRectangle.width - this.imageHelper.options.cropRectangle.y;
const width = this._imageHelper.options.cropRectangle.height + this.imageHelper.options.cropRectangle.y;
this.imageHelper.options.cropRectangle.width = width;
this.imageHelper.options.cropRectangle.height = height;
}
}
else if (orientation === DeviceOrientation.LANDSCAPE && this.isIOS) {
this.imageHelper.options.cropRectangle.x = 0;
const height = this._imageHelper.options.cropRectangle.width;
const width = this._imageHelper.options.cropRectangle.height + this._imageHelper.options.cropRectangle.y;
this.imageHelper.options.cropRectangle.y = 0;

this.imageHelper.options.cropRectangle.width = width;
this.imageHelper.options.cropRectangle.height = height;
}
else {
this.imageHelper.resetDefaultOptions();
}
}

Expand Down
4 changes: 1 addition & 3 deletions lib/image-helper.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ export declare class ImageHelper {
private _driver;
private _blockOutAreas;
private _imagesResults;
private _imageCropRect;
private _options;
private _defaultOptions;
constructor(_args: INsCapabilities, _driver: AppiumDriver);
Expand All @@ -80,7 +79,6 @@ export declare class ImageHelper {
*/
delta: number;
options: IImageCompareOptions;
imageCropRect: IRectangle;
blockOutAreas: IRectangle[];
compareScreen(options?: IImageCompareOptions): Promise<boolean>;
compareElement(element: UIElement, options?: IImageCompareOptions): Promise<boolean>;
Expand All @@ -97,7 +95,7 @@ export declare class ImageHelper {
getExpectedImagePathByDevice(imageName: string): string;
getExpectedImagePathByPlatform(imageName: string): string;
compare(options: IImageCompareOptions): Promise<boolean>;
compareImages(actual: string, expected: string, output: string, tolerance: number, toleranceType: ImageOptions): Promise<boolean>;
compareImages(options: IImageCompareOptions, actual: string, expected: string, output: string): Promise<boolean>;
clipRectangleImage(rect: IRectangle, path: string): Promise<{}>;
readImage(path: string): Promise<any>;
private runDiff;
Expand Down
92 changes: 44 additions & 48 deletions lib/image-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { AppiumDriver } from "./appium-driver";
import { logError, checkImageLogType, resolvePath, copy, addExt, logWarn } from "./utils";
import { unlinkSync, existsSync, mkdirSync } from "fs";
import { basename, join } from "path";
import { isObject } from "util";
import { isObject, isNumber } from "util";
import { logInfo } from "mobile-devices-controller/lib/utils";

export interface IImageCompareOptions {
Expand Down Expand Up @@ -82,7 +82,6 @@ export interface IImageCompareOptions {
export class ImageHelper {
private _blockOutAreas: IRectangle[];
private _imagesResults = new Map<string, boolean>();
private _imageCropRect: IRectangle;
private _options: IImageCompareOptions = {};
private _defaultOptions: IImageCompareOptions = {
timeOutSeconds: 2,
Expand All @@ -101,12 +100,14 @@ export class ImageHelper {
constructor(private _args: INsCapabilities, private _driver: AppiumDriver) {
this._defaultOptions.cropRectangle = (this._args.appiumCaps && this._args.appiumCaps.viewportRect) || this._args.device.viewportRect;
if (!this._defaultOptions.cropRectangle
|| this._defaultOptions.cropRectangle.y === undefined
|| this._defaultOptions.cropRectangle.y === null
|| this._defaultOptions.cropRectangle.y === NaN) {
|| !isNumber(this._defaultOptions.cropRectangle.y)) {
this._defaultOptions.cropRectangle = this._defaultOptions.cropRectangle || {};
this._defaultOptions.cropRectangle.y = this._args.device.config.offsetPixels || 0;
this._defaultOptions.cropRectangle.x = 0;
if (this._args.device.deviceScreenSize && this._args.device.deviceScreenSize.width && this._args.device.deviceScreenSize.height) {
this._defaultOptions.cropRectangle.height = this._args.device.deviceScreenSize.height - this._defaultOptions.cropRectangle.y;
this._defaultOptions.cropRectangle.width = this._args.device.deviceScreenSize.width - this._defaultOptions.cropRectangle.x;
}
}
ImageHelper.fullClone(this._defaultOptions, this._options);

Expand Down Expand Up @@ -137,14 +138,6 @@ export class ImageHelper {
this._options = this.extendOptions(options);
}

get imageCropRect(): IRectangle {
return this._imageCropRect || this.options.cropRectangle;
}

set imageCropRect(clipRectangle: IRectangle) {
this._imageCropRect = clipRectangle;
}

get blockOutAreas() {
return this._blockOutAreas;
}
Expand Down Expand Up @@ -257,7 +250,6 @@ export class ImageHelper {
// First time capture
if (!existsSync(pathExpectedImage)) {
await captureFirstImage();

return false;
}

Expand All @@ -269,7 +261,7 @@ export class ImageHelper {
const pathDiffImage = pathActualImage.replace("actual", "diff");

// await this.prepareImageToCompare(pathActualImage, options.cropRectangle);
let result = await this.compareImages(pathActualImage, pathExpectedImage, pathDiffImage, options.tolerance, options.toleranceType);
let result = await this.compareImages(options, pathActualImage, pathExpectedImage, pathDiffImage);

// Iterate
if (!result) {
Expand All @@ -283,7 +275,7 @@ export class ImageHelper {
await this.clipRectangleImage(options.cropRectangle, pathActualImage);
}
// await this.prepareImageToCompare(pathActualImage, this.imageCropRect);
result = await this.compareImages(pathActualImage, pathExpectedImage, pathDiffImage, options.tolerance, options.toleranceType);
result = await this.compareImages(options, pathActualImage, pathExpectedImage, pathDiffImage);
if (!result && checkImageLogType(this._args.testReporter, LogImageType.everyImage)) {
this._args.testReporterLog(`Actual image: ${basename(pathActualImage).replace(/\.\w{3,3}$/ig, "")}`);
this._args.testReporterLog(join(this._args.reportsPath, basename(pathActualImage)));
Expand Down Expand Up @@ -314,12 +306,12 @@ export class ImageHelper {
return result;
}

public compareImages(actual: string, expected: string, output: string, tolerance: number, toleranceType: ImageOptions) {
public compareImages(options: IImageCompareOptions, actual: string, expected: string, output: string) {
const clipRect = {
x: this.imageCropRect.x,
y: this.imageCropRect.y,
width: this.imageCropRect.width,
height: this.imageCropRect.height
x: this.options.cropRectangle.x,
y: this.options.cropRectangle.y,
width: this.options.cropRectangle.width,
height: this.options.cropRectangle.height
}

if (!this.options.keepOriginalImageSize) {
Expand All @@ -334,22 +326,22 @@ export class ImageHelper {
imageBPath: expected,
imageOutputPath: output,
imageOutputLimit: this.imageOutputLimit,
thresholdType: toleranceType,
threshold: tolerance,
thresholdType: options.toleranceType,
threshold: options.tolerance,
delta: this.delta,
cropImageA: clipRect,
cropImageB: clipRect,
blockOut: this._blockOutAreas,
verbose: this._args.verbose,
});

if (toleranceType == ImageOptions.percent) {
if (tolerance >= 1) {
if (options.toleranceType == ImageOptions.percent) {
if (options.tolerance >= 1) {
logError("Tolerance range is from 0 to 1 -> percentage thresholds: 1 = 100%, 0.2 = 20%");
}
console.log(`Using ${tolerance * 100}% tolerance`);
console.log(`Using ${options.tolerance * 100}% tolerance`);
} else {
console.log(`Using ${tolerance}px tolerance`);
console.log(`Using ${options.tolerance}px tolerance`);
}

const result = this.runDiff(diff, output);
Expand All @@ -361,26 +353,34 @@ export class ImageHelper {
let imageToClip: PngJsImage;
imageToClip = await this.readImage(path);
let shouldExit = false;
Object.getOwnPropertyNames(rect).forEach(prop => {
if (rect[prop] === undefined || rect[prop] === null) {
shouldExit = true;
return;
}
});
if (!isNumber(rect["x"])
|| !isNumber(rect["y"])
|| !isNumber(rect["width"])
|| !isNumber(rect["height"])) {
shouldExit = true;
}
if (shouldExit) {
logError(`Could not crop the image. Not enough data`, rect);
return
logError(`Could not crop the image. Not enough data {x: ${rect["x"]}, y: ${rect["y"]}, width: ${rect["width"]}, height: ${rect["height"]}}`);
}
imageToClip.clip(rect.x, rect.y, rect.width, rect.height);
return new Promise((resolve, reject) => {
imageToClip.writeImage(path, (err) => {
if (err) {
return reject(err);
}
return resolve();
});

})
if (!shouldExit) {
imageToClip.clip(rect.x, rect.y, rect.width, rect.height);
} else {
logWarn("Image will not be cropped!")
return true;
}
return new Promise((resolve, reject) => {
try {
imageToClip.writeImage(path, (err) => {
if (err) {
return reject(err);
}
return resolve();
});
} catch (error) {
logError(error);
}
});
}

public readImage(path: string): Promise<any> {
Expand Down Expand Up @@ -471,10 +471,6 @@ export class ImageHelper {
}
});

if (!options.cropRectangle) {
ImageHelper.fullClone(this.imageCropRect, options.cropRectangle);
}

return options;
}

Expand Down
5 changes: 2 additions & 3 deletions lib/ns-capabilities.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,9 @@ export declare class NsCapabilities implements INsCapabilities {
extend(args: INsCapabilities): this;
validateArgs(): Promise<void>;
private isAndroidPlatform;
shouldSetFullResetOption(): void;
setResetOption(): void;
tryGetApiLevel(): number;
private setAutomationName;
tryGetAndroidApiLevel(): number;
tryGetIOSApiLevel(): number;
private resolveApplication;
private checkMandatoryCapabilities;
private throwExceptions;
Expand Down
30 changes: 15 additions & 15 deletions lib/ns-capabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ export class NsCapabilities implements INsCapabilities {
this.resolveApplication();
this.checkMandatoryCapabilities();
this.throwExceptions();
this.shouldSetFullResetOption();
this.setResetOption();

this.isValidated = true;
} else {
Expand All @@ -275,7 +275,7 @@ export class NsCapabilities implements INsCapabilities {
return this.appiumCaps && this.appiumCaps ? this.appiumCaps.platformName.toLowerCase().includes("android") : undefined;
}

public shouldSetFullResetOption() {
public setResetOption() {
if (this.attachToDebug || this.devMode) {
this.appiumCaps["fullReset"] = false;
this.appiumCaps["noReset"] = true;
Expand All @@ -300,6 +300,18 @@ export class NsCapabilities implements INsCapabilities {
}
}

public tryGetApiLevel() {
try {
const apiLevel = this.appiumCaps["platformVersion"] || this.appiumCaps["apiLevel"];
if (this.isAndroid && apiLevel) {
return +apiLevel.split(".").splice(0, 2).join('.');
}
return +apiLevel;
} catch (error) { }

return undefined;
}

private setAutomationName() {
if (this.appiumCaps["automationName"]) {
switch (this.appiumCaps["automationName"].toLowerCase()) {
Expand All @@ -313,7 +325,7 @@ export class NsCapabilities implements INsCapabilities {
this.automationName = AutomationName.UiAutomator1; break;
}
} else {
const apiLevel = this.tryGetApiLevel();
const apiLevel = +this.tryGetApiLevel();
if (this.isAndroid) {
if ((apiLevel >= 6 && apiLevel <= 17)
|| apiLevel >= 23) {
Expand Down Expand Up @@ -341,18 +353,6 @@ export class NsCapabilities implements INsCapabilities {
}
}

tryGetApiLevel() {
try {
const apiLevel = this.appiumCaps["platformVersion"] || this.appiumCaps["apiLevel"];
if (this.isAndroid && apiLevel) {
return apiLevel.split(".").splice(0, 2).join('.');
}
return apiLevel;
} catch (error) { }

return undefined;
}

private resolveApplication() {
if (this.isSauceLab) {
if (this.appPath) {
Expand Down
4 changes: 2 additions & 2 deletions test/device-manager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ describe("ios-devices", () => {
deviceManager = new DeviceManager();
appiumArgs = new NsCapabilities(<any>{});
appiumArgs.extend(<any>{ appiumCaps: { platformName: Platform.IOS, fullReset: false, deviceName: /iPhone X/ } })
appiumArgs.shouldSetFullResetOption();
appiumArgs.setResetOption();
});

after("Kill all simulators", () => {
Expand All @@ -101,7 +101,7 @@ describe("ios-devices", () => {

it("Start simulator fullReset: true, should kill device", async () => {
appiumArgs.extend(<any>{ appiumCaps: { platformName: Platform.IOS, fullReset: true, deviceName: /iPhone X/ } });
appiumArgs.shouldSetFullResetOption();
appiumArgs.setResetOption();
const device = await deviceManager.startDevice(appiumArgs);
let foundBootedDevices = await DeviceController.getDevices({ platform: Platform.IOS, status: Status.BOOTED });
assert.isTrue(foundBootedDevices.some(d => d.token === device.token));
Expand Down