CB-10397 Added Appium tests
This commit is contained in:
parent
77653183dd
commit
a060fb36f3
451
appium-tests/android/android.spec.js
Normal file
451
appium-tests/android/android.spec.js
Normal file
@ -0,0 +1,451 @@
|
|||||||
|
/*jslint node: true, plusplus: true */
|
||||||
|
/*global beforeEach, afterEach */
|
||||||
|
/*global describe, it, xit, expect, jasmine */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// these tests are meant to be executed by Cordova Medic Appium runner
|
||||||
|
// you can find it here: https://github.com/apache/cordova-medic/
|
||||||
|
// it is not necessary to do a full CI setup to run these tests
|
||||||
|
// just run "node cordova-medic/medic/medic.js appium --platform android --plugins cordova-plugin-camera"
|
||||||
|
|
||||||
|
var wdHelper = require('../helpers/wdHelper');
|
||||||
|
var wd = wdHelper.getWD();
|
||||||
|
var cameraConstants = require('../../www/CameraConstants');
|
||||||
|
var cameraHelper = require('../helpers/cameraHelper');
|
||||||
|
|
||||||
|
describe('Camera tests Android.', function () {
|
||||||
|
var driver,
|
||||||
|
startingMessage = 'Ready for action!',
|
||||||
|
isTestPictureSaved = false, // this indicates if device library has test picture
|
||||||
|
stopFlag = false; // this indecates that there was critical error and tests cannot go on
|
||||||
|
|
||||||
|
function win() {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fail(error) {
|
||||||
|
if (error && error.message) {
|
||||||
|
console.log('An error occured: ' + error.message);
|
||||||
|
expect(true).toFailWithMessage(error.message);
|
||||||
|
throw error.message;
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
console.log('Failed expectation: ' + error);
|
||||||
|
expect(true).toFailWithMessage(error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
// no message provided :(
|
||||||
|
console.log('An error without description occured');
|
||||||
|
expect(true).toBe(false);
|
||||||
|
throw 'An error without description occured';
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateSpecs() {
|
||||||
|
var sourceTypes = [
|
||||||
|
cameraConstants.PictureSourceType.CAMERA,
|
||||||
|
cameraConstants.PictureSourceType.PHOTOLIBRARY
|
||||||
|
],
|
||||||
|
destinationTypes = cameraConstants.DestinationType,
|
||||||
|
encodingTypes = [
|
||||||
|
cameraConstants.EncodingType.JPEG,
|
||||||
|
cameraConstants.EncodingType.PNG
|
||||||
|
],
|
||||||
|
allowEditOptions = [
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
];
|
||||||
|
|
||||||
|
return cameraHelper.generateSpecs(sourceTypes, destinationTypes, encodingTypes, allowEditOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPicture(options, skipUiInteractions) {
|
||||||
|
if (!options) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
var command = "navigator.camera.getPicture(function (result) { document.getElementById('info').innerHTML = result.slice(0, 100); }, " +
|
||||||
|
"function (err) { document.getElementById('info').innerHTML = 'ERROR: ' + err; }," + JSON.stringify(options) + ");";
|
||||||
|
return driver
|
||||||
|
.context('WEBVIEW')
|
||||||
|
.execute(command)
|
||||||
|
.sleep(5000)
|
||||||
|
.context('NATIVE_APP')
|
||||||
|
.then(function () {
|
||||||
|
if (skipUiInteractions) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (options.hasOwnProperty('sourceType') &&
|
||||||
|
(options.sourceType === cameraConstants.PictureSourceType.PHOTOLIBRARY ||
|
||||||
|
options.sourceType === cameraConstants.PictureSourceType.SAVEDPHOTOALBUM)) {
|
||||||
|
var touchTile = new wd.TouchAction(),
|
||||||
|
swipeRight = new wd.TouchAction();
|
||||||
|
touchTile.press({x: 50, y: 50}).release();
|
||||||
|
swipeRight.press({x: 3, y: 100}).moveTo({x: 100, y: 100}).release();
|
||||||
|
return driver
|
||||||
|
.performTouchAction(swipeRight)
|
||||||
|
.sleep(1000)
|
||||||
|
.elementByXPath('//*[@text="Gallery"]')
|
||||||
|
.then(function (element) {
|
||||||
|
return element.click().sleep(5000);
|
||||||
|
}, function () {
|
||||||
|
// if the gallery is already opened, we'd just go on:
|
||||||
|
return driver;
|
||||||
|
})
|
||||||
|
.performTouchAction(touchTile);
|
||||||
|
}
|
||||||
|
return driver
|
||||||
|
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]')
|
||||||
|
.click()
|
||||||
|
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]')
|
||||||
|
.click();
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
if (skipUiInteractions) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (options.hasOwnProperty('allowEdit') && options.allowEdit === true) {
|
||||||
|
return driver
|
||||||
|
.elementByXPath('//*[contains(@resource-id,\'save\')]')
|
||||||
|
.click();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
if (!skipUiInteractions) {
|
||||||
|
return driver.sleep(10000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function enterTest() {
|
||||||
|
if (stopFlag) {
|
||||||
|
return driver
|
||||||
|
.context('WEBVIEW')
|
||||||
|
.then(function () {
|
||||||
|
throw 'stopFlag is on!';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return driver
|
||||||
|
// trying to determine where we are
|
||||||
|
.context('WEBVIEW')
|
||||||
|
.elementById('info')
|
||||||
|
.then(function () {
|
||||||
|
return driver; //we're already on the test screen
|
||||||
|
}, function () {
|
||||||
|
return driver
|
||||||
|
.elementById('middle')
|
||||||
|
.then(function () {
|
||||||
|
return driver
|
||||||
|
// we're on autotests page, we should go to start page
|
||||||
|
.execute('window.location = "../index.html"')
|
||||||
|
.sleep(5000)
|
||||||
|
.fail(function () {
|
||||||
|
stopFlag = true;
|
||||||
|
throw 'Couldn\'t find start page.';
|
||||||
|
});
|
||||||
|
}, function () {
|
||||||
|
return; // no-op
|
||||||
|
})
|
||||||
|
// unknown starting page: no 'info' div
|
||||||
|
// adding it manually
|
||||||
|
.execute('var info = document.createElement("div"); ' +
|
||||||
|
'info.id = "info"; ' +
|
||||||
|
'document.body.appendChild(info);');
|
||||||
|
})
|
||||||
|
.sleep(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkPicture(shouldLoad) {
|
||||||
|
return driver
|
||||||
|
.context('WEBVIEW')
|
||||||
|
.elementById('info')
|
||||||
|
.getAttribute('innerHTML')
|
||||||
|
.then(function (html) {
|
||||||
|
if (html.indexOf(startingMessage) >= 0) {
|
||||||
|
expect(true).toFailWithMessage('No callback was fired');
|
||||||
|
} else if (shouldLoad) {
|
||||||
|
expect(html.length).toBeGreaterThan(0);
|
||||||
|
if (html.indexOf('ERROR') >= 0) {
|
||||||
|
expect(true).toFailWithMessage(html);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (html.indexOf('ERROR') === -1) {
|
||||||
|
expect(true).toFailWithMessage('Unexpected success callback with result: ' + html);
|
||||||
|
}
|
||||||
|
expect(html.indexOf('ERROR')).toBe(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function runCombinedSpec(spec) {
|
||||||
|
return enterTest()
|
||||||
|
.then(function () {
|
||||||
|
return getPicture(spec.options);
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
return checkPicture(true);
|
||||||
|
})
|
||||||
|
.then(win, fail);
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteImage() {
|
||||||
|
var holdTile = new wd.TouchAction();
|
||||||
|
holdTile.press({x: 50, y: 50}).wait(1000).release();
|
||||||
|
return driver
|
||||||
|
.performTouchAction(holdTile)
|
||||||
|
.elementByXPath('//android.widget.TextView[@text="Delete"]')
|
||||||
|
.then(function (element) {
|
||||||
|
return element
|
||||||
|
.click()
|
||||||
|
.elementByXPath('//android.widget.Button[@text="OK"]')
|
||||||
|
.click();
|
||||||
|
}, function () {
|
||||||
|
// couldn't find Delete menu item. Possibly there is no image.
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
jasmine.addMatchers({
|
||||||
|
toFailWithMessage : function () {
|
||||||
|
return {
|
||||||
|
compare: function (actual, msg) {
|
||||||
|
console.log('Failing with message: ' + msg);
|
||||||
|
var result = {
|
||||||
|
pass: false,
|
||||||
|
message: msg
|
||||||
|
};
|
||||||
|
if (msg.indexOf('Error response status: 6') >= 0) {
|
||||||
|
stopFlag = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('camera.ui.util configuring driver and starting a session', function (done) {
|
||||||
|
driver = wdHelper.getDriver('Android', function () {
|
||||||
|
return driver
|
||||||
|
.sleep(10000)
|
||||||
|
.finally(done);
|
||||||
|
});
|
||||||
|
}, 240000);
|
||||||
|
|
||||||
|
describe('Specs.', function () {
|
||||||
|
beforeEach(function (done) {
|
||||||
|
if (!stopFlag) {
|
||||||
|
return driver
|
||||||
|
.context('WEBVIEW')
|
||||||
|
.execute('document.getElementById("info").innerHTML = "' + startingMessage + '";')
|
||||||
|
.finally(done);
|
||||||
|
}
|
||||||
|
}, 20000);
|
||||||
|
|
||||||
|
// getPicture() with saveToPhotoLibrary = true
|
||||||
|
it('camera.ui.spec.1 Saving the picture to photo library', function (done) {
|
||||||
|
var options = {
|
||||||
|
quality: 50,
|
||||||
|
allowEdit: false,
|
||||||
|
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||||
|
saveToPhotoAlbum: true
|
||||||
|
};
|
||||||
|
enterTest()
|
||||||
|
.context('WEBVIEW')
|
||||||
|
.then(function () {
|
||||||
|
return getPicture(options);
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
isTestPictureSaved = true;
|
||||||
|
return checkPicture(true);
|
||||||
|
})
|
||||||
|
.then(win, fail)
|
||||||
|
.finally(done);
|
||||||
|
}, 300000);
|
||||||
|
|
||||||
|
// getPicture() with mediaType: VIDEO, sourceType: PHOTOLIBRARY
|
||||||
|
it('camera.ui.spec.2 Selecting only videos', function (done) {
|
||||||
|
if (stopFlag) {
|
||||||
|
expect(true).toFailWithMessage('Couldn\'t start tests execution.');
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var options = { sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
||||||
|
mediaType: cameraConstants.MediaType.VIDEO };
|
||||||
|
enterTest()
|
||||||
|
.then(function () {
|
||||||
|
return getPicture(options, true);
|
||||||
|
})
|
||||||
|
.sleep(5000)
|
||||||
|
.context('WEBVIEW')
|
||||||
|
.elementById('info')
|
||||||
|
.getAttribute('innerHTML')
|
||||||
|
.then(function (html) {
|
||||||
|
if (html.indexOf('ERROR') >= 0) {
|
||||||
|
throw html;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.context('NATIVE_APP')
|
||||||
|
.then(function () {
|
||||||
|
// try to find "Gallery" menu item
|
||||||
|
// if there's none, the gallery should be already opened
|
||||||
|
return driver
|
||||||
|
.elementByXPath('//*[@text="Gallery"]')
|
||||||
|
.then(function (element) {
|
||||||
|
return element.click().sleep(2000);
|
||||||
|
}, function () {
|
||||||
|
return driver;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
// if the gallery is opened on the videos page,
|
||||||
|
// there should be a "Choose video" caption
|
||||||
|
return driver
|
||||||
|
.elementByXPath('//*[@text="Choose video"]')
|
||||||
|
.fail(function () {
|
||||||
|
throw 'Couldn\'t find "Choose video" element.';
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(win, fail)
|
||||||
|
.deviceKeyEvent(4)
|
||||||
|
.sleep(2000)
|
||||||
|
.deviceKeyEvent(4)
|
||||||
|
.sleep(2000)
|
||||||
|
.elementById('action_bar_title')
|
||||||
|
.then(function () {
|
||||||
|
// success means we're still in native app
|
||||||
|
return driver
|
||||||
|
.deviceKeyEvent(4)
|
||||||
|
.sleep(2000);
|
||||||
|
}, function () {
|
||||||
|
// error means we're already in webview
|
||||||
|
return driver;
|
||||||
|
})
|
||||||
|
.finally(done);
|
||||||
|
}, 300000);
|
||||||
|
|
||||||
|
// getPicture(), then dismiss
|
||||||
|
// wait for the error callback to bee called
|
||||||
|
it('camera.ui.spec.3 Dismissing the camera', function (done) {
|
||||||
|
if (stopFlag) {
|
||||||
|
expect(true).toFailWithMessage('Couldn\'t start tests execution.');
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var options = { quality: 50,
|
||||||
|
allowEdit: true,
|
||||||
|
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||||
|
destinationType: cameraConstants.DestinationType.FILE_URI };
|
||||||
|
enterTest()
|
||||||
|
.context('WEBVIEW')
|
||||||
|
.then(function () {
|
||||||
|
return getPicture(options, true);
|
||||||
|
})
|
||||||
|
.sleep(5000)
|
||||||
|
.context("NATIVE_APP")
|
||||||
|
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'cancel\')]')
|
||||||
|
.click()
|
||||||
|
.context('WEBVIEW')
|
||||||
|
.then(function () {
|
||||||
|
return driver
|
||||||
|
.elementByXPath('//*[contains(text(),"Camera cancelled")]')
|
||||||
|
.then(function () {
|
||||||
|
return checkPicture(false);
|
||||||
|
}, function () {
|
||||||
|
throw 'Couldn\'t find "Camera cancelled" message.';
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(win, fail)
|
||||||
|
.finally(done);
|
||||||
|
}, 300000);
|
||||||
|
|
||||||
|
// getPicture(), then take picture but dismiss the edit
|
||||||
|
// wait for the error cllback to be called
|
||||||
|
it('camera.ui.spec.4 Dismissing the edit', function (done) {
|
||||||
|
if (stopFlag) {
|
||||||
|
expect(true).toFailWithMessage('Couldn\'t start tests execution.');
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var options = { quality: 50,
|
||||||
|
allowEdit: true,
|
||||||
|
sourceType: cameraConstants.PictureSourceType.CAMERA,
|
||||||
|
destinationType: cameraConstants.DestinationType.FILE_URI };
|
||||||
|
enterTest()
|
||||||
|
.context('WEBVIEW')
|
||||||
|
.then(function () {
|
||||||
|
return getPicture(options, true);
|
||||||
|
})
|
||||||
|
.sleep(5000)
|
||||||
|
.context('NATIVE_APP')
|
||||||
|
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'shutter\')]')
|
||||||
|
.click()
|
||||||
|
.elementByXPath('//android.widget.ImageView[contains(@resource-id,\'done\')]')
|
||||||
|
.click()
|
||||||
|
.elementByXPath('//*[contains(@resource-id,\'discard\')]')
|
||||||
|
.click()
|
||||||
|
.sleep(5000)
|
||||||
|
.context('WEBVIEW')
|
||||||
|
.then(function () {
|
||||||
|
return driver
|
||||||
|
.elementByXPath('//*[contains(text(),"Camera cancelled")]')
|
||||||
|
.then(function () {
|
||||||
|
return checkPicture(false);
|
||||||
|
}, function () {
|
||||||
|
throw 'Couldn\'t find "Camera cancelled" message.';
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(win, fail)
|
||||||
|
.finally(done);
|
||||||
|
}, 300000);
|
||||||
|
|
||||||
|
// combine various options for getPicture()
|
||||||
|
generateSpecs().forEach(function (spec) {
|
||||||
|
it('camera.ui.spec.5.' + spec.id + ' Combining options', function (done) {
|
||||||
|
if (stopFlag) {
|
||||||
|
expect(true).toFailWithMessage('Couldn\'t start tests execution.');
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
runCombinedSpec(spec).then(done);
|
||||||
|
}, 3 * 60 * 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('camera.ui.util Delete test image from device library', function (done) {
|
||||||
|
if (stopFlag) {
|
||||||
|
expect(true).toFailWithMessage('Couldn\'t start tests executeion.');
|
||||||
|
done();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isTestPictureSaved) {
|
||||||
|
// delete exactly one last picture
|
||||||
|
// this should be the picture we've taken in the first spec
|
||||||
|
return driver
|
||||||
|
.context('NATIVE_APP')
|
||||||
|
.deviceKeyEvent(3)
|
||||||
|
.sleep(5000)
|
||||||
|
.elementByName('Apps')
|
||||||
|
.click()
|
||||||
|
.elementByXPath('//android.widget.TextView[@text="Gallery"]')
|
||||||
|
.click()
|
||||||
|
.elementByXPath('//android.widget.TextView[contains(@text,"Pictures")]')
|
||||||
|
.then(function (element) {
|
||||||
|
return element
|
||||||
|
.click()
|
||||||
|
.sleep(3000)
|
||||||
|
.then(deleteImage)
|
||||||
|
.then(function () { done(); }, function () { done(); });
|
||||||
|
}, function () {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// couldn't save test picture earlier, so nothing to delete here
|
||||||
|
done();
|
||||||
|
}, 300000);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('camera.ui.util Destroy the session', function (done) {
|
||||||
|
return driver.quit(done);
|
||||||
|
}, 10000);
|
||||||
|
});
|
65
appium-tests/helpers/cameraHelper.js
Normal file
65
appium-tests/helpers/cameraHelper.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*jslint node: true, plusplus: true */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var cameraConstants = require('../../www/CameraConstants');
|
||||||
|
|
||||||
|
module.exports.generateSpecs = function (sourceTypes, destinationTypes, encodingTypes, allowEditOptions) {
|
||||||
|
var destinationType,
|
||||||
|
sourceType,
|
||||||
|
encodingType,
|
||||||
|
allowEdit,
|
||||||
|
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)) {
|
||||||
|
// if taking picture from photolibrary, don't vary 'correctOrientation' option
|
||||||
|
if (sourceTypes[sourceType] === cameraConstants.PictureSourceType.PHOTOLIBRARY) {
|
||||||
|
specs.push({
|
||||||
|
'id': id++,
|
||||||
|
'options': {
|
||||||
|
'destinationType': destinationTypes[destinationType],
|
||||||
|
'sourceType': sourceTypes[sourceType],
|
||||||
|
'encodingType': encodingTypes[encodingType],
|
||||||
|
'allowEdit': allowEditOptions[allowEdit],
|
||||||
|
'saveToPhotoAlbum': false,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
specs.push({
|
||||||
|
'id': id++,
|
||||||
|
'options': {
|
||||||
|
'destinationType': destinationTypes[destinationType],
|
||||||
|
'sourceType': sourceTypes[sourceType],
|
||||||
|
'encodingType': encodingTypes[encodingType],
|
||||||
|
'correctOrientation': true,
|
||||||
|
'allowEdit': allowEditOptions[allowEdit],
|
||||||
|
'saveToPhotoAlbum': false,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'id': id++,
|
||||||
|
'options': {
|
||||||
|
'destinationType': destinationTypes[destinationType],
|
||||||
|
'sourceType': sourceTypes[sourceType],
|
||||||
|
'encodingType': encodingTypes[encodingType],
|
||||||
|
'correctOrientation': false,
|
||||||
|
'allowEdit': allowEditOptions[allowEdit],
|
||||||
|
'saveToPhotoAlbum': false,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return specs;
|
||||||
|
};
|
45
appium-tests/helpers/wdHelper.js
Normal file
45
appium-tests/helpers/wdHelper.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/*jslint node: true, plusplus: true */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var wd = global.WD || require('wd');
|
||||||
|
var driver;
|
||||||
|
|
||||||
|
module.exports.getDriver = function (platform, callback) {
|
||||||
|
var serverConfig = {
|
||||||
|
host: 'localhost',
|
||||||
|
port: 4723
|
||||||
|
},
|
||||||
|
driverConfig = {
|
||||||
|
browserName: '',
|
||||||
|
'appium-version': '1.3',
|
||||||
|
platformName: platform,
|
||||||
|
platformVersion: global.PLATFORM_VERSION || '',
|
||||||
|
deviceName: global.DEVICE_NAME || '',
|
||||||
|
app: global.PACKAGE_PATH,
|
||||||
|
autoAcceptAlerts: true
|
||||||
|
};
|
||||||
|
|
||||||
|
driver = wd.promiseChainRemote(serverConfig);
|
||||||
|
module.exports.configureLogging(driver);
|
||||||
|
driver.init(driverConfig).setImplicitWaitTimeout(10000)
|
||||||
|
.sleep(20000) // wait for the app to load
|
||||||
|
.then(callback);
|
||||||
|
|
||||||
|
return driver;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.getWD = function () {
|
||||||
|
return wd;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.configureLogging = function (driver) {
|
||||||
|
driver.on('status', function (info) {
|
||||||
|
console.log(info);
|
||||||
|
});
|
||||||
|
driver.on('command', function (meth, path, data) {
|
||||||
|
console.log(' > ' + meth, path, data || '');
|
||||||
|
});
|
||||||
|
driver.on('http', function (meth, path, data) {
|
||||||
|
console.log(' > ' + meth, path, data || '');
|
||||||
|
});
|
||||||
|
};
|
256
appium-tests/ios/ios.spec.js
Normal file
256
appium-tests/ios/ios.spec.js
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
/*jslint node: true, plusplus: true */
|
||||||
|
/*global beforeEach, afterEach */
|
||||||
|
/*global describe, it, xit, expect, jasmine, pending */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var wdHelper = require('../helpers/wdHelper');
|
||||||
|
var wd = wdHelper.getWD();
|
||||||
|
var isDevice = global.DEVICE;
|
||||||
|
var cameraConstants = require('../../www/CameraConstants');
|
||||||
|
var cameraHelper = require('../helpers/cameraHelper');
|
||||||
|
|
||||||
|
describe('Camera tests iOS.', function () {
|
||||||
|
var driver,
|
||||||
|
webviewContext = 'WEBVIEW_1',
|
||||||
|
startingMessage = 'Ready for action!';
|
||||||
|
|
||||||
|
function win() {
|
||||||
|
expect(true).toBe(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fail(error) {
|
||||||
|
if (error && error.message) {
|
||||||
|
console.log('An error occured: ' + error.message);
|
||||||
|
expect(true).toFailWithMessage(error.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
console.log('Failed expectation: ' + error);
|
||||||
|
expect(true).toFailWithMessage(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// no message provided :(
|
||||||
|
console.log('An error without description occured');
|
||||||
|
expect(true).toBe(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateSpecs() {
|
||||||
|
var sourceTypes = [
|
||||||
|
cameraConstants.PictureSourceType.CAMERA,
|
||||||
|
cameraConstants.PictureSourceType.PHOTOLIBRARY
|
||||||
|
],
|
||||||
|
destinationTypes = cameraConstants.DestinationType,
|
||||||
|
encodingTypes = [
|
||||||
|
cameraConstants.EncodingType.JPEG,
|
||||||
|
cameraConstants.EncodingType.PNG
|
||||||
|
],
|
||||||
|
allowEditOptions = [
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
];
|
||||||
|
|
||||||
|
return cameraHelper.generateSpecs(sourceTypes, destinationTypes, encodingTypes, allowEditOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPicture(options, cancelCamera, skipUiInteractions) {
|
||||||
|
if (!options) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
var command = "navigator.camera.getPicture(function (result) { document.getElementById('info').innerHTML = 'Success: ' + result.slice(0, 100); }, " +
|
||||||
|
"function (err) { document.getElementById('info').innerHTML = 'ERROR: ' + err; }," + JSON.stringify(options) + ");";
|
||||||
|
return driver
|
||||||
|
.sleep(2000)
|
||||||
|
.context(webviewContext)
|
||||||
|
.execute(command)
|
||||||
|
.sleep(5000)
|
||||||
|
.context('NATIVE_APP')
|
||||||
|
.then(function () {
|
||||||
|
if (skipUiInteractions) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (options.hasOwnProperty('sourceType') && options.sourceType === cameraConstants.PictureSourceType.PHOTOLIBRARY) {
|
||||||
|
return driver
|
||||||
|
.elementByName('Camera Roll')
|
||||||
|
.click()
|
||||||
|
.elementByXPath('//UIACollectionCell')
|
||||||
|
.click()
|
||||||
|
.then(function () {
|
||||||
|
if (options.hasOwnProperty('allowEdit') && options.allowEdit === true) {
|
||||||
|
return driver
|
||||||
|
.elementByName('Use')
|
||||||
|
.click();
|
||||||
|
}
|
||||||
|
return driver;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (options.hasOwnProperty('sourceType') && options.sourceType === cameraConstants.PictureSourceType.SAVEDPHOTOALBUM) {
|
||||||
|
return driver
|
||||||
|
.elementByXPath('//UIACollectionCell')
|
||||||
|
.click()
|
||||||
|
.then(function () {
|
||||||
|
if (options.hasOwnProperty('allowEdit') && options.allowEdit === true) {
|
||||||
|
return driver
|
||||||
|
.elementByName('Use')
|
||||||
|
.click();
|
||||||
|
}
|
||||||
|
return driver;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (cancelCamera) {
|
||||||
|
return driver
|
||||||
|
.elementByName('Cancel')
|
||||||
|
.click();
|
||||||
|
}
|
||||||
|
return driver
|
||||||
|
.elementByName('PhotoCapture')
|
||||||
|
.click()
|
||||||
|
.elementByName('Use Photo')
|
||||||
|
.click();
|
||||||
|
})
|
||||||
|
.sleep(3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function enterTest() {
|
||||||
|
return driver
|
||||||
|
.contexts(function (err, contexts) {
|
||||||
|
if (err) {
|
||||||
|
fail(err);
|
||||||
|
} else {
|
||||||
|
// if WEBVIEW context is available, use it
|
||||||
|
// if not, use NATIVE_APP
|
||||||
|
webviewContext = contexts[contexts.length - 1];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
return driver
|
||||||
|
.context(webviewContext);
|
||||||
|
})
|
||||||
|
.fail(fail)
|
||||||
|
.elementById('info')
|
||||||
|
.fail(function () {
|
||||||
|
// unknown starting page: no 'info' div
|
||||||
|
// adding it manually
|
||||||
|
return driver
|
||||||
|
.execute('var info = document.createElement("div"); ' +
|
||||||
|
'info.id = "info"' +
|
||||||
|
'document.body.appendChild(info);')
|
||||||
|
.fail(fail);
|
||||||
|
})
|
||||||
|
.execute('document.getElementById("info").innerHTML = "' + startingMessage + '";')
|
||||||
|
.fail(fail);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkPicture(shouldLoad) {
|
||||||
|
return driver
|
||||||
|
.contexts(function (err, contexts) {
|
||||||
|
// if WEBVIEW context is available, use it
|
||||||
|
// if not, use NATIVE_APP
|
||||||
|
webviewContext = contexts[contexts.length - 1];
|
||||||
|
})
|
||||||
|
.context(webviewContext)
|
||||||
|
.elementById('info')
|
||||||
|
.getAttribute('innerHTML')
|
||||||
|
.then(function (html) {
|
||||||
|
if (html.indexOf(startingMessage) >= 0) {
|
||||||
|
expect(true).toFailWithMessage('No callback was fired');
|
||||||
|
} else if (shouldLoad) {
|
||||||
|
expect(html.length).toBeGreaterThan(0);
|
||||||
|
if (html.indexOf('ERROR') >= 0) {
|
||||||
|
expect(true).toFailWithMessage(html);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (html.indexOf('ERROR') === -1) {
|
||||||
|
expect(true).toFailWithMessage('Unexpected success callback with result: ' + html);
|
||||||
|
}
|
||||||
|
expect(html.indexOf('ERROR')).toBe(0);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.context('NATIVE_APP');
|
||||||
|
}
|
||||||
|
|
||||||
|
function runCombinedSpec(spec) {
|
||||||
|
return enterTest()
|
||||||
|
.then(function () {
|
||||||
|
return getPicture(spec.options);
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
return checkPicture(true);
|
||||||
|
})
|
||||||
|
.then(win, fail);
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
jasmine.addMatchers({
|
||||||
|
toFailWithMessage : function () {
|
||||||
|
return {
|
||||||
|
compare: function (actual, msg) {
|
||||||
|
console.log('Failing with message: ' + msg);
|
||||||
|
var result = {
|
||||||
|
pass: false,
|
||||||
|
message: msg
|
||||||
|
};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('camera.ui.util Configuring driver and starting a session', function (done) {
|
||||||
|
driver = wdHelper.getDriver('iOS', done);
|
||||||
|
}, 240000);
|
||||||
|
|
||||||
|
describe('Specs.', function () {
|
||||||
|
// getPicture() with mediaType: VIDEO, sourceType: PHOTOLIBRARY
|
||||||
|
it('camera.ui.spec.1 Selecting only videos', function (done) {
|
||||||
|
var options = { sourceType: cameraConstants.PictureSourceType.PHOTOLIBRARY,
|
||||||
|
mediaType: cameraConstants.MediaType.VIDEO };
|
||||||
|
enterTest()
|
||||||
|
.then(function () { return getPicture(options, false, true); }) // skip ui unteractions
|
||||||
|
.sleep(5000)
|
||||||
|
.elementByName('Videos')
|
||||||
|
.then(win, fail)
|
||||||
|
.elementByName('Cancel')
|
||||||
|
.click()
|
||||||
|
.finally(done);
|
||||||
|
}, 300000);
|
||||||
|
|
||||||
|
// getPicture(), then dismiss
|
||||||
|
// wait for the error callback to bee called
|
||||||
|
it('camera.ui.spec.2 Dismissing the camera', function (done) {
|
||||||
|
// camera is not available on iOS simulator
|
||||||
|
if (!isDevice) {
|
||||||
|
pending();
|
||||||
|
}
|
||||||
|
var options = { sourceType: cameraConstants.PictureSourceType.CAMERA };
|
||||||
|
enterTest()
|
||||||
|
.then(function () {
|
||||||
|
return getPicture(options, true);
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
return checkPicture(false);
|
||||||
|
})
|
||||||
|
.elementByXPath('//UIAStaticText[contains(@label,"no image selected")]')
|
||||||
|
.then(function () {
|
||||||
|
return checkPicture(false);
|
||||||
|
}, fail)
|
||||||
|
.finally(done);
|
||||||
|
}, 300000);
|
||||||
|
|
||||||
|
// combine various options for getPicture()
|
||||||
|
generateSpecs().forEach(function (spec) {
|
||||||
|
it('camera.ui.spec.3.' + spec.id + ' Combining options', function (done) {
|
||||||
|
// camera is not available on iOS simulator
|
||||||
|
if (!isDevice) {
|
||||||
|
pending();
|
||||||
|
}
|
||||||
|
runCombinedSpec(spec).then(done);
|
||||||
|
}, 3 * 60 * 1000);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('camera.ui.util.4 Destroy the session', function (done) {
|
||||||
|
driver.quit(done);
|
||||||
|
}, 10000);
|
||||||
|
});
|
@ -121,8 +121,8 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
url = "data:image/jpeg;base64," + url;
|
url = "data:image/jpeg;base64," + url;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// not DATA_URL
|
// not DATA_URL
|
||||||
log('URL: ' + url.slice(0, 100));
|
|
||||||
}
|
}
|
||||||
|
log('URL: "' + url.slice(0, 90) + '"');
|
||||||
|
|
||||||
pictureUrl = url;
|
pictureUrl = url;
|
||||||
var img = document.getElementById('camera_image');
|
var img = document.getElementById('camera_image');
|
||||||
@ -141,10 +141,11 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
function getPictureWin(data) {
|
function getPictureWin(data) {
|
||||||
setPicture(data);
|
setPicture(data);
|
||||||
// TODO: Fix resolveLocalFileSystemURI to work with native-uri.
|
// TODO: Fix resolveLocalFileSystemURI to work with native-uri.
|
||||||
if (pictureUrl.indexOf('file:') == 0 || pictureUrl.indexOf('content:') == 0 || pictureUrl.indexOf('ms-appdata:') === 0) {
|
if (pictureUrl.indexOf('file:') == 0 || pictureUrl.indexOf('content:') == 0 || pictureUrl.indexOf('ms-appdata:') === 0 || pictureUrl.indexOf('assets-library:') === 0) {
|
||||||
resolveLocalFileSystemURI(data, function (e) {
|
resolveLocalFileSystemURI(data, function (e) {
|
||||||
fileEntry = e;
|
fileEntry = e;
|
||||||
logCallback('resolveLocalFileSystemURI()', true)(e.toURL());
|
logCallback('resolveLocalFileSystemURI()', true)(e.toURL());
|
||||||
|
readFile();
|
||||||
}, logCallback('resolveLocalFileSystemURI()', false));
|
}, logCallback('resolveLocalFileSystemURI()', false));
|
||||||
} else if (pictureUrl.indexOf('data:image/jpeg;base64') == 0) {
|
} else if (pictureUrl.indexOf('data:image/jpeg;base64') == 0) {
|
||||||
// do nothing
|
// do nothing
|
||||||
@ -217,6 +218,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
log('FileReader.readAsDataURL() - length = ' + reader.result.length);
|
log('FileReader.readAsDataURL() - length = ' + reader.result.length);
|
||||||
};
|
};
|
||||||
reader.onerror = logCallback('FileReader.readAsDataURL', false);
|
reader.onerror = logCallback('FileReader.readAsDataURL', false);
|
||||||
|
reader.onloadend = onFileReadAsDataURL;
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
};
|
};
|
||||||
// Test out onFileReceived when the file object was set via a native <input> elements.
|
// Test out onFileReceived when the file object was set via a native <input> elements.
|
||||||
@ -361,7 +363,7 @@ exports.defineManualTests = function (contentEl, createActionButton) {
|
|||||||
|
|
||||||
function createOptionsEl(name, values, selectionDefault) {
|
function createOptionsEl(name, values, selectionDefault) {
|
||||||
var openDiv = '<div style="display: inline-block">' + name + ': ';
|
var openDiv = '<div style="display: inline-block">' + name + ': ';
|
||||||
var select = '<select name=' + name + '>';
|
var select = '<select name=' + name + ' id="' + name + '">';
|
||||||
|
|
||||||
var defaultOption = '';
|
var defaultOption = '';
|
||||||
if (selectionDefault == undefined) {
|
if (selectionDefault == undefined) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user