mirror of
https://github.com/apache/cordova-plugin-camera.git
synced 2025-01-19 03:42:52 +08:00
fix: temporarily remove Appium tests (#468)
This commit is contained in:
parent
cffd0ac825
commit
19d8e2f6ff
@ -1,751 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// these tests are meant to be executed by Cordova ParaMedic Appium runner
|
|
||||||
// you can find it here: https://github.com/apache/cordova-paramedic/
|
|
||||||
// it is not necessary to do a full CI setup to run these tests
|
|
||||||
// Run:
|
|
||||||
// node cordova-paramedic/main.js --platform android --plugin cordova-plugin-camera --skipMainTests --target <emulator name>
|
|
||||||
// Please note only Android 5.1 and 4.4 are supported at this point.
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var wdHelper = global.WD_HELPER;
|
|
||||||
var screenshotHelper = global.SCREENSHOT_HELPER;
|
|
||||||
var wd = wdHelper.getWD();
|
|
||||||
var cameraConstants = require('../../www/CameraConstants');
|
|
||||||
var cameraHelper = require('../helpers/cameraHelper');
|
|
||||||
|
|
||||||
var MINUTE = 60 * 1000;
|
|
||||||
var BACK_BUTTON = 4;
|
|
||||||
var DEFAULT_SCREEN_WIDTH = 360;
|
|
||||||
var DEFAULT_SCREEN_HEIGHT = 567;
|
|
||||||
var DEFAULT_WEBVIEW_CONTEXT = 'WEBVIEW';
|
|
||||||
var PROMISE_PREFIX = 'appium_camera_promise_';
|
|
||||||
var CONTEXT_NATIVE_APP = 'NATIVE_APP';
|
|
||||||
|
|
||||||
describe('Camera tests Android.', function () {
|
|
||||||
var driver;
|
|
||||||
// the name of webview context, it will be changed to match needed context if there are named ones:
|
|
||||||
var webviewContext = DEFAULT_WEBVIEW_CONTEXT;
|
|
||||||
// this indicates that the device library has the test picture:
|
|
||||||
var isTestPictureSaved = false;
|
|
||||||
// we need to know the screen width and height to properly click on an image in the gallery:
|
|
||||||
var screenWidth = DEFAULT_SCREEN_WIDTH;
|
|
||||||
var screenHeight = DEFAULT_SCREEN_HEIGHT;
|
|
||||||
// promise count to use in promise ID
|
|
||||||
var promiseCount = 0;
|
|
||||||
// determine if Appium session is created successfully
|
|
||||||
var appiumSessionStarted = false;
|
|
||||||
// determine if camera is present on the device/emulator
|
|
||||||
var cameraAvailable = false;
|
|
||||||
// determine if emulator is within a range of acceptable resolutions able to run these tests
|
|
||||||
var isResolutionBad = true;
|
|
||||||
// a path to the image we add to the gallery before test run
|
|
||||||
var fillerImagePath;
|
|
||||||
var isAndroid7 = getIsAndroid7();
|
|
||||||
|
|
||||||
function getIsAndroid7() {
|
|
||||||
if (global.USE_SAUCE) {
|
|
||||||
return global.SAUCE_CAPS && (parseFloat(global.SAUCE_CAPS.platformVersion) >= 7);
|
|
||||||
} else {
|
|
||||||
// this is most likely null, meaning we cannot determine if it is Android 7 or not
|
|
||||||
// paramedic needs to be modified to receive and pass the platform version when testing locally
|
|
||||||
return global.PLATFORM_VERSION && (parseFloat(global.PLATFORM_VERSION) >= 7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNextPromiseId() {
|
|
||||||
promiseCount += 1;
|
|
||||||
return getCurrentPromiseId();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCurrentPromiseId() {
|
|
||||||
return PROMISE_PREFIX + promiseCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gracefullyFail(error) {
|
|
||||||
fail(error);
|
|
||||||
return driver
|
|
||||||
.quit()
|
|
||||||
.then(function () {
|
|
||||||
return getDriver();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// combinines specified options in all possible variations
|
|
||||||
// you can add more options to test more scenarios
|
|
||||||
function generateOptions() {
|
|
||||||
var sourceTypes = [
|
|
||||||
cameraConstants.PictureSourceType.CAMERA,
|
|
||||||
cameraConstants.PictureSourceType.PHOTOLIBRARY
|
|
||||||
];
|
|
||||||
var destinationTypes = cameraConstants.DestinationType;
|
|
||||||
var encodingTypes = cameraConstants.EncodingType;
|
|
||||||
var allowEditOptions = [ true, false ];
|
|
||||||
var correctOrientationOptions = [ true, false ];
|
|
||||||
|
|
||||||
return cameraHelper.generateSpecs(sourceTypes, destinationTypes, encodingTypes, allowEditOptions, correctOrientationOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
// invokes Camera.getPicture() with the specified options
|
|
||||||
// and goes through all UI interactions unless 'skipUiInteractions' is true
|
|
||||||
function getPicture(options, skipUiInteractions) {
|
|
||||||
var promiseId = getNextPromiseId();
|
|
||||||
if (!options) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
// assign default values
|
|
||||||
if (!options.hasOwnProperty('allowEdit')) {
|
|
||||||
options.allowEdit = true;
|
|
||||||
}
|
|
||||||
if (!options.hasOwnProperty('destinationType')) {
|
|
||||||
options.destinationType = cameraConstants.DestinationType.FILE_URI;
|
|
||||||
}
|
|
||||||
if (!options.hasOwnProperty('sourceType')) {
|
|
||||||
options.destinationType = cameraConstants.PictureSourceType.CAMERA;
|
|
||||||
}
|
|
||||||
|
|
||||||
return driver
|
|
||||||
.context(webviewContext)
|
|
||||||
.execute(cameraHelper.getPicture, [options, promiseId])
|
|
||||||
.context(CONTEXT_NATIVE_APP)
|
|
||||||
.then(function () {
|
|
||||||
if (skipUiInteractions) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// selecting a picture from gallery
|
|
||||||
if (options.hasOwnProperty('sourceType') &&
|
|
||||||
(options.sourceType === cameraConstants.PictureSourceType.PHOTOLIBRARY ||
|
|
||||||
options.sourceType === cameraConstants.PictureSourceType.SAVEDPHOTOALBUM)) {
|
|
||||||
var tapTile = new wd.TouchAction();
|
|
||||||
var swipeRight = new wd.TouchAction();
|
|
||||||
tapTile
|
|
||||||
.tap({
|
|
||||||
x: Math.round(screenWidth / 4),
|
|
||||||
y: Math.round(screenHeight / 4)
|
|
||||||
});
|
|
||||||
swipeRight
|
|
||||||
.press({x: 10, y: Math.round(screenHeight / 4)})
|
|
||||||
.wait(300)
|
|
||||||
.moveTo({x: Math.round(screenWidth - (screenWidth / 8)), y: 0})
|
|
||||||
.wait(1500)
|
|
||||||
.release()
|
|
||||||
.wait(1000);
|
|
||||||
if (options.allowEdit) {
|
|
||||||
return driver
|
|
||||||
// always wait before performing touchAction
|
|
||||||
.sleep(7000)
|
|
||||||
.performTouchAction(tapTile);
|
|
||||||
}
|
|
||||||
return driver
|
|
||||||
.waitForElementByAndroidUIAutomator('new UiSelector().text("Gallery");', 20000)
|
|
||||||
.fail(function () {
|
|
||||||
// If the Gallery button is not present, swipe right to reveal the Gallery button!
|
|
||||||
return driver
|
|
||||||
.performTouchAction(swipeRight)
|
|
||||||
.waitForElementByAndroidUIAutomator('new UiSelector().text("Gallery");', 20000)
|
|
||||||
})
|
|
||||||
.click()
|
|
||||||
// always wait before performing touchAction
|
|
||||||
.sleep(7000)
|
|
||||||
.performTouchAction(tapTile);
|
|
||||||
}
|
|
||||||
// taking a picture from camera
|
|
||||||
return driver
|
|
||||||
.waitForElementByAndroidUIAutomator('new UiSelector().resourceIdMatches(".*shutter.*")', MINUTE / 2)
|
|
||||||
.click()
|
|
||||||
.waitForElementByAndroidUIAutomator('new UiSelector().resourceIdMatches(".*done.*")', MINUTE / 2)
|
|
||||||
.click()
|
|
||||||
.then(function () {
|
|
||||||
if (isAndroid7 && options.allowEdit) {
|
|
||||||
return driver
|
|
||||||
.elementByAndroidUIAutomator('new UiSelector().text("Crop picture");', 20000)
|
|
||||||
.click()
|
|
||||||
.fail(function () {
|
|
||||||
// don't freak out just yet...
|
|
||||||
return driver;
|
|
||||||
})
|
|
||||||
.elementByAndroidUIAutomator('new UiSelector().text("JUST ONCE");', 20000)
|
|
||||||
.click()
|
|
||||||
.fail(function () {
|
|
||||||
// maybe someone's hit that "ALWAYS" button?
|
|
||||||
return driver;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return driver;
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
if (skipUiInteractions) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (options.allowEdit) {
|
|
||||||
var saveText = isAndroid7 ? 'SAVE' : 'Save';
|
|
||||||
return driver
|
|
||||||
.waitForElementByAndroidUIAutomator('new UiSelector().text("' + saveText + '")', MINUTE)
|
|
||||||
.click();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.fail(function (failure) {
|
|
||||||
throw failure;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// checks if the picture was successfully taken
|
|
||||||
// if shouldLoad is falsy, ensures that the error callback was called
|
|
||||||
function checkPicture(shouldLoad, options) {
|
|
||||||
if (!options) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
return driver
|
|
||||||
.context(webviewContext)
|
|
||||||
.setAsyncScriptTimeout(MINUTE / 2)
|
|
||||||
.executeAsync(cameraHelper.checkPicture, [getCurrentPromiseId(), options, isAndroid7])
|
|
||||||
.then(function (result) {
|
|
||||||
if (shouldLoad) {
|
|
||||||
if (result !== 'OK') {
|
|
||||||
fail(result);
|
|
||||||
}
|
|
||||||
} else if (result.indexOf('ERROR') === -1) {
|
|
||||||
throw 'Unexpected success callback with result: ' + result;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// deletes the latest image from the gallery
|
|
||||||
function deleteImage() {
|
|
||||||
var holdTile = new wd.TouchAction();
|
|
||||||
holdTile
|
|
||||||
.press({x: Math.round(screenWidth / 4), y: Math.round(screenHeight / 5)})
|
|
||||||
.wait(1000)
|
|
||||||
.release();
|
|
||||||
return driver
|
|
||||||
// always wait before performing touchAction
|
|
||||||
.sleep(7000)
|
|
||||||
.performTouchAction(holdTile)
|
|
||||||
.elementByAndroidUIAutomator('new UiSelector().text("Delete")')
|
|
||||||
.then(function (element) {
|
|
||||||
return element
|
|
||||||
.click()
|
|
||||||
.elementByAndroidUIAutomator('new UiSelector().text("OK")')
|
|
||||||
.click();
|
|
||||||
}, function () {
|
|
||||||
// couldn't find Delete menu item. Possibly there is no image.
|
|
||||||
return driver;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDriver() {
|
|
||||||
driver = wdHelper.getDriver('Android');
|
|
||||||
return driver.getWebviewContext()
|
|
||||||
.then(function(context) {
|
|
||||||
webviewContext = context;
|
|
||||||
return driver.context(webviewContext);
|
|
||||||
})
|
|
||||||
.waitForDeviceReady()
|
|
||||||
.injectLibraries()
|
|
||||||
.then(function () {
|
|
||||||
var options = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.SAVEDPHOTOALBUM,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 210,
|
|
||||||
targetHeight: 210
|
|
||||||
};
|
|
||||||
return driver
|
|
||||||
.then(function () { return getPicture(options, true); })
|
|
||||||
.context(CONTEXT_NATIVE_APP)
|
|
||||||
// case insensitive select, will be handy with Android 7 support
|
|
||||||
.elementByXPath('//android.widget.Button[translate(@text, "alow", "ALOW")="ALLOW"]')
|
|
||||||
.click()
|
|
||||||
.fail(function noAlert() { })
|
|
||||||
.deviceKeyEvent(BACK_BUTTON)
|
|
||||||
.sleep(2000)
|
|
||||||
.elementById('action_bar_title')
|
|
||||||
.then(function () {
|
|
||||||
// success means we're still in native app
|
|
||||||
return driver
|
|
||||||
.deviceKeyEvent(BACK_BUTTON);
|
|
||||||
}, function () {
|
|
||||||
// error means we're already in webview
|
|
||||||
return driver;
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
// doing it inside a function because otherwise
|
|
||||||
// it would not hook up to the webviewContext var change
|
|
||||||
// in the first methods of this chain
|
|
||||||
return driver.context(webviewContext);
|
|
||||||
})
|
|
||||||
.deleteFillerImage(fillerImagePath)
|
|
||||||
.then(function () {
|
|
||||||
fillerImagePath = null;
|
|
||||||
})
|
|
||||||
.addFillerImage()
|
|
||||||
.then(function (result) {
|
|
||||||
if (result && result.indexOf('ERROR:') === 0) {
|
|
||||||
throw new Error(result);
|
|
||||||
} else {
|
|
||||||
fillerImagePath = result;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function recreateSession() {
|
|
||||||
return driver
|
|
||||||
.quit()
|
|
||||||
.finally(function () {
|
|
||||||
return getDriver();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function tryRunSpec(spec) {
|
|
||||||
return driver
|
|
||||||
.then(spec)
|
|
||||||
.fail(function () {
|
|
||||||
return recreateSession()
|
|
||||||
.then(spec)
|
|
||||||
.fail(function() {
|
|
||||||
return recreateSession()
|
|
||||||
.then(spec);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.fail(gracefullyFail);
|
|
||||||
}
|
|
||||||
|
|
||||||
// produces a generic spec function which
|
|
||||||
// takes a picture with specified options
|
|
||||||
// and then verifies it
|
|
||||||
function generateSpec(options) {
|
|
||||||
return function () {
|
|
||||||
return driver
|
|
||||||
.then(function () {
|
|
||||||
return getPicture(options);
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
return checkPicture(true, options);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkSession(done, skipResolutionCheck) {
|
|
||||||
if (!appiumSessionStarted) {
|
|
||||||
fail('Failed to start a session ' + (lastFailureReason ? lastFailureReason : ''));
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
if (!skipResolutionCheck && isResolutionBad) {
|
|
||||||
fail('The resolution of this target device is not within the appropriate range of width: blah-blah and height: bleh-bleh. The target\'s current resolution is: ' + isResolutionBad);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkCamera(options, pending) {
|
|
||||||
if (!cameraAvailable) {
|
|
||||||
pending('Skipping because this test requires a functioning camera on the Android device/emulator, and this test suite\'s functional camera test failed on your target environment.');
|
|
||||||
} else if (isAndroid7 && options.allowEdit) {
|
|
||||||
// TODO: Check if it is fixed some day
|
|
||||||
pending('Skipping because can\'t test with allowEdit=true on Android 7: getting unexpected "Camera cancelled" message.');
|
|
||||||
} else if (isAndroid7 && (options.sourceType !== cameraConstants.PictureSourceType.CAMERA)) {
|
|
||||||
pending('Skipping because can\'t click on the gallery tile on Android 7.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
afterAll(function (done) {
|
|
||||||
checkSession(done);
|
|
||||||
driver
|
|
||||||
.quit()
|
|
||||||
.done(done);
|
|
||||||
}, MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.util configuring driver and starting a session', function (done) {
|
|
||||||
// retry up to 3 times
|
|
||||||
getDriver()
|
|
||||||
.fail(function () {
|
|
||||||
return getDriver()
|
|
||||||
.fail(function () {
|
|
||||||
return getDriver()
|
|
||||||
.fail(fail);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
appiumSessionStarted = true;
|
|
||||||
})
|
|
||||||
.done(done);
|
|
||||||
}, 30 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.util determine screen dimensions', function (done) {
|
|
||||||
checkSession(done, /*skipResolutionCheck?*/ true); // skip the resolution check here since we are about to find out in this spec!
|
|
||||||
driver
|
|
||||||
.context(CONTEXT_NATIVE_APP)
|
|
||||||
.getWindowSize()
|
|
||||||
.then(function (size) {
|
|
||||||
screenWidth = Number(size.width);
|
|
||||||
screenHeight = Number(size.height);
|
|
||||||
isResolutionBad = false;
|
|
||||||
/*
|
|
||||||
TODO: what are acceptable resolution values?
|
|
||||||
need to check what the emulators used in CI return.
|
|
||||||
and also what local device definitions work and dont
|
|
||||||
*/
|
|
||||||
})
|
|
||||||
.done(done);
|
|
||||||
}, MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.util determine camera availability', function (done) {
|
|
||||||
checkSession(done);
|
|
||||||
var opts = {
|
|
||||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
|
||||||
saveToPhotoAlbum: false
|
|
||||||
};
|
|
||||||
|
|
||||||
return driver
|
|
||||||
.then(function () {
|
|
||||||
return getPicture(opts);
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
cameraAvailable = true;
|
|
||||||
}, function () {
|
|
||||||
return recreateSession();
|
|
||||||
})
|
|
||||||
.done(done);
|
|
||||||
}, 5 * MINUTE);
|
|
||||||
|
|
||||||
describe('Specs.', function () {
|
|
||||||
// getPicture() with saveToPhotoLibrary = true
|
|
||||||
it('camera.ui.spec.1 Saving a picture to the photo library', function (done) {
|
|
||||||
var opts = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
|
||||||
saveToPhotoAlbum: true
|
|
||||||
};
|
|
||||||
checkSession(done);
|
|
||||||
checkCamera(opts, pending);
|
|
||||||
|
|
||||||
var spec = generateSpec(opts);
|
|
||||||
tryRunSpec(spec)
|
|
||||||
.then(function () {
|
|
||||||
isTestPictureSaved = true;
|
|
||||||
})
|
|
||||||
.done(done);
|
|
||||||
}, 10 * MINUTE);
|
|
||||||
|
|
||||||
// getPicture() with mediaType: VIDEO, sourceType: PHOTOLIBRARY
|
|
||||||
it('camera.ui.spec.2 Selecting only videos', function (done) {
|
|
||||||
checkSession(done);
|
|
||||||
var spec = function () {
|
|
||||||
var options = { sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
|
||||||
mediaType: cameraConstants.MediaType.VIDEO };
|
|
||||||
return driver
|
|
||||||
.then(function () {
|
|
||||||
return getPicture(options, true);
|
|
||||||
})
|
|
||||||
.context(CONTEXT_NATIVE_APP)
|
|
||||||
.then(function () {
|
|
||||||
// try to find "Gallery" menu item
|
|
||||||
// if there's none, the gallery should be already opened
|
|
||||||
return driver
|
|
||||||
.waitForElementByAndroidUIAutomator('new UiSelector().text("Gallery")', 20000)
|
|
||||||
.then(function (element) {
|
|
||||||
return element.click();
|
|
||||||
}, function () {
|
|
||||||
return driver;
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
// if the gallery is opened on the videos page,
|
|
||||||
// there should be a "Choose video" or "Select video" caption
|
|
||||||
var videoSelector = isAndroid7 ? 'new UiSelector().text("Select video")' : 'new UiSelector().text("Choose video")';
|
|
||||||
return driver
|
|
||||||
.elementByAndroidUIAutomator(videoSelector)
|
|
||||||
.fail(function () {
|
|
||||||
throw 'Couldn\'t find a "Choose/select video" element.';
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.deviceKeyEvent(BACK_BUTTON)
|
|
||||||
.elementByAndroidUIAutomator('new UiSelector().text("Gallery")')
|
|
||||||
.deviceKeyEvent(BACK_BUTTON)
|
|
||||||
.finally(function () {
|
|
||||||
return driver
|
|
||||||
.elementById('action_bar_title')
|
|
||||||
.then(function () {
|
|
||||||
// success means we're still in native app
|
|
||||||
return driver
|
|
||||||
.deviceKeyEvent(BACK_BUTTON)
|
|
||||||
// give native app some time to close
|
|
||||||
.sleep(2000)
|
|
||||||
// try again! because every ~30th build
|
|
||||||
// on Sauce Labs this backbutton doesn't work
|
|
||||||
.elementById('action_bar_title')
|
|
||||||
.then(function () {
|
|
||||||
// success means we're still in native app
|
|
||||||
return driver
|
|
||||||
.deviceKeyEvent(BACK_BUTTON);
|
|
||||||
}, function () {
|
|
||||||
// error means we're already in webview
|
|
||||||
return driver;
|
|
||||||
});
|
|
||||||
}, function () {
|
|
||||||
// error means we're already in webview
|
|
||||||
return driver;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
tryRunSpec(spec).done(done);
|
|
||||||
}, 10 * MINUTE);
|
|
||||||
|
|
||||||
// getPicture(), then dismiss
|
|
||||||
// wait for the error callback to be called
|
|
||||||
it('camera.ui.spec.3 Dismissing the camera', function (done) {
|
|
||||||
var options = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: true,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
|
||||||
destinationType: cameraConstants.DestinationType.FILE_URI
|
|
||||||
};
|
|
||||||
checkSession(done);
|
|
||||||
checkCamera(options, pending);
|
|
||||||
var spec = function () {
|
|
||||||
return driver
|
|
||||||
.then(function () {
|
|
||||||
return getPicture(options, true);
|
|
||||||
})
|
|
||||||
.context(CONTEXT_NATIVE_APP)
|
|
||||||
.waitForElementByAndroidUIAutomator('new UiSelector().resourceIdMatches(".*cancel.*")', MINUTE / 2)
|
|
||||||
.click()
|
|
||||||
.then(function () {
|
|
||||||
return checkPicture(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
tryRunSpec(spec).done(done);
|
|
||||||
}, 10 * MINUTE);
|
|
||||||
|
|
||||||
// getPicture(), then take picture but dismiss the edit
|
|
||||||
// wait for the error callback to be called
|
|
||||||
it('camera.ui.spec.4 Dismissing the edit', function (done) {
|
|
||||||
var options = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: true,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
|
||||||
destinationType: cameraConstants.DestinationType.FILE_URI
|
|
||||||
};
|
|
||||||
checkSession(done);
|
|
||||||
checkCamera(options, pending);
|
|
||||||
var spec = function () {
|
|
||||||
return driver
|
|
||||||
.then(function () {
|
|
||||||
return getPicture(options, true);
|
|
||||||
})
|
|
||||||
.waitForElementByAndroidUIAutomator('new UiSelector().resourceIdMatches(".*shutter.*")', MINUTE / 2)
|
|
||||||
.click()
|
|
||||||
.waitForElementByAndroidUIAutomator('new UiSelector().resourceIdMatches(".*done.*")', MINUTE / 2)
|
|
||||||
.click()
|
|
||||||
.then(function () {
|
|
||||||
if (isAndroid7 && options.allowEdit) {
|
|
||||||
return driver
|
|
||||||
.waitForElementByAndroidUIAutomator('new UiSelector().text("Crop picture");', 20000)
|
|
||||||
.click()
|
|
||||||
.waitForElementByAndroidUIAutomator('new UiSelector().text("JUST ONCE");', 20000)
|
|
||||||
.click()
|
|
||||||
.deviceKeyEvent(BACK_BUTTON);
|
|
||||||
}
|
|
||||||
return driver
|
|
||||||
.waitForElementByAndroidUIAutomator('new UiSelector().resourceIdMatches(".*discard.*")', MINUTE / 2)
|
|
||||||
.click();
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
return checkPicture(false);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
tryRunSpec(spec).done(done);
|
|
||||||
}, 10 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.5 Verifying target image size, sourceType=CAMERA', function (done) {
|
|
||||||
var opts = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 210,
|
|
||||||
targetHeight: 210
|
|
||||||
};
|
|
||||||
checkSession(done);
|
|
||||||
checkCamera(opts, pending);
|
|
||||||
var spec = generateSpec(opts);
|
|
||||||
|
|
||||||
tryRunSpec(spec).done(done);
|
|
||||||
}, 10 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.6 Verifying target image size, sourceType=PHOTOLIBRARY', function (done) {
|
|
||||||
var opts = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 210,
|
|
||||||
targetHeight: 210
|
|
||||||
};
|
|
||||||
checkSession(done);
|
|
||||||
checkCamera(opts, pending);
|
|
||||||
var spec = generateSpec(opts);
|
|
||||||
|
|
||||||
tryRunSpec(spec).done(done);
|
|
||||||
}, 10 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.7 Verifying target image size, sourceType=CAMERA, DestinationType=NATIVE_URI', function (done) {
|
|
||||||
var opts = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: true,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
|
||||||
destinationType: cameraConstants.DestinationType.NATIVE_URI,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 210,
|
|
||||||
targetHeight: 210
|
|
||||||
};
|
|
||||||
checkSession(done);
|
|
||||||
checkCamera(opts, pending);
|
|
||||||
var spec = generateSpec(opts);
|
|
||||||
|
|
||||||
tryRunSpec(spec).done(done);
|
|
||||||
}, 10 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.8 Verifying target image size, sourceType=PHOTOLIBRARY, DestinationType=NATIVE_URI', function (done) {
|
|
||||||
var opts = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
|
||||||
destinationType: cameraConstants.DestinationType.NATIVE_URI,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 210,
|
|
||||||
targetHeight: 210
|
|
||||||
};
|
|
||||||
checkSession(done);
|
|
||||||
checkCamera(opts, pending);
|
|
||||||
|
|
||||||
var spec = generateSpec(opts);
|
|
||||||
tryRunSpec(spec).done(done);
|
|
||||||
}, 10 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.9 Verifying target image size, sourceType=CAMERA, DestinationType=NATIVE_URI, quality=100', function (done) {
|
|
||||||
var opts = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: true,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
|
||||||
destinationType: cameraConstants.DestinationType.NATIVE_URI,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 305,
|
|
||||||
targetHeight: 305
|
|
||||||
};
|
|
||||||
checkSession(done);
|
|
||||||
checkCamera(opts, pending);
|
|
||||||
var spec = generateSpec(opts);
|
|
||||||
|
|
||||||
tryRunSpec(spec).done(done);
|
|
||||||
}, 10 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.10 Verifying target image size, sourceType=PHOTOLIBRARY, DestinationType=NATIVE_URI, quality=100', function (done) {
|
|
||||||
var opts = {
|
|
||||||
quality: 100,
|
|
||||||
allowEdit: true,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
|
||||||
destinationType: cameraConstants.DestinationType.NATIVE_URI,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 305,
|
|
||||||
targetHeight: 305
|
|
||||||
};
|
|
||||||
checkSession(done);
|
|
||||||
checkCamera(opts, pending);
|
|
||||||
var spec = generateSpec(opts);
|
|
||||||
|
|
||||||
tryRunSpec(spec).done(done);
|
|
||||||
}, 10 * MINUTE);
|
|
||||||
|
|
||||||
// combine various options for getPicture()
|
|
||||||
generateOptions().forEach(function (spec) {
|
|
||||||
it('camera.ui.spec.11.' + spec.id + ' Combining options. ' + spec.description, function (done) {
|
|
||||||
checkSession(done);
|
|
||||||
checkCamera(spec.options, pending);
|
|
||||||
|
|
||||||
var s = generateSpec(spec.options);
|
|
||||||
tryRunSpec(s).done(done);
|
|
||||||
}, 10 * MINUTE);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('camera.ui.util Delete filler picture from device library', function (done) {
|
|
||||||
if (isAndroid7 || global.USE_SAUCE) {
|
|
||||||
pending();
|
|
||||||
}
|
|
||||||
driver
|
|
||||||
.context(webviewContext)
|
|
||||||
.deleteFillerImage(fillerImagePath)
|
|
||||||
.done(done);
|
|
||||||
}, MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.util Delete taken picture from device library', function (done) {
|
|
||||||
if (isAndroid7 || global.USE_SAUCE) {
|
|
||||||
pending();
|
|
||||||
}
|
|
||||||
checkSession(done);
|
|
||||||
if (!isTestPictureSaved) {
|
|
||||||
// couldn't save test picture earlier, so nothing to delete here
|
|
||||||
done();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// delete exactly one latest picture
|
|
||||||
// this should be the picture we've taken in the first spec
|
|
||||||
driver
|
|
||||||
.context(CONTEXT_NATIVE_APP)
|
|
||||||
.deviceKeyEvent(BACK_BUTTON)
|
|
||||||
.sleep(1000)
|
|
||||||
.deviceKeyEvent(BACK_BUTTON)
|
|
||||||
.sleep(1000)
|
|
||||||
.deviceKeyEvent(BACK_BUTTON)
|
|
||||||
.elementById('Apps')
|
|
||||||
.click()
|
|
||||||
.then(function () {
|
|
||||||
return driver
|
|
||||||
.elementByXPath('//android.widget.Button[@text="OK"]')
|
|
||||||
.click()
|
|
||||||
.fail(function () {
|
|
||||||
// no cling is all right
|
|
||||||
// it is not a brand new emulator, then
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.elementByAndroidUIAutomator('new UiSelector().text("Gallery")')
|
|
||||||
.click()
|
|
||||||
.elementByAndroidUIAutomator('new UiSelector().textContains("Pictures")')
|
|
||||||
.click()
|
|
||||||
.then(deleteImage)
|
|
||||||
.deviceKeyEvent(BACK_BUTTON)
|
|
||||||
.sleep(1000)
|
|
||||||
.deviceKeyEvent(BACK_BUTTON)
|
|
||||||
.sleep(1000)
|
|
||||||
.deviceKeyEvent(BACK_BUTTON)
|
|
||||||
.fail(fail)
|
|
||||||
.finally(done);
|
|
||||||
}, 3 * MINUTE);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
@ -1,311 +0,0 @@
|
|||||||
/* global Q, resolveLocalFileSystemURL, Camera, cordova */
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var cameraConstants = require('../../www/CameraConstants');
|
|
||||||
|
|
||||||
function findKeyByValue(set, value) {
|
|
||||||
for (var k in set) {
|
|
||||||
if (set.hasOwnProperty(k)) {
|
|
||||||
if (set[k] == value) {
|
|
||||||
return k;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDescription(spec) {
|
|
||||||
var desc = '';
|
|
||||||
|
|
||||||
desc += 'sourceType: ' + findKeyByValue(cameraConstants.PictureSourceType, spec.options.sourceType);
|
|
||||||
desc += ', destinationType: ' + findKeyByValue(cameraConstants.DestinationType, spec.options.destinationType);
|
|
||||||
desc += ', encodingType: ' + findKeyByValue(cameraConstants.EncodingType, spec.options.encodingType);
|
|
||||||
desc += ', allowEdit: ' + spec.options.allowEdit.toString();
|
|
||||||
desc += ', correctOrientation: ' + spec.options.correctOrientation.toString();
|
|
||||||
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.generateSpecs = function (sourceTypes, destinationTypes, encodingTypes, allowEditOptions, correctOrientationOptions) {
|
|
||||||
var destinationType,
|
|
||||||
sourceType,
|
|
||||||
encodingType,
|
|
||||||
allowEdit,
|
|
||||||
correctOrientation,
|
|
||||||
specs = [],
|
|
||||||
id = 1;
|
|
||||||
for (destinationType in destinationTypes) {
|
|
||||||
if (destinationTypes.hasOwnProperty(destinationType)) {
|
|
||||||
for (sourceType in sourceTypes) {
|
|
||||||
if (sourceTypes.hasOwnProperty(sourceType)) {
|
|
||||||
for (encodingType in encodingTypes) {
|
|
||||||
if (encodingTypes.hasOwnProperty(encodingType)) {
|
|
||||||
for (allowEdit in allowEditOptions) {
|
|
||||||
if (allowEditOptions.hasOwnProperty(allowEdit)) {
|
|
||||||
for (correctOrientation in correctOrientationOptions) {
|
|
||||||
// if taking picture from photolibrary, don't vary 'correctOrientation' option
|
|
||||||
if ((sourceTypes[sourceType] === cameraConstants.PictureSourceType.PHOTOLIBRARY ||
|
|
||||||
sourceTypes[sourceType] === cameraConstants.PictureSourceType.SAVEDPHOTOALBUM) &&
|
|
||||||
correctOrientation === true) { continue; }
|
|
||||||
var spec = {
|
|
||||||
'id': id++,
|
|
||||||
'options': {
|
|
||||||
'destinationType': destinationTypes[destinationType],
|
|
||||||
'sourceType': sourceTypes[sourceType],
|
|
||||||
'encodingType': encodingTypes[encodingType],
|
|
||||||
'allowEdit': allowEditOptions[allowEdit],
|
|
||||||
'saveToPhotoAlbum': false,
|
|
||||||
'correctOrientation': correctOrientationOptions[correctOrientation]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
spec.description = getDescription(spec);
|
|
||||||
specs.push(spec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return specs;
|
|
||||||
};
|
|
||||||
|
|
||||||
// calls getPicture() and saves the result in promise
|
|
||||||
// note that this function is executed in the context of tested app
|
|
||||||
// and not in the context of tests
|
|
||||||
module.exports.getPicture = function (opts, pid) {
|
|
||||||
if (navigator._appiumPromises[pid - 1]) {
|
|
||||||
navigator._appiumPromises[pid - 1] = null;
|
|
||||||
}
|
|
||||||
navigator._appiumPromises[pid] = Q.defer();
|
|
||||||
navigator.camera.getPicture(function (result) {
|
|
||||||
navigator._appiumPromises[pid].resolve(result);
|
|
||||||
}, function (err) {
|
|
||||||
navigator._appiumPromises[pid].reject(err);
|
|
||||||
}, opts);
|
|
||||||
};
|
|
||||||
|
|
||||||
// verifies taken picture when the promise is resolved,
|
|
||||||
// calls a callback with 'OK' if everything is good,
|
|
||||||
// calls a callback with 'ERROR: <error message>' if something is wrong
|
|
||||||
// note that this function is executed in the context of tested app
|
|
||||||
// and not in the context of tests
|
|
||||||
module.exports.checkPicture = function (pid, options, skipContentCheck, cb) {
|
|
||||||
var isIos = cordova.platformId === "ios";
|
|
||||||
var isAndroid = cordova.platformId === "android";
|
|
||||||
// skip image type check if it's unmodified on Android:
|
|
||||||
// https://github.com/apache/cordova-plugin-camera/#android-quirks-1
|
|
||||||
var skipFileTypeCheckAndroid = isAndroid && options.quality === 100 &&
|
|
||||||
!options.targetWidth && !options.targetHeight &&
|
|
||||||
!options.correctOrientation;
|
|
||||||
|
|
||||||
// Skip image type check if destination is NATIVE_URI and source - device's photoalbum
|
|
||||||
// https://github.com/apache/cordova-plugin-camera/#ios-quirks-1
|
|
||||||
var skipFileTypeCheckiOS = isIos && options.destinationType === Camera.DestinationType.NATIVE_URI &&
|
|
||||||
(options.sourceType === Camera.PictureSourceType.PHOTOLIBRARY ||
|
|
||||||
options.sourceType === Camera.PictureSourceType.SAVEDPHOTOALBUM);
|
|
||||||
|
|
||||||
var skipFileTypeCheck = skipFileTypeCheckAndroid || skipFileTypeCheckiOS;
|
|
||||||
|
|
||||||
var desiredType = 'JPEG';
|
|
||||||
var mimeType = 'image/jpeg';
|
|
||||||
if (options.encodingType === Camera.EncodingType.PNG) {
|
|
||||||
desiredType = 'PNG';
|
|
||||||
mimeType = 'image/png';
|
|
||||||
}
|
|
||||||
|
|
||||||
function errorCallback(msg) {
|
|
||||||
if (msg.hasOwnProperty('message')) {
|
|
||||||
msg = msg.message;
|
|
||||||
}
|
|
||||||
cb('ERROR: ' + msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// verifies the image we get from plugin
|
|
||||||
function verifyResult(result) {
|
|
||||||
if (result.length === 0) {
|
|
||||||
errorCallback('The result is empty.');
|
|
||||||
return;
|
|
||||||
} else if (isIos && options.destinationType === Camera.DestinationType.NATIVE_URI && result.indexOf('assets-library:') !== 0) {
|
|
||||||
errorCallback('Expected "' + result.substring(0, 150) + '"to start with "assets-library:"');
|
|
||||||
return;
|
|
||||||
} else if (isIos && options.destinationType === Camera.DestinationType.FILE_URI && result.indexOf('file:') !== 0) {
|
|
||||||
errorCallback('Expected "' + result.substring(0, 150) + '"to start with "file:"');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
window.atob(result);
|
|
||||||
// if we got here it is a base64 string (DATA_URL)
|
|
||||||
result = "data:" + mimeType + ";base64," + result;
|
|
||||||
} catch (e) {
|
|
||||||
// not DATA_URL
|
|
||||||
if (options.destinationType === Camera.DestinationType.DATA_URL) {
|
|
||||||
errorCallback('Expected ' + result.substring(0, 150) + 'not to be DATA_URL');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (result.indexOf('file:') === 0 ||
|
|
||||||
result.indexOf('content:') === 0 ||
|
|
||||||
result.indexOf('assets-library:') === 0) {
|
|
||||||
|
|
||||||
if (!window.resolveLocalFileSystemURL) {
|
|
||||||
errorCallback('Cannot read file. Please install cordova-plugin-file to fix this.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (skipContentCheck) {
|
|
||||||
cb('OK');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolveLocalFileSystemURL(result, function (entry) {
|
|
||||||
if (skipFileTypeCheck) {
|
|
||||||
displayFile(entry);
|
|
||||||
} else {
|
|
||||||
verifyFile(entry);
|
|
||||||
}
|
|
||||||
}, function (err) {
|
|
||||||
errorCallback(err);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
displayImage(result);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
errorCallback(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// verifies that the file type matches the requested type
|
|
||||||
function verifyFile(entry) {
|
|
||||||
try {
|
|
||||||
var reader = new FileReader();
|
|
||||||
reader.onloadend = function(e) {
|
|
||||||
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
|
|
||||||
var header = '';
|
|
||||||
for(var i = 0; i < arr.length; i++) {
|
|
||||||
header += arr[i].toString(16);
|
|
||||||
}
|
|
||||||
var actualType = 'unknown';
|
|
||||||
|
|
||||||
switch (header) {
|
|
||||||
case "89504e47":
|
|
||||||
actualType = 'PNG';
|
|
||||||
break;
|
|
||||||
case 'ffd8ffe0':
|
|
||||||
case 'ffd8ffe1':
|
|
||||||
case 'ffd8ffe2':
|
|
||||||
actualType = 'JPEG';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (actualType === desiredType) {
|
|
||||||
displayFile(entry);
|
|
||||||
} else {
|
|
||||||
errorCallback('File type mismatch. Expected ' + desiredType + ', got ' + actualType);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
reader.onerror = function (e) {
|
|
||||||
errorCallback(e);
|
|
||||||
};
|
|
||||||
entry.file(function (file) {
|
|
||||||
reader.readAsArrayBuffer(file);
|
|
||||||
}, function (e) {
|
|
||||||
errorCallback(e);
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
errorCallback(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// reads the file, then displays the image
|
|
||||||
function displayFile(entry) {
|
|
||||||
function onFileReceived(file) {
|
|
||||||
var reader = new FileReader();
|
|
||||||
reader.onerror = function (e) {
|
|
||||||
errorCallback(e);
|
|
||||||
};
|
|
||||||
reader.onloadend = function (evt) {
|
|
||||||
displayImage(evt.target.result);
|
|
||||||
};
|
|
||||||
reader.readAsDataURL(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
entry.file(onFileReceived, function (e) {
|
|
||||||
errorCallback(e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function displayImage(image) {
|
|
||||||
try {
|
|
||||||
var imgEl = document.getElementById('camera_test_image');
|
|
||||||
if (!imgEl) {
|
|
||||||
imgEl = document.createElement('img');
|
|
||||||
imgEl.id = 'camera_test_image';
|
|
||||||
document.body.appendChild(imgEl);
|
|
||||||
}
|
|
||||||
var timedOut = false;
|
|
||||||
var loadTimeout = setTimeout(function () {
|
|
||||||
timedOut = true;
|
|
||||||
imgEl.src = '';
|
|
||||||
errorCallback('The image did not load: ' + image.substring(0, 150));
|
|
||||||
}, 10000);
|
|
||||||
var done = function (status) {
|
|
||||||
if (!timedOut) {
|
|
||||||
clearTimeout(loadTimeout);
|
|
||||||
imgEl.src = '';
|
|
||||||
cb(status);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
imgEl.onload = function () {
|
|
||||||
try {
|
|
||||||
// aspect ratio is preserved so only one dimension should match
|
|
||||||
if ((typeof options.targetWidth === 'number' && imgEl.naturalWidth !== options.targetWidth) &&
|
|
||||||
(typeof options.targetHeight === 'number' && imgEl.naturalHeight !== options.targetHeight))
|
|
||||||
{
|
|
||||||
done('ERROR: Wrong image size: ' + imgEl.naturalWidth + 'x' + imgEl.naturalHeight +
|
|
||||||
'. Requested size: ' + options.targetWidth + 'x' + options.targetHeight);
|
|
||||||
} else {
|
|
||||||
done('OK');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
errorCallback(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
imgEl.src = image;
|
|
||||||
} catch (e) {
|
|
||||||
errorCallback(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
navigator._appiumPromises[pid].promise
|
|
||||||
.then(function (result) {
|
|
||||||
verifyResult(result);
|
|
||||||
})
|
|
||||||
.fail(function (e) {
|
|
||||||
errorCallback(e);
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,512 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one
|
|
||||||
* or more contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. The ASF licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
// these tests are meant to be executed by Cordova Paramedic test runner
|
|
||||||
// you can find it here: https://github.com/apache/cordova-paramedic/
|
|
||||||
// it is not necessary to do a full CI setup to run these tests
|
|
||||||
// just run "node cordova-paramedic/main.js --platform ios --plugin cordova-plugin-camera"
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var wdHelper = global.WD_HELPER;
|
|
||||||
var screenshotHelper = global.SCREENSHOT_HELPER;
|
|
||||||
var isDevice = global.DEVICE;
|
|
||||||
var cameraConstants = require('../../www/CameraConstants');
|
|
||||||
var cameraHelper = require('../helpers/cameraHelper');
|
|
||||||
|
|
||||||
var MINUTE = 60 * 1000;
|
|
||||||
var DEFAULT_WEBVIEW_CONTEXT = 'WEBVIEW_1';
|
|
||||||
var PROMISE_PREFIX = 'appium_camera_promise_';
|
|
||||||
var CONTEXT_NATIVE_APP = 'NATIVE_APP';
|
|
||||||
|
|
||||||
describe('Camera tests iOS.', function () {
|
|
||||||
var driver;
|
|
||||||
var webviewContext = DEFAULT_WEBVIEW_CONTEXT;
|
|
||||||
// promise count to use in promise ID
|
|
||||||
var promiseCount = 0;
|
|
||||||
// going to set this to false if session is created successfully
|
|
||||||
var failedToStart = true;
|
|
||||||
// points out which UI automation to use
|
|
||||||
var isXCUI = false;
|
|
||||||
// spec counter to restart the session
|
|
||||||
var specsRun = 0;
|
|
||||||
|
|
||||||
function getNextPromiseId() {
|
|
||||||
promiseCount += 1;
|
|
||||||
return getCurrentPromiseId();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCurrentPromiseId() {
|
|
||||||
return PROMISE_PREFIX + promiseCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
function gracefullyFail(error) {
|
|
||||||
fail(error);
|
|
||||||
return driver
|
|
||||||
.quit()
|
|
||||||
.then(function () {
|
|
||||||
return getDriver();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// generates test specs by combining all the specified options
|
|
||||||
// you can add more options to test more scenarios
|
|
||||||
function generateOptions() {
|
|
||||||
var sourceTypes = cameraConstants.PictureSourceType;
|
|
||||||
var destinationTypes = cameraConstants.DestinationType;
|
|
||||||
var encodingTypes = cameraConstants.EncodingType;
|
|
||||||
var allowEditOptions = [ true, false ];
|
|
||||||
var correctOrientationOptions = [ true, false ];
|
|
||||||
|
|
||||||
return cameraHelper.generateSpecs(sourceTypes, destinationTypes, encodingTypes, allowEditOptions, correctOrientationOptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
function usePicture(allowEdit) {
|
|
||||||
return driver
|
|
||||||
.sleep(10)
|
|
||||||
.then(function () {
|
|
||||||
if (isXCUI) {
|
|
||||||
return driver.waitForElementByAccessibilityId('Choose', MINUTE / 3).click();
|
|
||||||
} else {
|
|
||||||
if (allowEdit) {
|
|
||||||
return wdHelper.tapElementByXPath('//UIAButton[@label="Choose"]', driver);
|
|
||||||
}
|
|
||||||
return driver.elementByXPath('//*[@label="Use"]').click();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function clickPhoto() {
|
|
||||||
if (isXCUI) {
|
|
||||||
// iOS >=10
|
|
||||||
return driver
|
|
||||||
.context(CONTEXT_NATIVE_APP)
|
|
||||||
.elementsByXPath('//XCUIElementTypeCell')
|
|
||||||
.then(function(photos) {
|
|
||||||
if (photos.length == 0) {
|
|
||||||
return driver
|
|
||||||
.sleep(0) // driver.source is not a function o.O
|
|
||||||
.source()
|
|
||||||
.then(function (src) {
|
|
||||||
console.log(src);
|
|
||||||
gracefullyFail('Couldn\'t find an image to click');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// intentionally clicking the second photo here
|
|
||||||
// the first one is not clickable for some reason
|
|
||||||
return photos[1].click();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// iOS <10
|
|
||||||
return driver
|
|
||||||
.elementByXPath('//UIACollectionCell')
|
|
||||||
.click();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPicture(options, cancelCamera, skipUiInteractions) {
|
|
||||||
var promiseId = getNextPromiseId();
|
|
||||||
if (!options) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
// assign defaults
|
|
||||||
if (!options.hasOwnProperty('allowEdit')) {
|
|
||||||
options.allowEdit = true;
|
|
||||||
}
|
|
||||||
if (!options.hasOwnProperty('destinationType')) {
|
|
||||||
options.destinationType = cameraConstants.DestinationType.FILE_URI;
|
|
||||||
}
|
|
||||||
if (!options.hasOwnProperty('sourceType')) {
|
|
||||||
options.destinationType = cameraConstants.PictureSourceType.CAMERA;
|
|
||||||
}
|
|
||||||
|
|
||||||
return driver
|
|
||||||
.context(webviewContext)
|
|
||||||
.execute(cameraHelper.getPicture, [options, promiseId])
|
|
||||||
.context(CONTEXT_NATIVE_APP)
|
|
||||||
.then(function () {
|
|
||||||
if (skipUiInteractions) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (options.hasOwnProperty('sourceType') && options.sourceType === cameraConstants.PictureSourceType.PHOTOLIBRARY) {
|
|
||||||
return driver
|
|
||||||
.waitForElementByAccessibilityId('Camera Roll', MINUTE / 2)
|
|
||||||
.click()
|
|
||||||
.then(function () {
|
|
||||||
return clickPhoto();
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
if (!options.allowEdit) {
|
|
||||||
return driver;
|
|
||||||
}
|
|
||||||
return usePicture(options.allowEdit);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (options.hasOwnProperty('sourceType') && options.sourceType === cameraConstants.PictureSourceType.SAVEDPHOTOALBUM) {
|
|
||||||
return clickPhoto()
|
|
||||||
.then(function () {
|
|
||||||
if (!options.allowEdit) {
|
|
||||||
return driver;
|
|
||||||
}
|
|
||||||
return usePicture(options.allowEdit);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (cancelCamera) {
|
|
||||||
return driver
|
|
||||||
.waitForElementByAccessibilityId('Cancel', MINUTE / 2)
|
|
||||||
.click();
|
|
||||||
}
|
|
||||||
return driver
|
|
||||||
.waitForElementByAccessibilityId('Take Picture', MINUTE / 2)
|
|
||||||
.click()
|
|
||||||
.waitForElementByAccessibilityId('Use Photo', MINUTE / 2)
|
|
||||||
.click();
|
|
||||||
})
|
|
||||||
.fail(fail);
|
|
||||||
}
|
|
||||||
|
|
||||||
// checks if the picture was successfully taken
|
|
||||||
// if shouldLoad is falsy, ensures that the error callback was called
|
|
||||||
function checkPicture(shouldLoad, options) {
|
|
||||||
if (!options) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
return driver
|
|
||||||
.context(webviewContext)
|
|
||||||
.setAsyncScriptTimeout(MINUTE / 2)
|
|
||||||
.executeAsync(cameraHelper.checkPicture, [getCurrentPromiseId(), options, false])
|
|
||||||
.then(function (result) {
|
|
||||||
if (shouldLoad) {
|
|
||||||
if (result !== 'OK') {
|
|
||||||
fail(result);
|
|
||||||
}
|
|
||||||
} else if (result.indexOf('ERROR') === -1) {
|
|
||||||
throw 'Unexpected success callback with result: ' + result;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// takes a picture with the specified options
|
|
||||||
// and then verifies it
|
|
||||||
function runSpec(options, done, pending) {
|
|
||||||
if (options.sourceType === cameraConstants.PictureSourceType.CAMERA && !isDevice) {
|
|
||||||
pending('Camera is not available on iOS simulator');
|
|
||||||
}
|
|
||||||
checkSession(done);
|
|
||||||
specsRun += 1;
|
|
||||||
return driver
|
|
||||||
.then(function () {
|
|
||||||
return getPicture(options);
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
return checkPicture(true, options);
|
|
||||||
})
|
|
||||||
.fail(gracefullyFail);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDriver() {
|
|
||||||
failedToStart = true;
|
|
||||||
driver = wdHelper.getDriver('iOS');
|
|
||||||
return wdHelper.getWebviewContext(driver)
|
|
||||||
.then(function(context) {
|
|
||||||
webviewContext = context;
|
|
||||||
return driver.context(webviewContext);
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
return wdHelper.waitForDeviceReady(driver);
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
return wdHelper.injectLibraries(driver);
|
|
||||||
})
|
|
||||||
.sessionCapabilities()
|
|
||||||
.then(function (caps) {
|
|
||||||
var platformVersion = parseFloat(caps.platformVersion);
|
|
||||||
isXCUI = platformVersion >= 10.0;
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
var options = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.SAVEDPHOTOALBUM,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 210,
|
|
||||||
targetHeight: 210
|
|
||||||
};
|
|
||||||
return driver
|
|
||||||
.then(function () { return getPicture(options, false, true); })
|
|
||||||
.context(CONTEXT_NATIVE_APP)
|
|
||||||
.acceptAlert()
|
|
||||||
.then(function alertDismissed() {
|
|
||||||
// TODO: once we move to only XCUITest-based (which is force on you in either iOS 10+ or Xcode 8+)
|
|
||||||
// UI tests, we will have to:
|
|
||||||
// a) remove use of autoAcceptAlerts appium capability since it no longer functions in XCUITest
|
|
||||||
// b) can remove this entire then() clause, as we do not need to explicitly handle the acceptAlert
|
|
||||||
// failure callback, since we will be guaranteed to hit the permission dialog on startup.
|
|
||||||
}, function noAlert() {
|
|
||||||
// in case the contacts permission alert never showed up: no problem, don't freak out.
|
|
||||||
// This can happen if:
|
|
||||||
// a) The application-under-test already had photos permissions granted to it
|
|
||||||
// b) Appium's autoAcceptAlerts capability is provided (and functioning)
|
|
||||||
})
|
|
||||||
.elementByAccessibilityId('Cancel', 10000)
|
|
||||||
.click();
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
failedToStart = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkSession(done) {
|
|
||||||
if (failedToStart) {
|
|
||||||
fail('Failed to start a session');
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
it('camera.ui.util configure driver and start a session', function (done) {
|
|
||||||
// retry up to 3 times
|
|
||||||
getDriver()
|
|
||||||
.fail(function () {
|
|
||||||
return getDriver()
|
|
||||||
.fail(function () {
|
|
||||||
return getDriver()
|
|
||||||
.fail(fail);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.fail(fail)
|
|
||||||
.done(done);
|
|
||||||
}, 30 * MINUTE);
|
|
||||||
|
|
||||||
describe('Specs.', function () {
|
|
||||||
afterEach(function (done) {
|
|
||||||
if (specsRun >= 19) {
|
|
||||||
specsRun = 0;
|
|
||||||
// we need to restart the session regularly because for some reason
|
|
||||||
// when running against iOS 10 simulator on SauceLabs,
|
|
||||||
// Appium cannot handle more than ~20 specs at one session
|
|
||||||
// the error would be as follows:
|
|
||||||
// "Could not proxy command to remote server. Original error: Error: connect ECONNREFUSED 127.0.0.1:8100"
|
|
||||||
checkSession(done);
|
|
||||||
return driver
|
|
||||||
.quit()
|
|
||||||
.then(function () {
|
|
||||||
return getDriver()
|
|
||||||
.fail(function () {
|
|
||||||
return getDriver()
|
|
||||||
.fail(function () {
|
|
||||||
return getDriver()
|
|
||||||
.fail(fail);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.done(done);
|
|
||||||
} else {
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
}, 30 * MINUTE);
|
|
||||||
|
|
||||||
// getPicture() with mediaType: VIDEO, sourceType: PHOTOLIBRARY
|
|
||||||
it('camera.ui.spec.1 Selecting only videos', function (done) {
|
|
||||||
checkSession(done);
|
|
||||||
specsRun += 1;
|
|
||||||
var options = { sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
|
||||||
mediaType: cameraConstants.MediaType.VIDEO };
|
|
||||||
driver
|
|
||||||
// skip ui unteractions
|
|
||||||
.then(function () { return getPicture(options, false, true); })
|
|
||||||
.waitForElementByXPath('//*[contains(@label,"Videos")]', MINUTE / 2)
|
|
||||||
.elementByAccessibilityId('Cancel')
|
|
||||||
.click()
|
|
||||||
.fail(gracefullyFail)
|
|
||||||
.done(done);
|
|
||||||
}, 7 * MINUTE);
|
|
||||||
|
|
||||||
// getPicture(), then dismiss
|
|
||||||
// wait for the error callback to be called
|
|
||||||
it('camera.ui.spec.2 Dismissing the camera', function (done) {
|
|
||||||
checkSession(done);
|
|
||||||
if (!isDevice) {
|
|
||||||
pending('Camera is not available on iOS simulator');
|
|
||||||
}
|
|
||||||
specsRun += 1;
|
|
||||||
var options = { sourceType: cameraConstants.PictureSourceType.CAMERA,
|
|
||||||
saveToPhotoAlbum: false };
|
|
||||||
driver
|
|
||||||
.then(function () {
|
|
||||||
return getPicture(options, true);
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
return checkPicture(false);
|
|
||||||
})
|
|
||||||
.fail(gracefullyFail)
|
|
||||||
.done(done);
|
|
||||||
}, 7 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.3 Verifying target image size, sourceType=CAMERA', function (done) {
|
|
||||||
var options = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 210,
|
|
||||||
targetHeight: 210
|
|
||||||
};
|
|
||||||
|
|
||||||
runSpec(options, done, pending).done(done);
|
|
||||||
}, 7 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.4 Verifying target image size, sourceType=SAVEDPHOTOALBUM', function (done) {
|
|
||||||
var options = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.SAVEDPHOTOALBUM,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 210,
|
|
||||||
targetHeight: 210
|
|
||||||
};
|
|
||||||
|
|
||||||
runSpec(options, done, pending).done(done);
|
|
||||||
}, 7 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.5 Verifying target image size, sourceType=PHOTOLIBRARY', function (done) {
|
|
||||||
var options = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 210,
|
|
||||||
targetHeight: 210
|
|
||||||
};
|
|
||||||
|
|
||||||
runSpec(options, done, pending).done(done);
|
|
||||||
}, 7 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.6 Verifying target image size, sourceType=CAMERA, destinationType=FILE_URL', function (done) {
|
|
||||||
// remove this line if you don't mind the tests leaving a photo saved on device
|
|
||||||
pending('Cannot prevent iOS from saving the picture to photo library');
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
|
||||||
destinationType: cameraConstants.DestinationType.FILE_URL,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 210,
|
|
||||||
targetHeight: 210
|
|
||||||
};
|
|
||||||
|
|
||||||
runSpec(options, done, pending).done(done);
|
|
||||||
}, 7 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.7 Verifying target image size, sourceType=SAVEDPHOTOALBUM, destinationType=FILE_URL', function (done) {
|
|
||||||
var options = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.SAVEDPHOTOALBUM,
|
|
||||||
destinationType: cameraConstants.DestinationType.FILE_URL,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 210,
|
|
||||||
targetHeight: 210
|
|
||||||
};
|
|
||||||
|
|
||||||
runSpec(options, done, pending).done(done);
|
|
||||||
}, 7 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.8 Verifying target image size, sourceType=PHOTOLIBRARY, destinationType=FILE_URL', function (done) {
|
|
||||||
var options = {
|
|
||||||
quality: 50,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
|
||||||
destinationType: cameraConstants.DestinationType.FILE_URL,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 210,
|
|
||||||
targetHeight: 210
|
|
||||||
};
|
|
||||||
|
|
||||||
runSpec(options, done, pending).done(done);
|
|
||||||
}, 7 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.9 Verifying target image size, sourceType=CAMERA, destinationType=FILE_URL, quality=100', function (done) {
|
|
||||||
// remove this line if you don't mind the tests leaving a photo saved on device
|
|
||||||
pending('Cannot prevent iOS from saving the picture to photo library');
|
|
||||||
|
|
||||||
var options = {
|
|
||||||
quality: 100,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
|
||||||
destinationType: cameraConstants.DestinationType.FILE_URL,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 305,
|
|
||||||
targetHeight: 305
|
|
||||||
};
|
|
||||||
runSpec(options, done, pending).done(done);
|
|
||||||
}, 7 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.10 Verifying target image size, sourceType=SAVEDPHOTOALBUM, destinationType=FILE_URL, quality=100', function (done) {
|
|
||||||
var options = {
|
|
||||||
quality: 100,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.SAVEDPHOTOALBUM,
|
|
||||||
destinationType: cameraConstants.DestinationType.FILE_URL,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 305,
|
|
||||||
targetHeight: 305
|
|
||||||
};
|
|
||||||
|
|
||||||
runSpec(options, done, pending).done(done);
|
|
||||||
}, 7 * MINUTE);
|
|
||||||
|
|
||||||
it('camera.ui.spec.11 Verifying target image size, sourceType=PHOTOLIBRARY, destinationType=FILE_URL, quality=100', function (done) {
|
|
||||||
var options = {
|
|
||||||
quality: 100,
|
|
||||||
allowEdit: false,
|
|
||||||
sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
|
||||||
destinationType: cameraConstants.DestinationType.FILE_URL,
|
|
||||||
saveToPhotoAlbum: false,
|
|
||||||
targetWidth: 305,
|
|
||||||
targetHeight: 305
|
|
||||||
};
|
|
||||||
|
|
||||||
runSpec(options, done, pending).done(done);
|
|
||||||
}, 7 * MINUTE);
|
|
||||||
|
|
||||||
// combine various options for getPicture()
|
|
||||||
generateOptions().forEach(function (spec) {
|
|
||||||
it('camera.ui.spec.12.' + spec.id + ' Combining options. ' + spec.description, function (done) {
|
|
||||||
// remove this check if you don't mind the tests leaving a photo saved on device
|
|
||||||
if (spec.options.sourceType === cameraConstants.PictureSourceType.CAMERA &&
|
|
||||||
spec.options.destinationType === cameraConstants.DestinationType.NATIVE_URI) {
|
|
||||||
pending('Skipping: cannot prevent iOS from saving the picture to photo library and cannot delete it. ' +
|
|
||||||
'For more info, see iOS quirks here: https://github.com/apache/cordova-plugin-camera#ios-quirks-1');
|
|
||||||
}
|
|
||||||
|
|
||||||
runSpec(spec.options, done, pending).done(done);
|
|
||||||
}, 7 * MINUTE);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it('camera.ui.util Destroy the session', function (done) {
|
|
||||||
checkSession(done);
|
|
||||||
driver
|
|
||||||
.quit()
|
|
||||||
.done(done);
|
|
||||||
}, 5 * MINUTE);
|
|
||||||
});
|
|
Loading…
Reference in New Issue
Block a user