2016-02-22 23:37:41 +08:00
/*jshint node: true, jasmine: true */
2016-04-21 19:16:47 +08:00
2016-03-09 11:21:47 +08:00
/ *
*
* 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 .
*
* /
2016-02-04 23:55:57 +08:00
2016-12-17 06:33:59 +08:00
// these tests are meant to be executed by Cordova ParaMedic Appium runner
// you can find it here: https://github.com/apache/cordova-paramedic/
2016-02-04 23:55:57 +08:00
// it is not necessary to do a full CI setup to run these tests
2016-12-17 06:33:59 +08:00
// 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.
2016-02-04 23:55:57 +08:00
2016-02-22 23:37:41 +08:00
'use strict' ;
2016-04-13 17:42:51 +08:00
var wdHelper = global . WD _HELPER ;
var screenshotHelper = global . SCREENSHOT _HELPER ;
2016-02-04 23:55:57 +08:00
var wd = wdHelper . getWD ( ) ;
var cameraConstants = require ( '../../www/CameraConstants' ) ;
var cameraHelper = require ( '../helpers/cameraHelper' ) ;
2016-02-22 23:37:41 +08:00
var MINUTE = 60 * 1000 ;
2016-04-13 17:42:51 +08:00
var BACK _BUTTON = 4 ;
2016-02-22 23:37:41 +08:00
var DEFAULT _SCREEN _WIDTH = 360 ;
var DEFAULT _SCREEN _HEIGHT = 567 ;
var DEFAULT _WEBVIEW _CONTEXT = 'WEBVIEW' ;
2016-04-13 17:42:51 +08:00
var PROMISE _PREFIX = 'appium_camera_promise_' ;
2017-02-23 22:32:23 +08:00
var CONTEXT _NATIVE _APP = 'NATIVE_APP' ;
2016-02-04 23:55:57 +08:00
describe ( 'Camera tests Android.' , function ( ) {
2016-02-22 23:37:41 +08:00
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 ;
2016-03-01 23:27:08 +08:00
// we need to know the screen width and height to properly click on an image in the gallery:
2016-02-22 23:37:41 +08:00
var screenWidth = DEFAULT _SCREEN _WIDTH ;
var screenHeight = DEFAULT _SCREEN _HEIGHT ;
2016-04-13 17:42:51 +08:00
// promise count to use in promise ID
var promiseCount = 0 ;
2016-06-28 21:20:24 +08:00
// determine if Appium session is created successfully
var appiumSessionStarted = false ;
// determine if camera is present on the device/emulator
var cameraAvailable = false ;
2016-12-17 06:33:59 +08:00
// determine if emulator is within a range of acceptable resolutions able to run these tests
var isResolutionBad = true ;
2016-06-28 21:20:24 +08:00
// a path to the image we add to the gallery before test run
var fillerImagePath ;
2017-06-02 20:02:01 +08:00
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 ) ;
}
}
2016-02-04 23:55:57 +08:00
2016-04-13 17:42:51 +08:00
function getNextPromiseId ( ) {
promiseCount += 1 ;
return getCurrentPromiseId ( ) ;
2016-02-04 23:55:57 +08:00
}
2016-04-13 17:42:51 +08:00
function getCurrentPromiseId ( ) {
return PROMISE _PREFIX + promiseCount ;
}
2017-02-23 22:32:23 +08:00
function gracefullyFail ( error ) {
2016-04-13 17:42:51 +08:00
fail ( error ) ;
2017-02-23 22:32:23 +08:00
return driver
2016-04-13 17:42:51 +08:00
. quit ( )
. then ( function ( ) {
return getDriver ( ) ;
} ) ;
2016-02-04 23:55:57 +08:00
}
2016-05-18 16:48:29 +08:00
// combinines specified options in all possible variations
2016-02-22 23:37:41 +08:00
// you can add more options to test more scenarios
2016-05-18 16:48:29 +08:00
function generateOptions ( ) {
2016-02-04 23:55:57 +08:00
var sourceTypes = [
cameraConstants . PictureSourceType . CAMERA ,
cameraConstants . PictureSourceType . PHOTOLIBRARY
] ;
2016-04-25 22:37:48 +08:00
var destinationTypes = cameraConstants . DestinationType ;
var encodingTypes = cameraConstants . EncodingType ;
var allowEditOptions = [ true , false ] ;
var correctOrientationOptions = [ true , false ] ;
2016-02-04 23:55:57 +08:00
2016-04-25 22:37:48 +08:00
return cameraHelper . generateSpecs ( sourceTypes , destinationTypes , encodingTypes , allowEditOptions , correctOrientationOptions ) ;
2016-02-04 23:55:57 +08:00
}
2016-04-13 17:42:51 +08:00
// invokes Camera.getPicture() with the specified options
// and goes through all UI interactions unless 'skipUiInteractions' is true
function getPicture ( options , skipUiInteractions ) {
var promiseId = getNextPromiseId ( ) ;
2016-02-04 23:55:57 +08:00
if ( ! options ) {
options = { } ;
}
2017-07-10 17:07:38 +08:00
// 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 ;
}
2016-02-22 23:37:41 +08:00
2016-02-04 23:55:57 +08:00
return driver
2016-02-16 21:28:43 +08:00
. context ( webviewContext )
2016-04-13 17:42:51 +08:00
. execute ( cameraHelper . getPicture , [ options , promiseId ] )
2017-02-23 22:32:23 +08:00
. context ( CONTEXT _NATIVE _APP )
2016-02-04 23:55:57 +08:00
. then ( function ( ) {
if ( skipUiInteractions ) {
return ;
}
2016-04-13 17:42:51 +08:00
// selecting a picture from gallery
2016-02-04 23:55:57 +08:00
if ( options . hasOwnProperty ( 'sourceType' ) &&
( options . sourceType === cameraConstants . PictureSourceType . PHOTOLIBRARY ||
options . sourceType === cameraConstants . PictureSourceType . SAVEDPHOTOALBUM ) ) {
2016-04-13 17:42:51 +08:00
var tapTile = new wd . TouchAction ( ) ;
var swipeRight = new wd . TouchAction ( ) ;
2016-04-21 19:16:47 +08:00
tapTile
. tap ( {
x : Math . round ( screenWidth / 4 ) ,
2016-08-02 18:05:01 +08:00
y : Math . round ( screenHeight / 4 )
2016-04-21 19:16:47 +08:00
} ) ;
swipeRight
2016-12-17 06:33:59 +08:00
. press ( { x : 10 , y : Math . round ( screenHeight / 4 ) } )
2016-02-16 21:28:43 +08:00
. wait ( 300 )
2016-08-02 18:05:01 +08:00
. moveTo ( { x : Math . round ( screenWidth - ( screenWidth / 8 ) ) , y : 0 } )
2016-08-02 23:11:19 +08:00
. wait ( 1500 )
2016-04-21 19:16:47 +08:00
. release ( )
. wait ( 1000 ) ;
if ( options . allowEdit ) {
return driver
// always wait before performing touchAction
. sleep ( 7000 )
. performTouchAction ( tapTile ) ;
}
2016-02-04 23:55:57 +08:00
return driver
2017-02-23 22:32:23 +08:00
. waitForElementByAndroidUIAutomator ( 'new UiSelector().text("Gallery");' , 20000 )
2016-04-13 17:42:51 +08:00
. fail ( function ( ) {
2016-12-17 06:33:59 +08:00
// If the Gallery button is not present, swipe right to reveal the Gallery button!
2016-04-13 17:42:51 +08:00
return driver
. performTouchAction ( swipeRight )
2017-02-23 22:32:23 +08:00
. waitForElementByAndroidUIAutomator ( 'new UiSelector().text("Gallery");' , 20000 )
2016-04-13 17:42:51 +08:00
} )
2016-04-21 19:16:47 +08:00
. click ( )
// always wait before performing touchAction
. sleep ( 7000 )
2016-04-13 17:42:51 +08:00
. performTouchAction ( tapTile ) ;
2016-02-04 23:55:57 +08:00
}
2016-04-13 17:42:51 +08:00
// taking a picture from camera
2016-02-04 23:55:57 +08:00
return driver
2017-02-23 22:32:23 +08:00
. waitForElementByAndroidUIAutomator ( 'new UiSelector().resourceIdMatches(".*shutter.*")' , MINUTE / 2 )
2016-02-22 23:37:41 +08:00
. click ( )
2017-02-23 22:32:23 +08:00
. waitForElementByAndroidUIAutomator ( 'new UiSelector().resourceIdMatches(".*done.*")' , MINUTE / 2 )
2017-06-02 20:02:01 +08:00
. 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 ;
} ) ;
2016-02-04 23:55:57 +08:00
} )
. then ( function ( ) {
if ( skipUiInteractions ) {
return ;
}
2016-04-13 17:42:51 +08:00
if ( options . allowEdit ) {
2017-06-02 20:02:01 +08:00
var saveText = isAndroid7 ? 'SAVE' : 'Save' ;
2016-02-04 23:55:57 +08:00
return driver
2017-06-02 20:02:01 +08:00
. waitForElementByAndroidUIAutomator ( 'new UiSelector().text("' + saveText + '")' , MINUTE )
2016-02-04 23:55:57 +08:00
. click ( ) ;
}
} )
2016-04-21 19:16:47 +08:00
. fail ( function ( failure ) {
2016-04-27 23:02:48 +08:00
throw failure ;
2016-04-21 19:16:47 +08:00
} ) ;
2016-02-04 23:55:57 +08:00
}
2016-04-13 17:42:51 +08:00
// checks if the picture was successfully taken
// if shouldLoad is falsy, ensures that the error callback was called
2016-05-18 16:48:29 +08:00
function checkPicture ( shouldLoad , options ) {
if ( ! options ) {
options = { } ;
}
2016-02-04 23:55:57 +08:00
return driver
2016-02-16 21:28:43 +08:00
. context ( webviewContext )
2016-05-19 23:08:07 +08:00
. setAsyncScriptTimeout ( MINUTE / 2 )
2017-06-02 20:02:01 +08:00
. executeAsync ( cameraHelper . checkPicture , [ getCurrentPromiseId ( ) , options , isAndroid7 ] )
2016-04-13 17:42:51 +08:00
. then ( function ( result ) {
if ( shouldLoad ) {
2016-05-18 16:48:29 +08:00
if ( result !== 'OK' ) {
fail ( result ) ;
2016-02-04 23:55:57 +08:00
}
2016-05-18 16:48:29 +08:00
} else if ( result . indexOf ( 'ERROR' ) === - 1 ) {
throw 'Unexpected success callback with result: ' + result ;
2016-02-04 23:55:57 +08:00
}
} ) ;
}
2016-04-13 17:42:51 +08:00
// deletes the latest image from the gallery
2016-02-04 23:55:57 +08:00
function deleteImage ( ) {
var holdTile = new wd . TouchAction ( ) ;
2016-12-17 06:33:59 +08:00
holdTile
. press ( { x : Math . round ( screenWidth / 4 ) , y : Math . round ( screenHeight / 5 ) } )
. wait ( 1000 )
. release ( ) ;
2016-02-04 23:55:57 +08:00
return driver
2016-04-21 19:16:47 +08:00
// always wait before performing touchAction
. sleep ( 7000 )
2016-02-04 23:55:57 +08:00
. performTouchAction ( holdTile )
2017-02-23 22:32:23 +08:00
. elementByAndroidUIAutomator ( 'new UiSelector().text("Delete")' )
2016-02-04 23:55:57 +08:00
. then ( function ( element ) {
return element
. click ( )
2017-02-23 22:32:23 +08:00
. elementByAndroidUIAutomator ( 'new UiSelector().text("OK")' )
2016-02-04 23:55:57 +08:00
. click ( ) ;
} , function ( ) {
// couldn't find Delete menu item. Possibly there is no image.
2016-04-13 17:42:51 +08:00
return driver ;
2016-02-04 23:55:57 +08:00
} ) ;
}
2016-02-22 23:37:41 +08:00
function getDriver ( ) {
driver = wdHelper . getDriver ( 'Android' ) ;
2016-06-28 21:20:24 +08:00
return driver . getWebviewContext ( )
2016-04-13 17:42:51 +08:00
. then ( function ( context ) {
webviewContext = context ;
return driver . context ( webviewContext ) ;
} )
2016-06-28 21:20:24 +08:00
. waitForDeviceReady ( )
. injectLibraries ( )
2017-04-20 14:01:54 +08:00
. 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 ) ;
} )
2016-06-28 21:20:24 +08:00
. deleteFillerImage ( fillerImagePath )
2016-04-13 17:42:51 +08:00
. then ( function ( ) {
2016-06-28 21:20:24 +08:00
fillerImagePath = null ;
2016-04-13 17:42:51 +08:00
} )
2016-06-28 21:20:24 +08:00
. addFillerImage ( )
. then ( function ( result ) {
if ( result && result . indexOf ( 'ERROR:' ) === 0 ) {
throw new Error ( result ) ;
} else {
fillerImagePath = result ;
}
2016-04-13 17:42:51 +08:00
} ) ;
2016-02-22 23:37:41 +08:00
}
2016-04-27 23:02:48 +08:00
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 ) ;
} ) ;
} )
2017-02-23 22:32:23 +08:00
. fail ( gracefullyFail ) ;
2016-04-27 23:02:48 +08:00
}
2016-05-18 16:48:29 +08:00
// produces a generic spec function which
// takes a picture with specified options
// and then verifies it
function generateSpec ( options ) {
return function ( ) {
2016-04-27 23:02:48 +08:00
return driver
. then ( function ( ) {
2016-05-18 16:48:29 +08:00
return getPicture ( options ) ;
2016-04-27 23:02:48 +08:00
} )
. then ( function ( ) {
2016-05-18 16:48:29 +08:00
return checkPicture ( true , options ) ;
2016-04-27 23:02:48 +08:00
} ) ;
} ;
}
2016-12-17 06:33:59 +08:00
function checkSession ( done , skipResolutionCheck ) {
2016-06-28 21:20:24 +08:00
if ( ! appiumSessionStarted ) {
2016-12-17 06:33:59 +08:00
fail ( 'Failed to start a session ' + ( lastFailureReason ? lastFailureReason : '' ) ) ;
2016-05-19 23:08:07 +08:00
done ( ) ;
}
2016-12-17 06:33:59 +08:00
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 ) ;
}
2016-05-19 23:08:07 +08:00
}
2017-06-02 20:02:01 +08:00
function checkCamera ( options , pending ) {
2016-06-28 21:20:24 +08:00
if ( ! cameraAvailable ) {
2017-06-02 20:02:01 +08:00
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.' ) ;
2016-06-28 21:20:24 +08:00
}
}
2017-04-20 14:01:54 +08:00
2016-12-17 06:33:59 +08:00
afterAll ( function ( done ) {
checkSession ( done ) ;
driver
. quit ( )
. done ( done ) ;
} , MINUTE ) ;
2016-06-28 21:20:24 +08:00
2016-02-04 23:55:57 +08:00
it ( 'camera.ui.util configuring driver and starting a session' , function ( done ) {
2017-07-03 22:03:22 +08:00
// retry up to 3 times
2016-04-13 17:42:51 +08:00
getDriver ( )
2017-07-03 22:03:22 +08:00
. fail ( function ( ) {
return getDriver ( )
. fail ( function ( ) {
return getDriver ( )
. fail ( fail ) ;
} ) ;
} )
2016-05-19 23:08:07 +08:00
. then ( function ( ) {
2016-06-28 21:20:24 +08:00
appiumSessionStarted = true ;
2017-07-03 22:03:22 +08:00
} )
2016-04-13 17:42:51 +08:00
. done ( done ) ;
2017-07-03 22:03:22 +08:00
} , 30 * MINUTE ) ;
2016-02-16 21:28:43 +08:00
it ( 'camera.ui.util determine screen dimensions' , function ( done ) {
2016-12-17 06:33:59 +08:00
checkSession ( done , /*skipResolutionCheck?*/ true ) ; // skip the resolution check here since we are about to find out in this spec!
2016-06-28 21:20:24 +08:00
driver
2017-02-23 22:32:23 +08:00
. context ( CONTEXT _NATIVE _APP )
2016-12-17 06:33:59 +08:00
. getWindowSize ( )
2016-04-13 17:42:51 +08:00
. then ( function ( size ) {
screenWidth = Number ( size . width ) ;
screenHeight = Number ( size . height ) ;
2016-12-17 06:33:59 +08:00
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
* /
2016-02-16 21:28:43 +08:00
} )
2016-04-13 17:42:51 +08:00
. done ( done ) ;
2016-02-22 23:37:41 +08:00
} , MINUTE ) ;
2016-02-04 23:55:57 +08:00
2016-06-28 21:20:24 +08:00
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 ;
2016-08-02 18:05:01 +08:00
} , function ( ) {
return recreateSession ( ) ;
2016-06-28 21:20:24 +08:00
} )
2016-08-02 18:05:01 +08:00
. done ( done ) ;
2016-06-28 21:20:24 +08:00
} , 5 * MINUTE ) ;
2016-02-04 23:55:57 +08:00
describe ( 'Specs.' , function ( ) {
// getPicture() with saveToPhotoLibrary = true
2016-04-27 23:02:48 +08:00
it ( 'camera.ui.spec.1 Saving a picture to the photo library' , function ( done ) {
2017-06-02 20:02:01 +08:00
var opts = {
2016-05-18 16:48:29 +08:00
quality : 50 ,
allowEdit : false ,
sourceType : cameraConstants . PictureSourceType . CAMERA ,
saveToPhotoAlbum : true
2017-06-02 20:02:01 +08:00
} ;
checkSession ( done ) ;
checkCamera ( opts , pending ) ;
2016-04-27 23:02:48 +08:00
2017-06-02 20:02:01 +08:00
var spec = generateSpec ( opts ) ;
2016-05-18 16:48:29 +08:00
tryRunSpec ( spec )
. then ( function ( ) {
isTestPictureSaved = true ;
} )
2016-04-13 17:42:51 +08:00
. done ( done ) ;
2016-04-27 23:02:48 +08:00
} , 10 * MINUTE ) ;
2016-02-04 23:55:57 +08:00
// getPicture() with mediaType: VIDEO, sourceType: PHOTOLIBRARY
it ( 'camera.ui.spec.2 Selecting only videos' , function ( done ) {
2016-05-19 23:08:07 +08:00
checkSession ( done ) ;
2016-04-27 23:02:48 +08:00
var spec = function ( ) {
var options = { sourceType : cameraConstants . PictureSourceType . PHOTOLIBRARY ,
mediaType : cameraConstants . MediaType . VIDEO } ;
return driver
. then ( function ( ) {
return getPicture ( options , true ) ;
} )
2017-02-23 22:32:23 +08:00
. context ( CONTEXT _NATIVE _APP )
2016-04-27 23:02:48 +08:00
. then ( function ( ) {
// try to find "Gallery" menu item
// if there's none, the gallery should be already opened
return driver
2017-02-23 22:32:23 +08:00
. waitForElementByAndroidUIAutomator ( 'new UiSelector().text("Gallery")' , 20000 )
2016-04-27 23:02:48 +08:00
. then ( function ( element ) {
return element . click ( ) ;
} , function ( ) {
return driver ;
} ) ;
} )
. then ( function ( ) {
// if the gallery is opened on the videos page,
2017-06-02 20:02:01 +08:00
// there should be a "Choose video" or "Select video" caption
var videoSelector = isAndroid7 ? 'new UiSelector().text("Select video")' : 'new UiSelector().text("Choose video")' ;
2016-04-27 23:02:48 +08:00
return driver
2017-06-02 20:02:01 +08:00
. elementByAndroidUIAutomator ( videoSelector )
2016-04-27 23:02:48 +08:00
. fail ( function ( ) {
2017-06-02 20:02:01 +08:00
throw 'Couldn\'t find a "Choose/select video" element.' ;
2016-04-27 23:02:48 +08:00
} ) ;
} )
. deviceKeyEvent ( BACK _BUTTON )
2017-02-23 22:32:23 +08:00
. elementByAndroidUIAutomator ( 'new UiSelector().text("Gallery")' )
2016-04-27 23:02:48 +08:00
. deviceKeyEvent ( BACK _BUTTON )
. finally ( function ( ) {
return driver
. elementById ( 'action_bar_title' )
. then ( function ( ) {
// success means we're still in native app
return driver
2016-08-13 21:58:33 +08:00
. deviceKeyEvent ( BACK _BUTTON )
// give native app some time to close
2016-08-17 22:35:23 +08:00
. 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 ;
} ) ;
2016-04-27 23:02:48 +08:00
} , function ( ) {
// error means we're already in webview
return driver ;
} ) ;
} ) ;
} ;
2016-05-18 16:48:29 +08:00
tryRunSpec ( spec ) . done ( done ) ;
2016-04-27 23:02:48 +08:00
} , 10 * MINUTE ) ;
2016-02-04 23:55:57 +08:00
// getPicture(), then dismiss
2016-04-13 17:42:51 +08:00
// wait for the error callback to be called
2016-02-04 23:55:57 +08:00
it ( 'camera.ui.spec.3 Dismissing the camera' , function ( done ) {
2017-06-02 20:02:01 +08:00
var options = {
quality : 50 ,
allowEdit : true ,
sourceType : cameraConstants . PictureSourceType . CAMERA ,
destinationType : cameraConstants . DestinationType . FILE _URI
} ;
2016-05-19 23:08:07 +08:00
checkSession ( done ) ;
2017-06-02 20:02:01 +08:00
checkCamera ( options , pending ) ;
2016-04-27 23:02:48 +08:00
var spec = function ( ) {
return driver
. then ( function ( ) {
return getPicture ( options , true ) ;
} )
2017-02-23 22:32:23 +08:00
. context ( CONTEXT _NATIVE _APP )
. waitForElementByAndroidUIAutomator ( 'new UiSelector().resourceIdMatches(".*cancel.*")' , MINUTE / 2 )
2016-04-27 23:02:48 +08:00
. click ( )
. then ( function ( ) {
return checkPicture ( false ) ;
} ) ;
} ;
2016-05-18 16:48:29 +08:00
tryRunSpec ( spec ) . done ( done ) ;
2016-04-27 23:02:48 +08:00
} , 10 * MINUTE ) ;
2016-02-04 23:55:57 +08:00
// getPicture(), then take picture but dismiss the edit
2016-04-13 17:42:51 +08:00
// wait for the error callback to be called
2016-02-04 23:55:57 +08:00
it ( 'camera.ui.spec.4 Dismissing the edit' , function ( done ) {
2017-06-02 20:02:01 +08:00
var options = {
quality : 50 ,
allowEdit : true ,
sourceType : cameraConstants . PictureSourceType . CAMERA ,
destinationType : cameraConstants . DestinationType . FILE _URI
} ;
2016-05-19 23:08:07 +08:00
checkSession ( done ) ;
2017-06-02 20:02:01 +08:00
checkCamera ( options , pending ) ;
2016-04-27 23:02:48 +08:00
var spec = function ( ) {
return driver
. then ( function ( ) {
return getPicture ( options , true ) ;
} )
2017-02-23 22:32:23 +08:00
. waitForElementByAndroidUIAutomator ( 'new UiSelector().resourceIdMatches(".*shutter.*")' , MINUTE / 2 )
2016-04-27 23:02:48 +08:00
. click ( )
2017-02-23 22:32:23 +08:00
. waitForElementByAndroidUIAutomator ( 'new UiSelector().resourceIdMatches(".*done.*")' , MINUTE / 2 )
2016-04-27 23:02:48 +08:00
. click ( )
2017-06-02 20:02:01 +08:00
. 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 ( ) ;
} )
2016-04-27 23:02:48 +08:00
. then ( function ( ) {
return checkPicture ( false ) ;
} ) ;
} ;
2016-05-18 16:48:29 +08:00
tryRunSpec ( spec ) . done ( done ) ;
} , 10 * MINUTE ) ;
it ( 'camera.ui.spec.5 Verifying target image size, sourceType=CAMERA' , function ( done ) {
2017-06-02 20:02:01 +08:00
var opts = {
2016-05-18 16:48:29 +08:00
quality : 50 ,
allowEdit : false ,
sourceType : cameraConstants . PictureSourceType . CAMERA ,
saveToPhotoAlbum : false ,
targetWidth : 210 ,
targetHeight : 210
2017-06-02 20:02:01 +08:00
} ;
checkSession ( done ) ;
checkCamera ( opts , pending ) ;
var spec = generateSpec ( opts ) ;
2016-05-18 16:48:29 +08:00
tryRunSpec ( spec ) . done ( done ) ;
} , 10 * MINUTE ) ;
it ( 'camera.ui.spec.6 Verifying target image size, sourceType=PHOTOLIBRARY' , function ( done ) {
2017-06-02 20:02:01 +08:00
var opts = {
2016-05-18 16:48:29 +08:00
quality : 50 ,
allowEdit : false ,
sourceType : cameraConstants . PictureSourceType . PHOTOLIBRARY ,
saveToPhotoAlbum : false ,
targetWidth : 210 ,
targetHeight : 210
2017-06-02 20:02:01 +08:00
} ;
checkSession ( done ) ;
checkCamera ( opts , pending ) ;
var spec = generateSpec ( opts ) ;
2016-05-18 16:48:29 +08:00
tryRunSpec ( spec ) . done ( done ) ;
} , 10 * MINUTE ) ;
it ( 'camera.ui.spec.7 Verifying target image size, sourceType=CAMERA, DestinationType=NATIVE_URI' , function ( done ) {
2017-06-02 20:02:01 +08:00
var opts = {
2016-05-18 16:48:29 +08:00
quality : 50 ,
2017-06-02 20:02:01 +08:00
allowEdit : true ,
2016-05-18 16:48:29 +08:00
sourceType : cameraConstants . PictureSourceType . CAMERA ,
destinationType : cameraConstants . DestinationType . NATIVE _URI ,
saveToPhotoAlbum : false ,
targetWidth : 210 ,
targetHeight : 210
2017-06-02 20:02:01 +08:00
} ;
checkSession ( done ) ;
checkCamera ( opts , pending ) ;
var spec = generateSpec ( opts ) ;
2016-05-18 16:48:29 +08:00
tryRunSpec ( spec ) . done ( done ) ;
} , 10 * MINUTE ) ;
it ( 'camera.ui.spec.8 Verifying target image size, sourceType=PHOTOLIBRARY, DestinationType=NATIVE_URI' , function ( done ) {
2017-06-02 20:02:01 +08:00
var opts = {
2016-05-18 16:48:29 +08:00
quality : 50 ,
allowEdit : false ,
sourceType : cameraConstants . PictureSourceType . PHOTOLIBRARY ,
destinationType : cameraConstants . DestinationType . NATIVE _URI ,
saveToPhotoAlbum : false ,
targetWidth : 210 ,
targetHeight : 210
2017-06-02 20:02:01 +08:00
} ;
checkSession ( done ) ;
checkCamera ( opts , pending ) ;
2016-05-18 16:48:29 +08:00
2017-06-02 20:02:01 +08:00
var spec = generateSpec ( opts ) ;
2016-05-18 16:48:29 +08:00
tryRunSpec ( spec ) . done ( done ) ;
} , 10 * MINUTE ) ;
it ( 'camera.ui.spec.9 Verifying target image size, sourceType=CAMERA, DestinationType=NATIVE_URI, quality=100' , function ( done ) {
2017-06-02 20:02:01 +08:00
var opts = {
quality : 50 ,
2016-05-18 16:48:29 +08:00
allowEdit : true ,
sourceType : cameraConstants . PictureSourceType . CAMERA ,
destinationType : cameraConstants . DestinationType . NATIVE _URI ,
saveToPhotoAlbum : false ,
targetWidth : 305 ,
targetHeight : 305
2017-06-02 20:02:01 +08:00
} ;
checkSession ( done ) ;
checkCamera ( opts , pending ) ;
var spec = generateSpec ( opts ) ;
2016-05-18 16:48:29 +08:00
tryRunSpec ( spec ) . done ( done ) ;
} , 10 * MINUTE ) ;
it ( 'camera.ui.spec.10 Verifying target image size, sourceType=PHOTOLIBRARY, DestinationType=NATIVE_URI, quality=100' , function ( done ) {
2017-06-02 20:02:01 +08:00
var opts = {
2016-05-18 16:48:29 +08:00
quality : 100 ,
allowEdit : true ,
sourceType : cameraConstants . PictureSourceType . PHOTOLIBRARY ,
destinationType : cameraConstants . DestinationType . NATIVE _URI ,
saveToPhotoAlbum : false ,
targetWidth : 305 ,
targetHeight : 305
2017-06-02 20:02:01 +08:00
} ;
checkSession ( done ) ;
checkCamera ( opts , pending ) ;
var spec = generateSpec ( opts ) ;
2016-05-18 16:48:29 +08:00
tryRunSpec ( spec ) . done ( done ) ;
2016-04-27 23:02:48 +08:00
} , 10 * MINUTE ) ;
2016-02-04 23:55:57 +08:00
// combine various options for getPicture()
2016-05-18 16:48:29 +08:00
generateOptions ( ) . forEach ( function ( spec ) {
it ( 'camera.ui.spec.11.' + spec . id + ' Combining options. ' + spec . description , function ( done ) {
2016-05-19 23:08:07 +08:00
checkSession ( done ) ;
2017-06-02 20:02:01 +08:00
checkCamera ( spec . options , pending ) ;
2016-05-18 16:48:29 +08:00
var s = generateSpec ( spec . options ) ;
tryRunSpec ( s ) . done ( done ) ;
2016-04-27 23:02:48 +08:00
} , 10 * MINUTE ) ;
2016-02-04 23:55:57 +08:00
} ) ;
2016-06-28 21:20:24 +08:00
it ( 'camera.ui.util Delete filler picture from device library' , function ( done ) {
2017-06-02 20:02:01 +08:00
if ( isAndroid7 || global . USE _SAUCE ) {
pending ( ) ;
}
2016-06-28 21:20:24 +08:00
driver
. context ( webviewContext )
. deleteFillerImage ( fillerImagePath )
. done ( done ) ;
} , MINUTE ) ;
it ( 'camera.ui.util Delete taken picture from device library' , function ( done ) {
2017-06-02 20:02:01 +08:00
if ( isAndroid7 || global . USE _SAUCE ) {
pending ( ) ;
}
2016-05-19 23:08:07 +08:00
checkSession ( done ) ;
2016-04-13 17:42:51 +08:00
if ( ! isTestPictureSaved ) {
// couldn't save test picture earlier, so nothing to delete here
2016-02-04 23:55:57 +08:00
done ( ) ;
return ;
}
2016-04-13 17:42:51 +08:00
// delete exactly one latest picture
// this should be the picture we've taken in the first spec
2016-06-28 21:20:24 +08:00
driver
2017-02-23 22:32:23 +08:00
. context ( CONTEXT _NATIVE _APP )
2016-04-13 17:42:51 +08:00
. deviceKeyEvent ( BACK _BUTTON )
. sleep ( 1000 )
. deviceKeyEvent ( BACK _BUTTON )
. sleep ( 1000 )
. deviceKeyEvent ( BACK _BUTTON )
. elementById ( 'Apps' )
. click ( )
2017-03-30 22:52:15 +08:00
. 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
} ) ;
} )
2017-02-23 22:32:23 +08:00
. elementByAndroidUIAutomator ( 'new UiSelector().text("Gallery")' )
2016-04-13 17:42:51 +08:00
. click ( )
2017-02-23 22:32:23 +08:00
. elementByAndroidUIAutomator ( 'new UiSelector().textContains("Pictures")' )
2016-04-13 17:42:51 +08:00
. click ( )
. then ( deleteImage )
. deviceKeyEvent ( BACK _BUTTON )
. sleep ( 1000 )
. deviceKeyEvent ( BACK _BUTTON )
. sleep ( 1000 )
. deviceKeyEvent ( BACK _BUTTON )
. fail ( fail )
. finally ( done ) ;
2016-02-22 23:37:41 +08:00
} , 3 * MINUTE ) ;
2016-02-04 23:55:57 +08:00
} ) ;
} ) ;
2017-07-03 22:03:22 +08:00