diff --git a/appium-tests/android/android.spec.js b/appium-tests/android/android.spec.js index 25f662c..e6dec6d 100644 --- a/appium-tests/android/android.spec.js +++ b/appium-tests/android/android.spec.js @@ -52,6 +52,8 @@ describe('Camera tests Android.', function () { var screenHeight = DEFAULT_SCREEN_HEIGHT; // promise count to use in promise ID var promiseCount = 0; + // going to set this to false if session is created successfully + var failedToStart = true; function getNextPromiseId() { promiseCount += 1; @@ -127,10 +129,18 @@ describe('Camera tests Android.', function () { .performTouchAction(tapTile); } return driver + .waitForElementByXPath('//android.widget.TextView[@text="Gallery"]', 20000) + .elementByXPath('//android.widget.TextView[@text="Gallery"]') + .elementByXPath('//android.widget.TextView[@text="Gallery"]') + .elementByXPath('//android.widget.TextView[@text="Gallery"]') .elementByXPath('//android.widget.TextView[@text="Gallery"]') .fail(function () { return driver .performTouchAction(swipeRight) + .waitForElementByXPath('//android.widget.TextView[@text="Gallery"]', 20000) + .elementByXPath('//android.widget.TextView[@text="Gallery"]') + .elementByXPath('//android.widget.TextView[@text="Gallery"]') + .elementByXPath('//android.widget.TextView[@text="Gallery"]') .elementByXPath('//android.widget.TextView[@text="Gallery"]'); }) .click() @@ -140,9 +150,13 @@ describe('Camera tests Android.', function () { } // taking a picture from camera return driver - .waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]', MINUTE) + .waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]', MINUTE / 2) + .elementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]') + .elementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]') .click() - .waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]', MINUTE) + .waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]', MINUTE / 2) + .elementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]') + .elementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]') .click(); }) .then(function () { @@ -168,7 +182,7 @@ describe('Camera tests Android.', function () { } return driver .context(webviewContext) - .setAsyncScriptTimeout(MINUTE) + .setAsyncScriptTimeout(MINUTE / 2) .executeAsync(cameraHelper.checkPicture, [getCurrentPromiseId(), options]) .then(function (result) { if (shouldLoad) { @@ -253,13 +267,23 @@ describe('Camera tests Android.', function () { }; } + function checkSession(done) { + if (failedToStart) { + fail('Failed to start a session'); + done(); + } + } + it('camera.ui.util configuring driver and starting a session', function (done) { getDriver() - .fail(fail) + .then(function () { + failedToStart = false; + }, fail) .done(done); }, 5 * MINUTE); it('camera.ui.util determine screen dimensions', function (done) { + checkSession(done); return driver .context(webviewContext) .execute(function () { @@ -278,6 +302,7 @@ describe('Camera tests Android.', function () { describe('Specs.', function () { // getPicture() with saveToPhotoLibrary = true it('camera.ui.spec.1 Saving a picture to the photo library', function (done) { + checkSession(done); var spec = generateSpec({ quality: 50, allowEdit: false, @@ -294,6 +319,7 @@ describe('Camera tests Android.', function () { // 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 }; @@ -306,6 +332,8 @@ describe('Camera tests Android.', function () { // try to find "Gallery" menu item // if there's none, the gallery should be already opened return driver + .waitForElementByXPath('//android.widget.TextView[@text="Gallery"]', 20000) + .elementByXPath('//android.widget.TextView[@text="Gallery"]') .elementByXPath('//android.widget.TextView[@text="Gallery"]') .then(function (element) { return element.click(); @@ -344,6 +372,7 @@ describe('Camera tests Android.', function () { // getPicture(), then dismiss // wait for the error callback to be called it('camera.ui.spec.3 Dismissing the camera', function (done) { + checkSession(done); var spec = function () { var options = { quality: 50, @@ -357,6 +386,8 @@ describe('Camera tests Android.', function () { }) .context("NATIVE_APP") .waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'cancel\')]', MINUTE / 2) + .elementByXPath('//android.widget.ImageView[contains(@resource-id,\'cancel\')]') + .elementByXPath('//android.widget.ImageView[contains(@resource-id,\'cancel\')]') .click() .then(function () { return checkPicture(false); @@ -369,6 +400,7 @@ describe('Camera tests Android.', function () { // 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) { + checkSession(done); var spec = function () { var options = { quality: 50, @@ -382,10 +414,16 @@ describe('Camera tests Android.', function () { }) .context('NATIVE_APP') .waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]', MINUTE / 2) + .elementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]') + .elementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]') .click() .waitForElementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]', MINUTE / 2) + .elementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]') + .elementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]') .click() .waitForElementByXPath('//*[contains(@resource-id,\'discard\')]', MINUTE / 2) + .elementByXPath('//*[contains(@resource-id,\'discard\')]') + .elementByXPath('//*[contains(@resource-id,\'discard\')]') .click() .then(function () { return checkPicture(false); @@ -396,6 +434,7 @@ describe('Camera tests Android.', function () { }, 10 * MINUTE); it('camera.ui.spec.5 Verifying target image size, sourceType=CAMERA', function (done) { + checkSession(done); var spec = generateSpec({ quality: 50, allowEdit: false, @@ -409,6 +448,7 @@ describe('Camera tests Android.', function () { }, 10 * MINUTE); it('camera.ui.spec.6 Verifying target image size, sourceType=PHOTOLIBRARY', function (done) { + checkSession(done); var spec = generateSpec({ quality: 50, allowEdit: false, @@ -422,6 +462,7 @@ describe('Camera tests Android.', function () { }, 10 * MINUTE); it('camera.ui.spec.7 Verifying target image size, sourceType=CAMERA, DestinationType=NATIVE_URI', function (done) { + checkSession(done); var spec = generateSpec({ quality: 50, allowEdit: false, @@ -436,6 +477,7 @@ describe('Camera tests Android.', function () { }, 10 * MINUTE); it('camera.ui.spec.8 Verifying target image size, sourceType=PHOTOLIBRARY, DestinationType=NATIVE_URI', function (done) { + checkSession(done); var spec = generateSpec({ quality: 50, allowEdit: false, @@ -450,6 +492,7 @@ describe('Camera tests Android.', function () { }, 10 * MINUTE); it('camera.ui.spec.9 Verifying target image size, sourceType=CAMERA, DestinationType=NATIVE_URI, quality=100', function (done) { + checkSession(done); var spec = generateSpec({ quality: 100, allowEdit: true, @@ -464,6 +507,7 @@ describe('Camera tests Android.', function () { }, 10 * MINUTE); it('camera.ui.spec.10 Verifying target image size, sourceType=PHOTOLIBRARY, DestinationType=NATIVE_URI, quality=100', function (done) { + checkSession(done); var spec = generateSpec({ quality: 100, allowEdit: true, @@ -480,12 +524,14 @@ describe('Camera tests Android.', function () { // combine various options for getPicture() generateOptions().forEach(function (spec) { it('camera.ui.spec.11.' + spec.id + ' Combining options. ' + spec.description, function (done) { + checkSession(done); var s = generateSpec(spec.options); tryRunSpec(s).done(done); }, 10 * MINUTE); }); it('camera.ui.util Delete test image from device library', function (done) { + checkSession(done); if (!isTestPictureSaved) { // couldn't save test picture earlier, so nothing to delete here done(); @@ -518,6 +564,7 @@ describe('Camera tests Android.', function () { }); it('camera.ui.util Destroy the session', function (done) { + checkSession(done); driver .quit() .done(done); diff --git a/appium-tests/helpers/cameraHelper.js b/appium-tests/helpers/cameraHelper.js index 544a9e7..5f60bc3 100644 --- a/appium-tests/helpers/cameraHelper.js +++ b/appium-tests/helpers/cameraHelper.js @@ -247,18 +247,22 @@ module.exports.checkPicture = function (pid, options, cb) { function displayImage(image) { try { - var imgEl = document.createElement('img'); - document.body.appendChild(imgEl); + 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; - document.body.removeChild(imgEl); + imgEl.src = ''; errorCallback('The image did not load: ' + image.substring(0, 150)); }, 10000); var done = function (status) { if (!timedOut) { clearTimeout(loadTimeout); - document.body.removeChild(imgEl); + imgEl.src = ''; cb(status); } }; diff --git a/appium-tests/ios/ios.spec.js b/appium-tests/ios/ios.spec.js index 3f5a68c..224190e 100644 --- a/appium-tests/ios/ios.spec.js +++ b/appium-tests/ios/ios.spec.js @@ -30,7 +30,6 @@ var wdHelper = global.WD_HELPER; var screenshotHelper = global.SCREENSHOT_HELPER; -var wd = wdHelper.getWD(); var isDevice = global.DEVICE; var cameraConstants = require('../../www/CameraConstants'); var cameraHelper = require('../helpers/cameraHelper'); @@ -44,6 +43,8 @@ describe('Camera tests iOS.', function () { 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; function getNextPromiseId() { promiseCount += 1; @@ -127,12 +128,14 @@ describe('Camera tests iOS.', function () { if (cancelCamera) { return driver .waitForElementByXPath('//*[@label="Cancel"]', MINUTE / 2) + .elementByXPath('//*[@label="Cancel"]') + .elementByXPath('//*[@label="Cancel"]') .click(); } return driver .waitForElementByXPath('//*[@label="Take Picture"]', MINUTE / 2) .click() - .elementByXPath('//*[@label="Use Photo"]') + .waitForElementByXPath('//*[@label="Use Photo"]', MINUTE / 2) .click(); }) .fail(fail); @@ -146,7 +149,7 @@ describe('Camera tests iOS.', function () { } return driver .context(webviewContext) - .setAsyncScriptTimeout(MINUTE) + .setAsyncScriptTimeout(MINUTE / 2) .executeAsync(cameraHelper.checkPicture, [getCurrentPromiseId(), options]) .then(function (result) { if (shouldLoad) { @@ -187,15 +190,25 @@ describe('Camera tests iOS.', function () { }); } + function checkSession(done) { + if (failedToStart) { + fail('Failed to start a session'); + done(); + } + } + it('camera.ui.util configure driver and start a session', function (done) { getDriver() - .fail(fail) - .finally(done); + .then(function () { + failedToStart = false; + }, fail) + .done(done); }, 5 * MINUTE); describe('Specs.', function () { // getPicture() with mediaType: VIDEO, sourceType: PHOTOLIBRARY it('camera.ui.spec.1 Selecting only videos', function (done) { + checkSession(done); var options = { sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY, mediaType: cameraConstants.MediaType.VIDEO }; driver @@ -211,10 +224,12 @@ describe('Camera tests iOS.', function () { // 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'); } - var options = { sourceType: cameraConstants.PictureSourceType.CAMERA }; + var options = { sourceType: cameraConstants.PictureSourceType.CAMERA, + saveToPhotoAlbum: false }; driver .then(function () { return getPicture(options, true); @@ -227,6 +242,7 @@ describe('Camera tests iOS.', function () { }, 3 * MINUTE); it('camera.ui.spec.3 Verifying target image size, sourceType=CAMERA', function (done) { + checkSession(done); if (!isDevice) { pending('Camera is not available on iOS simulator'); } @@ -243,6 +259,7 @@ describe('Camera tests iOS.', function () { }, 3 * MINUTE); it('camera.ui.spec.4 Verifying target image size, sourceType=SAVEDPHOTOALBUM', function (done) { + checkSession(done); var options = { quality: 50, allowEdit: false, @@ -256,6 +273,7 @@ describe('Camera tests iOS.', function () { }, 3 * MINUTE); it('camera.ui.spec.5 Verifying target image size, sourceType=PHOTOLIBRARY', function (done) { + checkSession(done); var options = { quality: 50, allowEdit: false, @@ -269,6 +287,10 @@ describe('Camera tests iOS.', function () { }, 3 * MINUTE); it('camera.ui.spec.6 Verifying target image size, sourceType=CAMERA, destinationType=NATIVE_URI', 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'); + + checkSession(done); if (!isDevice) { pending('Camera is not available on iOS simulator'); } @@ -286,6 +308,7 @@ describe('Camera tests iOS.', function () { }, 3 * MINUTE); it('camera.ui.spec.7 Verifying target image size, sourceType=SAVEDPHOTOALBUM, destinationType=NATIVE_URI', function (done) { + checkSession(done); var options = { quality: 50, allowEdit: false, @@ -300,6 +323,7 @@ describe('Camera tests iOS.', function () { }, 3 * MINUTE); it('camera.ui.spec.8 Verifying target image size, sourceType=PHOTOLIBRARY, destinationType=NATIVE_URI', function (done) { + checkSession(done); var options = { quality: 50, allowEdit: false, @@ -314,6 +338,10 @@ describe('Camera tests iOS.', function () { }, 3 * MINUTE); it('camera.ui.spec.9 Verifying target image size, sourceType=CAMERA, destinationType=NATIVE_URI, 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'); + + checkSession(done); if (!isDevice) { pending('Camera is not available on iOS simulator'); } @@ -330,6 +358,7 @@ describe('Camera tests iOS.', function () { }, 3 * MINUTE); it('camera.ui.spec.10 Verifying target image size, sourceType=SAVEDPHOTOALBUM, destinationType=NATIVE_URI, quality=100', function (done) { + checkSession(done); var options = { quality: 100, allowEdit: false, @@ -344,6 +373,7 @@ describe('Camera tests iOS.', function () { }, 3 * MINUTE); it('camera.ui.spec.11 Verifying target image size, sourceType=PHOTOLIBRARY, destinationType=NATIVE_URI, quality=100', function (done) { + checkSession(done); var options = { quality: 100, allowEdit: false, @@ -360,9 +390,12 @@ describe('Camera tests iOS.', function () { // combine various options for getPicture() generateOptions().forEach(function (spec) { it('camera.ui.spec.12.' + spec.id + ' Combining options. ' + spec.description, function (done) { + checkSession(done); if (!isDevice && spec.options.sourceType === cameraConstants.PictureSourceType.CAMERA) { pending('Camera is not available on iOS simulator'); } + + // 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. ' + @@ -376,6 +409,7 @@ describe('Camera tests iOS.', function () { }); it('camera.ui.util Destroy the session', function (done) { + checkSession(done); driver .quit() .done(done);