mirror of
https://github.com/appium/appium.git
synced 2026-02-12 04:50:08 -06:00
Merge pull request #1796 from sebv/sebv-working
Test reformatting, step2.
This commit is contained in:
@@ -30,13 +30,13 @@ module.exports = function (grunt) {
|
||||
, trailing: true
|
||||
, node: true
|
||||
, strict: true
|
||||
, white: true
|
||||
, indent: 2
|
||||
},
|
||||
files: {
|
||||
src: ['*.js', './**/*.js'],
|
||||
options: {
|
||||
ignores: ['./submodules/**/*.js', './node_modules/**/*.js', './lib/devices/ios/webdriver-atoms/*.js', './sample-code/**/*.js', './test/**/*.js', './lib/server/static/**/*.js', './lib/devices/firefoxos/atoms/*.js', './lib/devices/ios/uiauto/**/*.js']
|
||||
, white: true
|
||||
, indent: 2
|
||||
}
|
||||
},
|
||||
test: {
|
||||
|
||||
0
assets/TestApp.app/PkgInfo
Normal file
0
assets/TestApp.app/PkgInfo
Normal file
56
bin/test.sh
56
bin/test.sh
@@ -2,6 +2,7 @@
|
||||
set +e
|
||||
mocha_args=""
|
||||
ios_only=false
|
||||
ios6_only=false
|
||||
ios7_only=false
|
||||
android_only=false
|
||||
all_tests=true
|
||||
@@ -11,29 +12,6 @@ if command -v xcode-select 2>/dev/null; then
|
||||
fi
|
||||
did_switch_xcode=false
|
||||
|
||||
join_testfiles () {
|
||||
testtype=$1
|
||||
shift
|
||||
outfile=$1
|
||||
rm -rf $outfile
|
||||
shift
|
||||
indirs=$@
|
||||
out=""
|
||||
touch $outfile
|
||||
echo "\"use strict\";\n\n" >> $outfile
|
||||
for indir in $indirs; do
|
||||
for infile in ./test/functional/$indir/*.js; do
|
||||
basefile=$(basename $infile | sed s/\.js//g)
|
||||
pre="describe('$testtype:$indir/$basefile', function() {"
|
||||
post="});"
|
||||
echo "Collating $infile..."
|
||||
echo "$pre\n" >> $outfile
|
||||
cat $infile >> $outfile
|
||||
echo "\n$post\n" >> $outfile
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
for arg in "$@"; do
|
||||
if [ "$arg" = "--ios" ]; then
|
||||
ios_only=true
|
||||
@@ -41,6 +19,9 @@ for arg in "$@"; do
|
||||
elif [ "$arg" = "--android" ]; then
|
||||
android_only=true
|
||||
all_tests=false
|
||||
elif [ "$arg" = "--ios6" ]; then
|
||||
ios6_only=true
|
||||
all_tests=false
|
||||
elif [ "$arg" = "--ios7" ]; then
|
||||
ios7_only=true
|
||||
all_tests=false
|
||||
@@ -51,16 +32,18 @@ for arg in "$@"; do
|
||||
fi
|
||||
done
|
||||
|
||||
to_func_test_path () {
|
||||
echo $@ | \
|
||||
sed -e "s/^/test\/functional\//g" | \
|
||||
sed -e "s/[[:space:]]/ test\/functional\//g"
|
||||
}
|
||||
|
||||
appium_mocha="mocha -t 90000 -R spec $mocha_args"
|
||||
|
||||
mkdir -p ./test/functional/_joined
|
||||
|
||||
if $ios_only || $all_tests; then
|
||||
if $ios6_only || $ios_only || $all_tests; then
|
||||
echo "RUNNING IOS 6.1 TESTS"
|
||||
echo "---------------------"
|
||||
ios_testfile="./test/functional/_joined/ios.js"
|
||||
ios_dirs="appium prefs safari testapp uicatalog webview gappium"
|
||||
join_testfiles ios6.1 $ios_testfile $ios_dirs
|
||||
if test -d /Applications/Xcode-6.1.app; then
|
||||
echo "Found Xcode for iOS 6.1, switching to it"
|
||||
sudo xcode-select -switch /Applications/Xcode-6.1.app
|
||||
@@ -68,15 +51,13 @@ if $ios_only || $all_tests; then
|
||||
else
|
||||
echo "Did not find /Applications/Xcode-6.1.app, using default"
|
||||
fi
|
||||
time $appium_mocha $ios_testfile
|
||||
DEVICE=ios6 time $appium_mocha $(to_func_test_path $ios_dirs) -g '@skip-ios6|@skip-all-ios' -i
|
||||
fi
|
||||
|
||||
if $ios7_only || $all_tests; then
|
||||
echo "RUNNING IOS 7.0 TESTS"
|
||||
echo "---------------------"
|
||||
ios7_testfile="./test/functional/_joined/ios7.js"
|
||||
ios7_dirs="testapp safari uicatalog webview gappium"
|
||||
join_testfiles ios7 $ios7_testfile $ios7_dirs
|
||||
ios7_dirs="testapp safari uicatalog webview gappium"
|
||||
if test -d /Applications/Xcode-7.0.app; then
|
||||
echo "Found Xcode for iOS 7.0, switching to it"
|
||||
sudo xcode-select -switch /Applications/Xcode-7.0.app
|
||||
@@ -84,7 +65,8 @@ if $ios7_only || $all_tests; then
|
||||
else
|
||||
echo "Did not find /Applications/Xcode-7.0.app, using default"
|
||||
fi
|
||||
time $appium_mocha $ios7_testfile
|
||||
echo
|
||||
DEVICE=ios7 time $appium_mocha $(to_func_test_path $ios7_dirs) -g '@skip-ios7|@skip-all-ios' -i
|
||||
fi
|
||||
|
||||
if $did_switch_xcode; then
|
||||
@@ -95,8 +77,8 @@ fi
|
||||
if $android_only || $all_tests; then
|
||||
echo "RUNNING ANDROID TESTS"
|
||||
echo "---------------------"
|
||||
android_testfile="./test/functional/_joined/android.js"
|
||||
android_dirs="apidemos selendroid android toggletest gappium"
|
||||
join_testfiles android $android_testfile $android_dirs
|
||||
APPIUM_CORDOVA="android" time $appium_mocha $android_testfile
|
||||
android_dirs="apidemos android toggletest"
|
||||
selendroid_dirs=" gappium selendroid"
|
||||
DEVICE=android time $appium_mocha $(to_func_test_path $android_dirs) -g '@skip-all-android' -i && \
|
||||
DEVICE=selendroid time $appium_mocha $(to_func_test_path $selendroid_dirs) -g '@skip-all-selendroid' -i
|
||||
fi
|
||||
|
||||
@@ -39,10 +39,10 @@ I am some page content
|
||||
</span>
|
||||
ñ☃
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$("#i_am_a_textbox").focus(function(){$(this).val("");})
|
||||
.blur(function(){$(this).val("i has no focus");});
|
||||
});
|
||||
$(document).ready(function(){
|
||||
$("#i_am_a_textbox").focus(function(){$(this).val("");})
|
||||
.blur(function(){$(this).val("i has no focus");});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="border">
|
||||
@@ -65,7 +65,10 @@ I am some page content
|
||||
<p>Server time: <span id="servertime">{{ serverTime }}</span></p>
|
||||
<p>Client time: <span id="clienttime"></span></p>
|
||||
<script type="text/javascript">
|
||||
$("#clienttime").text(parseInt(new Date().getTime() / 1000))
|
||||
var uuid;
|
||||
try {uuid = window.location.toString().match(/\?(.*)$/)[1]; } catch (ign) {}
|
||||
if (uuid) document.title = document.title + " - " + uuid;
|
||||
$("#clienttime").text(parseInt(new Date().getTime() / 1000));
|
||||
</script>
|
||||
|
||||
<p id="useragent">{{ userAgent }}</p>
|
||||
|
||||
@@ -92,6 +92,6 @@
|
||||
"chai-as-promised": "~4.1.0",
|
||||
"chai": "~1.8.1",
|
||||
"node-static": "~0.7.2",
|
||||
"chai": "~1.8.1"
|
||||
"q": "~1.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
"trailing": true,
|
||||
"es5": true,
|
||||
"expr": true,
|
||||
"white": true,
|
||||
"indent": 2,
|
||||
"globals": {
|
||||
"describe": true,
|
||||
"it": true,
|
||||
|
||||
@@ -3,59 +3,63 @@
|
||||
var chai = require('chai')
|
||||
, should = chai.should()
|
||||
, childProcess = require('child_process')
|
||||
, it = require("../../helpers/driverblock.js").it
|
||||
, Android = require('../../../lib/devices/android/android.js')
|
||||
, ADB = require('../../../lib/devices/android/adb');
|
||||
|
||||
describe('Android Device State module', function() {
|
||||
var deviceState = new ADB({});
|
||||
beforeEach(function(done) {
|
||||
// ensure a device or emu is connected
|
||||
childProcess.exec("adb devices", function(err, stdout) {
|
||||
should.not.exist(err);
|
||||
var device = /\n([A-Za-z0-9\-]+)\W+device\n/.exec(stdout);
|
||||
if (!device) {
|
||||
throw new Error("Looks like device isn't ready for test");
|
||||
}
|
||||
device = device[1];
|
||||
should.exist(device);
|
||||
done();
|
||||
});
|
||||
});
|
||||
// todo: hangs when doing 'adb shell input keyevent 3'
|
||||
describe("android tests - device state - @skip-all-android", function () {
|
||||
|
||||
describe('isScreenLocked method', function() {
|
||||
it('should return true if screen is locked', function(done) {
|
||||
// Press POWER btn to lock screen first
|
||||
childProcess.exec('adb shell input keyevent 26 && sleep 5', function(err) {
|
||||
describe('Android Device State module', function () {
|
||||
var deviceState = new ADB({});
|
||||
beforeEach(function (done) {
|
||||
// ensure a device or emu is connected
|
||||
childProcess.exec("adb devices", function (err, stdout) {
|
||||
should.not.exist(err);
|
||||
// press home to get to lock screen
|
||||
childProcess.exec('adb shell input keyevent 3 && sleep 5', function(err) {
|
||||
var device = /\n([A-Za-z0-9\-]+)\W+device\n/.exec(stdout);
|
||||
if (!device) {
|
||||
throw new Error("Looks like device isn't ready for test");
|
||||
}
|
||||
device = device[1];
|
||||
should.exist(device);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('isScreenLocked method', function () {
|
||||
it('should return true if screen is locked', function (done) {
|
||||
// Press POWER btn to lock screen first
|
||||
childProcess.exec('adb shell input keyevent 26 && sleep 5', function (err) {
|
||||
should.not.exist(err);
|
||||
deviceState.isScreenLocked(function(err, isLocked) {
|
||||
// press home to get to lock screen
|
||||
childProcess.exec('adb shell input keyevent 3 && sleep 5', function (err) {
|
||||
should.not.exist(err);
|
||||
isLocked.should.equal(true);
|
||||
done();
|
||||
deviceState.isScreenLocked(function (err, isLocked) {
|
||||
should.not.exist(err);
|
||||
isLocked.should.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
it('should return false is screen is unlocked', function(done) {
|
||||
// Push unlock.apk first
|
||||
var androidObj = new Android({});
|
||||
androidObj.adb = deviceState;
|
||||
androidObj.pushUnlock(function(err) {
|
||||
should.not.exist(err);
|
||||
childProcess.exec('adb shell am start -n io.appium.unlock/.Unlock && sleep 5', function(err) {
|
||||
it('should return false is screen is unlocked', function (done) {
|
||||
// Push unlock.apk first
|
||||
var androidObj = new Android({});
|
||||
androidObj.adb = deviceState;
|
||||
androidObj.pushUnlock(function (err) {
|
||||
should.not.exist(err);
|
||||
setTimeout(function() {
|
||||
deviceState.isScreenLocked(function(err, isLocked) {
|
||||
should.not.exist(err);
|
||||
isLocked.should.equal(false);
|
||||
done();
|
||||
});
|
||||
}, 2500);
|
||||
childProcess.exec('adb shell am start -n io.appium.unlock/.Unlock && sleep 5', function (err) {
|
||||
should.not.exist(err);
|
||||
setTimeout(function () {
|
||||
deviceState.isScreenLocked(function (err, isLocked) {
|
||||
should.not.exist(err);
|
||||
isLocked.should.equal(false);
|
||||
done();
|
||||
});
|
||||
}, 2500);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,62 +1,58 @@
|
||||
"use strict";
|
||||
|
||||
var path = require('path')
|
||||
, appPath = path.resolve(__dirname, "../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk")
|
||||
, appPkg = "com.example.android.apis"
|
||||
, appAct = ".ApiDemos"
|
||||
, describeWd = require("../../helpers/driverblock.js").describeForApp(appPath,
|
||||
"android", appPkg, appAct)
|
||||
, it = require("../../helpers/driverblock.js").it
|
||||
var env = require('../../helpers/env')
|
||||
, setup = require("../common/setup-base")
|
||||
, desired = require("./desired")
|
||||
, net = require('net')
|
||||
, appiumPort = process.env.APPIUM_PORT || 4723
|
||||
, io = require('socket.io-client');
|
||||
|
||||
describe("apidemos - alerts -", function () {
|
||||
|
||||
describeWd('alert dialog detection', function() {
|
||||
setup(this, desired);
|
||||
|
||||
// set up telnet...
|
||||
var runCommands = function(cmds, cb) {
|
||||
var runCommands = function (cmds, cb) {
|
||||
try {
|
||||
var conn = net.createConnection(5554, 'localhost');
|
||||
conn.on('connect', function() {
|
||||
conn.on('connect', function () {
|
||||
try {
|
||||
for (var i = 0; i < cmds.length; i++) {
|
||||
conn.write(cmds[i] + "\n");
|
||||
}
|
||||
conn.write('quit\n');
|
||||
cb(true);
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
console.log("Could not run commands: " + err.description);
|
||||
cb(undefined);
|
||||
}
|
||||
}, cb);
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
console.log("Couldn't run commands: " + err.description);
|
||||
}
|
||||
};
|
||||
|
||||
it('should detect low power...', function(done) {
|
||||
it('should detect low power...', function (done) {
|
||||
// setup websocket client...
|
||||
var options ={
|
||||
var options = {
|
||||
transports: ['websocket'],
|
||||
'force new connection': true
|
||||
};
|
||||
try {
|
||||
var client = io.connect('http://127.0.0.1:' + appiumPort, options);
|
||||
client.on('connect', function() {
|
||||
runCommands(['power ac off', 'power capacity 9'], function(success) {
|
||||
var client = io.connect('http://127.0.0.1:' + env.APPIUM_PORT, options);
|
||||
client.on('connect', function () {
|
||||
runCommands(['power ac off', 'power capacity 9'], function (success) {
|
||||
success.should.equal(true);
|
||||
});
|
||||
});
|
||||
client.on('alert', function() {
|
||||
runCommands(['power ac on', 'power capacity 50'], function(success) {
|
||||
client.on('alert', function () {
|
||||
runCommands(['power ac on', 'power capacity 50'], function (success) {
|
||||
success.should.equal(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
console.log("Unknown exception: " + err.description);
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,67 +1,65 @@
|
||||
"use strict";
|
||||
|
||||
var path = require('path')
|
||||
, appPath = path.resolve(__dirname, "../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk")
|
||||
, appPkg = "com.example.android.apis"
|
||||
, appAct = ".ApiDemos"
|
||||
, describeWd = require("../../helpers/driverblock.js").describeForApp(appPath,
|
||||
"android", appPkg, appAct)
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var env = require('../../helpers/env')
|
||||
, setup = require("../common/setup-base")
|
||||
, desired = require("./desired")
|
||||
, androidReset = require('../../helpers/reset-utils').androidReset;
|
||||
|
||||
describeWd('get attribute', function(h) {
|
||||
if (process.env.FAST_TESTS) {
|
||||
afterEach(function(done) {
|
||||
// going back to main page if necessary todo: find better way
|
||||
h.driver.elementByNameOrNull('Accessibility').then(function(el) {
|
||||
if (!el) return h.driver.back();
|
||||
}).nodeify(done);
|
||||
describe("apidemos - attributes -", function () {
|
||||
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
if (env.FAST_TESTS) {
|
||||
beforeEach(function (done) {
|
||||
androidReset(desired['app-package'], desired['app-activity']).nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should be able to find text attribute', function(done) {
|
||||
h.driver
|
||||
|
||||
it('should be able to find text attribute', function (done) {
|
||||
driver
|
||||
.elementByName('Animation').getAttribute('text')
|
||||
.should.become("Animation")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to find name attribute', function(done) {
|
||||
h.driver.elementByName('Animation').getAttribute('name')
|
||||
it('should be able to find name attribute', function (done) {
|
||||
driver.elementByName('Animation').getAttribute('name')
|
||||
.should.become("Animation")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to find name attribute, falling back to text', function(done) {
|
||||
h.driver
|
||||
it('should be able to find name attribute, falling back to text', function (done) {
|
||||
driver
|
||||
.elementByName('Animation').click()
|
||||
.elementsByTagName('text')
|
||||
.then(function(els) { return els[1].getAttribute('name'); })
|
||||
.then(function (els) { return els[1].getAttribute('name'); })
|
||||
.should.become("Bouncing Balls")
|
||||
.back()
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to find displayed attribute', function(done) {
|
||||
h.driver
|
||||
it('should be able to find displayed attribute', function (done) {
|
||||
driver
|
||||
.elementByName('Animation').getAttribute('displayed')
|
||||
.should.become('true')
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to find displayed attribute through normal func', function(done) {
|
||||
h.driver
|
||||
it('should be able to find displayed attribute through normal func', function (done) {
|
||||
driver
|
||||
.elementByName('Animation').isDisplayed()
|
||||
.should.become(true)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to get element location', function(done) {
|
||||
h.driver
|
||||
it('should be able to get element location', function (done) {
|
||||
driver
|
||||
.elementByName('Animation').getLocation()
|
||||
.then(function(loc) {
|
||||
.then(function (loc) {
|
||||
loc.x.should.be.at.least(0);
|
||||
loc.y.should.be.at.least(0);
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should be able to get element size', function(done) {
|
||||
h.driver
|
||||
it('should be able to get element size', function (done) {
|
||||
driver
|
||||
.elementByName('Animation').getSize()
|
||||
.then(function(size) {
|
||||
.then(function (size) {
|
||||
size.width.should.be.at.least(0);
|
||||
size.height.should.be.at.least(0);
|
||||
}).nodeify(done);
|
||||
@@ -69,12 +67,13 @@ describeWd('get attribute', function(h) {
|
||||
// TODO: tests for checkable, checked, clickable, focusable, focused,
|
||||
// longClickable, scrollable, selected
|
||||
|
||||
it('should be able to get selected value of a tab', function(done) {
|
||||
h.driver
|
||||
.execute("mobile: find", [["scroll",[[3, "views"]],[[7, "views"]]]]).click()
|
||||
.execute("mobile: find", [["scroll",[[3, "tabs"]],[[7, "tabs"]]]]).click()
|
||||
.execute("mobile: find", [["scroll",[[3, "content by id"]],[[7, "content by id"]]]]).click()
|
||||
.elementsByTagName("text").then(function(els) {
|
||||
// TODO: fix that, the second scroll doesn't scroll far enough.
|
||||
it('should be able to get selected value of a tab @skip-all-android', function (done) {
|
||||
driver
|
||||
.execute("mobile: find", [["scroll", [[3, "views"]], [[7, "views"]]]]).click()
|
||||
.execute("mobile: find", [["scroll", [[3, "tabs"]], [[7, "tabs"]]]]).click()
|
||||
.execute("mobile: find", [["scroll", [[3, "content by id"]], [[7, "content by id"]]]]).click()
|
||||
.elementsByTagName("text").then(function (els) {
|
||||
els[0].getAttribute('selected').should.become('false'); // the 1st text is not selected
|
||||
els[1].getAttribute('selected').should.become('true'); // tab 1 is selected
|
||||
}).nodeify(done);
|
||||
|
||||
@@ -1,203 +1,248 @@
|
||||
"use strict";
|
||||
|
||||
var path = require('path')
|
||||
var setup = require("../common/setup-base")
|
||||
, desired = require("./desired")
|
||||
, try3Times = require('../../helpers/repeat-utils').try3Times
|
||||
, sessionUtils = require('../../helpers/session-utils')
|
||||
, path = require('path')
|
||||
, ADB = require("../../../lib/devices/android/adb.js")
|
||||
, spawn = require('child_process').spawn
|
||||
, appPath = path.resolve(__dirname, "../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk")
|
||||
, badAppPath = path.resolve(__dirname, "../../../sample-code/apps/ApiDemos/bin/ApiDemos-debugz.apk")
|
||||
, appPkg = "com.example.android.apis"
|
||||
, appAct = ".ApiDemos"
|
||||
, appAct2 = "ApiDemos"
|
||||
, appAct3 = "com.example.android.apis.ApiDemos"
|
||||
, appAct4 = ".Blargimarg"
|
||||
, appUrl = 'http://appium.s3.amazonaws.com/ApiDemos-debug.apk'
|
||||
, describeUrl = require('../../helpers/driverblock.js').describeForApp(appUrl, "android", appPkg, appAct)
|
||||
, driverBlock = require("../../helpers/driverblock.js")
|
||||
, describeWd = driverBlock.describeForApp(appPath, "android", appPkg, appAct)
|
||||
, describeWd2 = driverBlock.describeForApp(appPath, "android", appPkg, appAct2)
|
||||
, describeWd3 = driverBlock.describeForApp(appPath, "android", appPkg, appAct3)
|
||||
, describeWd4 = driverBlock.describeForApp(appPath, "android", appPkg, appAct4)
|
||||
, describeBad = driverBlock.describeForApp(badAppPath, "android", appPkg,
|
||||
appAct)
|
||||
, describeNoPkg = driverBlock.describeForApp(appPath, "android", null, appAct)
|
||||
, describeNoAct = driverBlock.describeForApp(appPath, "android", appPkg, null)
|
||||
, it = driverBlock.it
|
||||
, chai = require('chai')
|
||||
, should = chai.should();
|
||||
, should = chai.should()
|
||||
, spawn = require('child_process').spawn
|
||||
, _ = require('underscore');
|
||||
|
||||
describeWd('basic', function(h) {
|
||||
it('should die with short command timeout', function(done) {
|
||||
var params = {timeout: 3};
|
||||
h.driver
|
||||
.execute("mobile: setCommandTimeout", [params])
|
||||
.sleep(4000)
|
||||
.elementByName('Animation')
|
||||
.should.be.rejectedWith(/status: (13|6)/)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
describe("apidemo - basic -", function () {
|
||||
|
||||
describeWd('basic', function(h) {
|
||||
it('should not die if commands come in', function(done) {
|
||||
var start;
|
||||
var find = function() {
|
||||
if ((Date.now() - start) < 5000) {
|
||||
return h.driver
|
||||
.elementByName('Animation').should.eventually.exist
|
||||
.then(find);
|
||||
}
|
||||
};
|
||||
var params = {timeout: 7};
|
||||
h.driver
|
||||
.execute("mobile: setCommandTimeout", [params])
|
||||
.then(function() { start = Date.now(); })
|
||||
.then(find)
|
||||
.sleep(10000)
|
||||
.elementByName('Animation').should.be.rejected
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describeWd('basic', function(h) {
|
||||
it('should get device size', function(done) {
|
||||
h.driver.getWindowSize()
|
||||
.then(function(size) {
|
||||
size.width.should.be.above(0);
|
||||
size.height.should.be.above(0);
|
||||
}).nodeify(done);
|
||||
afterEach(function (done) {
|
||||
setTimeout(function () { done(); }, 2000); // cooldown
|
||||
});
|
||||
|
||||
it('should be able to get current activity', function(done) {
|
||||
h.driver
|
||||
.execute("mobile: currentActivity")
|
||||
.should.eventually.include("ApiDemos")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to get logcat log type', function(done) {
|
||||
h.driver
|
||||
.logTypes()
|
||||
.should.eventually.include('logcat')
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to get logcat logs', function(done) {
|
||||
h.driver.log('logcat').then(function(logs) {
|
||||
logs.length.should.be.above(0);
|
||||
logs[0].message.should.not.include("\n");
|
||||
logs[0].level.should.equal("ALL");
|
||||
logs[0].timestamp.should.exist;
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should be able to detect if app is installed', function(done) {
|
||||
h.driver
|
||||
.execute('mobile: isAppInstalled', [{bundleId: 'foo'}])
|
||||
.should.eventually.equal(false)
|
||||
.execute('mobile: isAppInstalled', [{bundleId: 'com.example.android.apis'}])
|
||||
.should.eventually.equal(true)
|
||||
.nodeify(done);
|
||||
});
|
||||
it("should background the app", function(done) {
|
||||
var before = new Date().getTime() / 1000;
|
||||
h.driver
|
||||
.execute("mobile: background", [{seconds: 3}])
|
||||
.then(function() {
|
||||
((new Date().getTime() / 1000) - before).should.be.above(2);
|
||||
((new Date().getTime() / 1000) - before).should.be.below(5);
|
||||
})
|
||||
.execute("mobile: currentActivity")
|
||||
.should.eventually.include("ApiDemos")
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
describe('short command timeout', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
// todo: not working in Nexus7
|
||||
describeWd('without fastClear', function(h) {
|
||||
it('should still be able to reset', function(done) {
|
||||
h.driver
|
||||
.execute('mobile: reset')
|
||||
.getWindowSize()
|
||||
.nodeify(done);
|
||||
});
|
||||
}, null, null, null, {fastClear: false});
|
||||
|
||||
describeWd2('activity style: no period', function() {
|
||||
it('should still find activity', function(done) {
|
||||
done();
|
||||
});
|
||||
}, null, null, null, {expectConnError: true});
|
||||
|
||||
describeWd3('activity style: fully qualified', function() {
|
||||
it('should still find activity', function(done) {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describeWd4('activity style: non-existent', function(h) {
|
||||
it('should throw an error', function(done) {
|
||||
h.connError.should.exist;
|
||||
var err = JSON.parse(h.connError.data);
|
||||
err.value.origValue.should.include("Activity used to start app doesn't exist");
|
||||
done();
|
||||
});
|
||||
}, null, null, null, {expectConnError: true});
|
||||
|
||||
describeBad('bad app path', function(h) {
|
||||
it('should throw an error', function(done) {
|
||||
h.connError.should.exist;
|
||||
var err = JSON.parse(h.connError.data);
|
||||
err.value.origValue.should.include("Error locating the app");
|
||||
done();
|
||||
});
|
||||
}, null, null, null, {expectConnError: true});
|
||||
|
||||
describeNoAct('no activity sent in with caps', function(h) {
|
||||
it('should throw an error', function(done) {
|
||||
h.connError.should.exist;
|
||||
var err = JSON.parse(h.connError.data);
|
||||
err.value.origValue.should.include("app-activity");
|
||||
done();
|
||||
});
|
||||
}, null, null, null, {expectConnError: true});
|
||||
|
||||
describeNoPkg('no package sent in with caps', function(h) {
|
||||
it('should throw an error', function(done) {
|
||||
h.connError.should.exist;
|
||||
var err = JSON.parse(h.connError.data);
|
||||
err.value.origValue.should.include("app-package");
|
||||
done();
|
||||
});
|
||||
}, null, null, null, {expectConnError: true});
|
||||
|
||||
describe('pre-existing uiautomator session', function() {
|
||||
before(function(done) {
|
||||
var adb = new ADB();
|
||||
var binPath = path.resolve(__dirname, "..", "..", "..", "build",
|
||||
"android_bootstrap", "AppiumBootstrap.jar");
|
||||
var uiArgs = ["shell", "uiautomator", "runtest", "AppiumBootstrap.jar", "-c",
|
||||
"io.appium.android.bootstrap.Bootstrap"];
|
||||
adb.push(binPath, "/data/local/tmp/", function(err) {
|
||||
should.not.exist(err);
|
||||
spawn("adb", uiArgs);
|
||||
setTimeout(function() {
|
||||
adb.getPIDsByName("uiautomator", function(err, pids) {
|
||||
should.not.exist(err);
|
||||
pids.length.should.equal(1);
|
||||
done();
|
||||
});
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
describeWd('launching new session', function(h) {
|
||||
it('should kill pre-existing uiautomator process', function(done) {
|
||||
h.driver.getWindowSize().should.eventually.exist
|
||||
it('should die with short command timeout', function (done) {
|
||||
var params = {timeout: 3};
|
||||
driver
|
||||
.execute("mobile: setCommandTimeout", [params])
|
||||
.sleep(4000)
|
||||
.elementByName('Animation')
|
||||
.should.be.rejectedWith(/status: (13|6)/)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describeUrl('appium android', function(h) {
|
||||
it('should load a zipped app via url', function(done) {
|
||||
h.driver.execute("mobile: currentActivity")
|
||||
.should.eventually.include("ApiDemos")
|
||||
.nodeify(done);
|
||||
describe('commands coming in', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should not die if commands come in', function (done) {
|
||||
var start;
|
||||
var find = function () {
|
||||
if ((Date.now() - start) < 5000) {
|
||||
return driver
|
||||
.elementByName('Animation').should.eventually.exist
|
||||
.then(find);
|
||||
}
|
||||
};
|
||||
var params = {timeout: 7};
|
||||
driver
|
||||
.execute("mobile: setCommandTimeout", [params])
|
||||
.then(function () { start = Date.now(); })
|
||||
.then(find)
|
||||
.sleep(10000)
|
||||
.elementByName('Animation').should.be.rejected
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('api', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should get device size', function (done) {
|
||||
driver.getWindowSize()
|
||||
.then(function (size) {
|
||||
size.width.should.be.above(0);
|
||||
size.height.should.be.above(0);
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it('should be able to get current activity', function (done) {
|
||||
driver
|
||||
.execute("mobile: currentActivity")
|
||||
.should.eventually.include("ApiDemos")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to get logcat log type', function (done) {
|
||||
driver
|
||||
.logTypes()
|
||||
.should.eventually.include('logcat')
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to get logcat logs', function (done) {
|
||||
driver.log('logcat').then(function (logs) {
|
||||
logs.length.should.be.above(0);
|
||||
logs[0].message.should.not.include("\n");
|
||||
logs[0].level.should.equal("ALL");
|
||||
logs[0].timestamp.should.exist;
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it('should be able to detect if app is installed', function (done) {
|
||||
driver
|
||||
.execute('mobile: isAppInstalled', [{bundleId: 'foo'}])
|
||||
.should.eventually.equal(false)
|
||||
.execute('mobile: isAppInstalled', [{bundleId: 'com.example.android.apis'}])
|
||||
.should.eventually.equal(true)
|
||||
.nodeify(done);
|
||||
});
|
||||
it("should background the app", function (done) {
|
||||
var before = new Date().getTime() / 1000;
|
||||
driver
|
||||
.execute("mobile: background", [{seconds: 3}])
|
||||
.then(function () {
|
||||
((new Date().getTime() / 1000) - before).should.be.least(3);
|
||||
// should really not be checking this.
|
||||
//((new Date().getTime() / 1000) - before).should.be.below(5);
|
||||
})
|
||||
.execute("mobile: currentActivity")
|
||||
.should.eventually.include("ApiDemos")
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: fix that, that frequently hangs then crashes Appium
|
||||
describe('without fastClear @skip-all-android', function () {
|
||||
var driver;
|
||||
setup(this, _.defaults({fastClear: false}, desired))
|
||||
.then(function (d) { driver = d; });
|
||||
|
||||
it('should still be able to reset', function (done) {
|
||||
driver
|
||||
.sleep(3000)
|
||||
.execute('mobile: reset')
|
||||
.getWindowSize()
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('activity style: no period', function () {
|
||||
var session;
|
||||
after(function () { session.tearDown(); });
|
||||
it('should still find activity', function (done) {
|
||||
session = sessionUtils.initSession(_.defaults({'app-activity': 'ApiDemos'}, desired));
|
||||
session.setUp().nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('activity style: fully qualified', function () {
|
||||
var session;
|
||||
after(function () { session.tearDown(); });
|
||||
it('should still find activity', function (done) {
|
||||
session = sessionUtils.initSession(_.defaults({'app-activity': 'com.example.android.apis.ApiDemos'}, desired));
|
||||
session.setUp().nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('error cases', function () {
|
||||
var opts = {'no-retry': true};
|
||||
|
||||
describe('activity style: non-existent', function () {
|
||||
var session;
|
||||
after(function () { session.tearDown(); });
|
||||
it('should throw an error', function (done) {
|
||||
session = sessionUtils.initSession(_.defaults({'app-activity': '.Blargimarg'}, desired), opts);
|
||||
try3Times(function () {
|
||||
return session.setUp()
|
||||
.catch(function (err) { throw err.data; })
|
||||
.should.be.rejectedWith(/Activity used to start app doesn't exist/);
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('bad app path', function () {
|
||||
var session;
|
||||
after(function () { session.tearDown(); });
|
||||
it('should throw an error', function (done) {
|
||||
var badAppPath = path.resolve(__dirname, "../../../sample-code/apps/ApiDemos/bin/ApiDemos-debugz.apk");
|
||||
session = sessionUtils.initSession(_.defaults({'app': badAppPath}, desired), opts);
|
||||
try3Times(function () {
|
||||
return session.setUp()
|
||||
.catch(function (err) { throw err.data; })
|
||||
.should.be.rejectedWith(/Error locating the app/);
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('no activity sent in with caps', function () {
|
||||
var session;
|
||||
after(function () { session.tearDown(); });
|
||||
it('should throw an error', function (done) {
|
||||
session = sessionUtils.initSession(_.omit(desired, 'app-activity'), opts);
|
||||
try3Times(function () {
|
||||
return session.setUp()
|
||||
.catch(function (err) { throw err.data; })
|
||||
.should.be.rejectedWith(/app-activity/);
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('no package sent in with caps', function () {
|
||||
var session;
|
||||
after(function () { session.tearDown(); });
|
||||
it('should throw an error', function (done) {
|
||||
session = sessionUtils.initSession(_.omit(desired, 'app-package'), opts);
|
||||
try3Times(function () {
|
||||
return session.setUp()
|
||||
.catch(function (err) { throw err.data; })
|
||||
.should.be.rejectedWith(/app-package/);
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: fix that, same fastclear issue killing appium
|
||||
describe('pre-existing uiautomator session @skip-all-android', function () {
|
||||
before(function (done) {
|
||||
var adb = new ADB();
|
||||
var binPath = path.resolve(__dirname, "..", "..", "..", "build",
|
||||
"android_bootstrap", "AppiumBootstrap.jar");
|
||||
var uiArgs = ["shell", "uiautomator", "runtest", "AppiumBootstrap.jar", "-c",
|
||||
"io.appium.android.bootstrap.Bootstrap"];
|
||||
adb.push(binPath, "/data/local/tmp/", function (err) {
|
||||
should.not.exist(err);
|
||||
spawn("adb", uiArgs);
|
||||
setTimeout(function () {
|
||||
adb.getPIDsByName("uiautomator", function (err, pids) {
|
||||
should.not.exist(err);
|
||||
pids.length.should.equal(1);
|
||||
done();
|
||||
});
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('launching new session', function () {
|
||||
var driver;
|
||||
setup(this, _.defaults({fastClear: false}, desired))
|
||||
.then(function (d) { driver = d; });
|
||||
|
||||
it('should kill pre-existing uiautomator process', function (done) {
|
||||
driver.getWindowSize().should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('appium android', function () {
|
||||
var session;
|
||||
after(function () { session.tearDown(); });
|
||||
it('should load a zipped app via url', function (done) {
|
||||
var appUrl = 'http://appium.s3.amazonaws.com/ApiDemos-debug.apk';
|
||||
session = sessionUtils.initSession(_.defaults({'app': appUrl}, desired));
|
||||
session.setUp().nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
9
test/functional/apidemos/desired.js
Normal file
9
test/functional/apidemos/desired.js
Normal file
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
var appUtils = require('../../helpers/app-utils');
|
||||
|
||||
module.exports = {
|
||||
app: appUtils.getAppPath('ApiDemos'),
|
||||
'app-package': 'com.example.android.apis',
|
||||
'app-activity': '.ApiDemos'
|
||||
};
|
||||
@@ -1,171 +1,162 @@
|
||||
"use strict";
|
||||
|
||||
var path = require('path')
|
||||
, appPath = path.resolve(__dirname, "../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk")
|
||||
, appPkg = "com.example.android.apis"
|
||||
, appAct = ".ApiDemos"
|
||||
, describeWd = require("../../helpers/driverblock.js").describeForApp(appPath,
|
||||
"android", appPkg, appAct)
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var env = require('../../helpers/env')
|
||||
, setup = require("../common/setup-base")
|
||||
, desired = require("./desired")
|
||||
, androidReset = require('../../helpers/reset-utils').androidReset;
|
||||
|
||||
describeWd('find elements', function(h) {
|
||||
describe("apidemo - find elements -", function () {
|
||||
|
||||
if (process.env.FAST_TESTS) {
|
||||
afterEach(function(done) {
|
||||
// going back to main page if necessary todo: find better way
|
||||
function back() {
|
||||
return h.driver.elementByNameOrNull('Accessibility').then(function(el) {
|
||||
if (!el) return h.driver.back();
|
||||
});
|
||||
}
|
||||
back().then(back).nodeify(done);
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
if (env.FAST_TESTS) {
|
||||
beforeEach(function (done) {
|
||||
androidReset(desired['app-package'], desired['app-activity']).nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
describe('mobile find', function() {
|
||||
it('should scroll to an element by text or content desc', function(done) {
|
||||
h.driver
|
||||
.execute("mobile: find", [["scroll",[[3, "views"]],[[7, "views"]]]]).text()
|
||||
describe('mobile find', function () {
|
||||
it('should scroll to an element by text or content desc', function (done) {
|
||||
driver
|
||||
.execute("mobile: find", [["scroll", [[3, "views"]], [[7, "views"]]]]).text()
|
||||
.should.become("Views")
|
||||
.nodeify(done);
|
||||
});
|
||||
// todo: does not work in Nexus7
|
||||
it('should find a single element by content-description', function(done) {
|
||||
h.driver.execute("mobile: find", [[[[7, "Animation"]]]]).text()
|
||||
it('should find a single element by content-description', function (done) {
|
||||
driver.execute("mobile: find", [[[[7, "Animation"]]]]).text()
|
||||
.should.become("Animation")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should find a single element by text', function(done) {
|
||||
h.driver.execute("mobile: find", [[[[3, "Animation"]]]]).text()
|
||||
it('should find a single element by text', function (done) {
|
||||
driver.execute("mobile: find", [[[[3, "Animation"]]]]).text()
|
||||
.should.become("Animation")
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('find element(s)', function() {
|
||||
it('should find a single element by content-description', function(done) {
|
||||
h.driver
|
||||
describe('find element(s) methods', function () {
|
||||
it('should find a single element by content-description', function (done) {
|
||||
driver
|
||||
.elementByName("Animation").text().should.become("Animation")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should find a single element by tag name', function(done) {
|
||||
h.driver
|
||||
it('should find a single element by tag name', function (done) {
|
||||
driver
|
||||
.elementByTagName("text").text().should.become("API Demos")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should find multiple elements by tag name', function(done) {
|
||||
h.driver
|
||||
it('should find multiple elements by tag name', function (done) {
|
||||
driver
|
||||
.elementsByTagName("text")
|
||||
.should.eventually.have.length.at.least(10)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should not find an element that doesnt exist', function(done) {
|
||||
h.driver
|
||||
it('should not find an element that doesnt exist', function (done) {
|
||||
driver
|
||||
.elementByTagName("blargimarg").should.be.rejectedWith(/status: 7/)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should not find multiple elements that doesnt exist', function(done) {
|
||||
h.driver
|
||||
it('should not find multiple elements that doesnt exist', function (done) {
|
||||
driver
|
||||
.elementsByTagName("blargimarg").should.eventually.have.length(0)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should fail on empty locator', function(done) {
|
||||
h.driver.elementsByTagName("")
|
||||
.catch(function(err) {
|
||||
err.data.should.include("selector");
|
||||
throw err;
|
||||
}).should.be.rejected
|
||||
it('should fail on empty locator', function (done) {
|
||||
driver.elementsByTagName("")
|
||||
.catch(function (err) { throw err.data; }).should.be.rejectedWith(/selector/)
|
||||
.elementsByTagName("text").should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should find a single element by id', function(done) {
|
||||
h.driver
|
||||
.execute("mobile: find", [["scroll",[[3, "views"]],[[7, "views"]]]]).click()
|
||||
it('should find a single element by id', function (done) {
|
||||
driver
|
||||
.execute("mobile: find", [["scroll", [[3, "views"]], [[7, "views"]]]]).click()
|
||||
.elementByXPath("//text[@text='Buttons']").click()
|
||||
.elementById("buttons_1_normal").text().should.become("Normal")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should find a single element by resource-id', function(done) {
|
||||
h.driver
|
||||
// TODO: find by resource id doesn't seem to work
|
||||
it('should find a single element by resource-id @skip-all-android', function (done) {
|
||||
driver
|
||||
.elementById('android:id/home').should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should find multiple elements by resource-id', function(done) {
|
||||
h.driver
|
||||
it('should find multiple elements by resource-id @skip-all-android', function (done) {
|
||||
driver
|
||||
.elementsById('android:id/text1')
|
||||
.should.eventually.have.length.at.least(10)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('find element(s) from element', function() {
|
||||
it('should find a single element by tag name', function(done) {
|
||||
h.driver.elementByTagName("list").then(function(el) {
|
||||
describe('find element(s) from element', function () {
|
||||
it('should find a single element by tag name', function (done) {
|
||||
driver.elementByTagName("list").then(function (el) {
|
||||
return el
|
||||
.elementByTagName("text").text().should.become("Accessibility");
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should find multiple elements by tag name', function(done) {
|
||||
h.driver.elementByTagName("list").then(function(el) {
|
||||
it('should find multiple elements by tag name', function (done) {
|
||||
driver.elementByTagName("list").then(function (el) {
|
||||
return el
|
||||
.elementsByTagName("text").should.eventually.have.length.at.least(10);
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should not find an element that doesnt exist', function(done) {
|
||||
h.driver.elementByTagName("list").then(function(el) {
|
||||
it('should not find an element that doesnt exist', function (done) {
|
||||
driver.elementByTagName("list").then(function (el) {
|
||||
return el
|
||||
.elementByTagName("blargimarg").should.be.rejectedWith(/status: 7/);
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should not find multiple elements that doesnt exist', function(done) {
|
||||
h.driver.elementByTagName("list").then(function(el) {
|
||||
it('should not find multiple elements that doesnt exist', function (done) {
|
||||
driver.elementByTagName("list").then(function (el) {
|
||||
return el
|
||||
.elementsByTagName("blargimarg").should.eventually.have.length(0);
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('xpath', function() {
|
||||
it('should find element by type', function(done) {
|
||||
h.driver
|
||||
describe('xpath', function () {
|
||||
it('should find element by type', function (done) {
|
||||
driver
|
||||
.elementByXPath('//text').text()
|
||||
.should.become("API Demos")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should find element by text', function(done) {
|
||||
h.driver
|
||||
it('should find element by text', function (done) {
|
||||
driver
|
||||
.elementByXPath("//text[@value='Accessibility']").text()
|
||||
.should.become("Accessibility")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should find element by partial text', function(done) {
|
||||
h.driver
|
||||
it('should find element by partial text', function (done) {
|
||||
driver
|
||||
.elementByXPath("//text[contains(@value, 'Accessibility')]").text()
|
||||
.should.become("Accessibility")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should find the last element', function(done) {
|
||||
h.driver
|
||||
it('should find the last element', function (done) {
|
||||
driver
|
||||
.elementByXPath("//text[last()]").text()
|
||||
.then(function(text) {
|
||||
.then(function (text) {
|
||||
["OS", "Text", "Views"].should.include(text);
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should find element by xpath index and child', function(done) {
|
||||
h.driver
|
||||
it('should find element by xpath index and child', function (done) {
|
||||
driver
|
||||
.elementByXPath("//frame[1]/frame[1]/list[1]/text[3]").text()
|
||||
.should.become("App")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should find element by index and embedded desc', function(done) {
|
||||
h.driver
|
||||
it('should find element by index and embedded desc', function (done) {
|
||||
driver
|
||||
.elementByXPath("//frame/frame[1]//text[3]").text()
|
||||
.should.become("App")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should get an error when strategy doesnt exist', function(done) {
|
||||
h.driver
|
||||
.elementByCss('button').catch(function(err) {
|
||||
it('should get an error when strategy doesnt exist', function (done) {
|
||||
driver
|
||||
.elementByCss('button').catch(function (err) {
|
||||
err.cause.value.message.should.equal("Invalid locator strategy: css selector");
|
||||
throw err;
|
||||
}).should.be.rejectedWith(/status: 9/)
|
||||
@@ -173,13 +164,11 @@ describeWd('find elements', function(h) {
|
||||
});
|
||||
});
|
||||
|
||||
describe('unallowed tag names', function() {
|
||||
it('should not find secure fields', function(done) {
|
||||
h.driver
|
||||
.elementsByTagName('secure').catch(function(err) {
|
||||
err.cause.value.origValue.should.include("not supported in Android");
|
||||
throw err;
|
||||
}).should.be.rejected
|
||||
describe('unallowed tag names', function () {
|
||||
it('should not find secure fields', function (done) {
|
||||
driver
|
||||
.elementsByTagName('secure').catch(function (err) { throw JSON.stringify(err.cause.value); })
|
||||
.should.be.rejectedWith(/not supported in Android/)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,237 +1,230 @@
|
||||
"use strict";
|
||||
|
||||
var path = require('path')
|
||||
, appPath = path.resolve(__dirname, "../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk")
|
||||
, appPkg = "com.example.android.apis"
|
||||
, appAct = ".ApiDemos"
|
||||
, driverblock = require("../../helpers/driverblock.js")
|
||||
, Q = driverblock.Q
|
||||
, describeWd = driverblock.describeForApp(appPath,
|
||||
"android", appPkg, appAct)
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var env = require('../../helpers/env')
|
||||
, setup = require("../common/setup-base")
|
||||
, desired = require("./desired")
|
||||
, androidReset = require('../../helpers/reset-utils').androidReset
|
||||
, Q = require("q");
|
||||
|
||||
describeWd('gestures', function(h) {
|
||||
describe("apidemo - gestures -", function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
if (process.env.FAST_TESTS) {
|
||||
afterEach(function(done) {
|
||||
// going back to main page if necessary todo: find better way
|
||||
function back() {
|
||||
return h.driver.elementByNameOrNull('Accessibility').then(function(el) {
|
||||
if (!el) return h.driver.back();
|
||||
});
|
||||
}
|
||||
back().then(back).nodeify(done);
|
||||
if (env.FAST_TESTS) {
|
||||
beforeEach(function (done) {
|
||||
androidReset(desired['app-package'], desired['app-activity']).nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should click via x/y pixel coords', function(done) {
|
||||
h.driver
|
||||
it('should click via x/y pixel coords', function (done) {
|
||||
driver
|
||||
.execute("mobile: tap", [{x: 100, y: 300}])
|
||||
.sleep(3000)
|
||||
.elementsByTagName("text").then(function(els) { return els[1]; })
|
||||
.elementsByTagName("text").then(function (els) { return els[1]; })
|
||||
.text().should.become("Action Bar")
|
||||
.nodeify(done);
|
||||
});
|
||||
//todo: not working in nexus 7
|
||||
it(' should click via x/y pct', function(done) {
|
||||
it(' should click via x/y pct', function (done) {
|
||||
// this test depends on having a certain size screen, obviously
|
||||
// I use a nexus something or other phone style thingo
|
||||
h.driver
|
||||
driver
|
||||
.execute("mobile: tap", [{x: 0.6, y: 0.8}])
|
||||
.sleep(3000)
|
||||
.elementsByTagName("text").then(function(els) { return els[1]; }).text()
|
||||
.then(function(text) {
|
||||
.elementsByTagName("text").then(function (els) { return els[1]; }).text()
|
||||
.then(function (text) {
|
||||
["ForegroundDispatch", "Morse Code"].should.include(text);
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should click via touch api', function(done) {
|
||||
it('should click via touch api', function (done) {
|
||||
// this test depends on having a certain size screen, obviously
|
||||
// I use a nexus something or other phone style thingo
|
||||
h.driver.elementByName("Animation").tap()
|
||||
driver.elementByName("Animation").tap()
|
||||
.sleep(1500)
|
||||
.elementsByTagName("text").then(function(els) { return els[1]; })
|
||||
.elementsByTagName("text").then(function (els) { return els[1]; })
|
||||
.text().should.become("Bouncing Balls")
|
||||
.nodeify(done);
|
||||
});
|
||||
// todo fix this test, success depends on emulator size
|
||||
it('should swipe screen by pixels', function(done) {
|
||||
// todo fix this: got Error response status: 13, The swipe did not complete successfully
|
||||
it('should swipe screen by pixels @skip-all-android', function (done) {
|
||||
var swipeOpts = {
|
||||
startX: 100
|
||||
, startY: 500
|
||||
, endX: 100
|
||||
, endY: 100
|
||||
, duration: 1.2
|
||||
, startY: 500
|
||||
, endX: 100
|
||||
, endY: 100
|
||||
, duration: 1.2
|
||||
};
|
||||
h.driver
|
||||
// .elementByName("Views").should.be.rejected // shouldn't be visible
|
||||
driver
|
||||
.elementByName("Views").should.be.rejected // shouldn't be visible
|
||||
.execute("mobile: swipe", [swipeOpts])
|
||||
.elementByName("Views").should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
// todo fix this test, success depends on emulator size
|
||||
it('should swipe screen by pct', function(done) {
|
||||
// todo fix this: got Error response status: 13, The swipe did not complete successfully
|
||||
it('should swipe screen by pct @skip-all-android', function (done) {
|
||||
var swipeOpts = {
|
||||
endX: 0.5
|
||||
, endY: 0.05
|
||||
, duration: 0.7
|
||||
, endY: 0.05
|
||||
, duration: 0.7
|
||||
};
|
||||
h.driver
|
||||
// .elementByName("Views").should.be.rejected // shouldn't be visible
|
||||
driver
|
||||
.elementByName("Views").should.be.rejected // shouldn't be visible
|
||||
.execute("mobile: swipe", [swipeOpts])
|
||||
.elementByName("Views").should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
// todo fix this test, success depends on emulator size
|
||||
it('should flick screen by pixels', function(done) {
|
||||
// todo fix this: got Error response status: 13, The swipe did not complete successfully
|
||||
it('should flick screen by pixels @skip-all-android', function (done) {
|
||||
var swipeOpts = {
|
||||
startX: 100
|
||||
, startY: 500
|
||||
, endX: 100
|
||||
, endY: 100
|
||||
, startY: 500
|
||||
, endX: 100
|
||||
, endY: 100
|
||||
};
|
||||
h.driver
|
||||
// .elementByName("Views").should.be.rejected // shouldn't be visible
|
||||
driver
|
||||
.elementByName("Views").should.be.rejected // shouldn't be visible
|
||||
.execute("mobile: flick", [swipeOpts])
|
||||
.elementByName("Views").should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
// todo fix this test, success depends on emulator size
|
||||
it('should flick screen by speed', function(done) {
|
||||
h.driver
|
||||
// .elementByName("Views").should.be.rejected // shouldn't be visible
|
||||
// todo fix this: got Error response status: 13, Flick did not complete successfully
|
||||
it('should flick screen by speed @skip-all-android', function (done) {
|
||||
driver
|
||||
.elementByName("Views").should.be.rejected // shouldn't be visible
|
||||
.flick(0, -100)
|
||||
.elementByName("Views").should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
// todo fix this test, it is testing nothing on big screens
|
||||
it('should drag by pixels', function(done) {
|
||||
// todo fix this: got Error response status: 13, Could not scroll element into view: Views
|
||||
it('should drag by pixels @skip-all-android', function (done) {
|
||||
var scrollOpts;
|
||||
h.driver.elementByTagName("listView")
|
||||
.then(function(el) {
|
||||
driver.elementByTagName("listView")
|
||||
.then(function (el) {
|
||||
scrollOpts = { element: el.value, text: 'Views' };
|
||||
return h.driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
return driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
}).elementByXPath("//text[@value='Views']").click()
|
||||
.then(function() {
|
||||
.then(function () {
|
||||
scrollOpts.text = 'Drag and Drop';
|
||||
return h.driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
return driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
}).elementByXPath("//text[@value='Drag and Drop']").click()
|
||||
.then(function() {
|
||||
.then(function () {
|
||||
return Q.all([
|
||||
h.driver.elementById("com.example.android.apis:id/drag_dot_3").getLocation(),
|
||||
h.driver.elementById("com.example.android.apis:id/drag_dot_2").getLocation()
|
||||
driver.elementById("com.example.android.apis:id/drag_dot_3").getLocation(),
|
||||
driver.elementById("com.example.android.apis:id/drag_dot_2").getLocation()
|
||||
]);
|
||||
}).then(function(locations) {
|
||||
}).then(function (locations) {
|
||||
var dragOpts = {
|
||||
startX: locations[0].x
|
||||
, startY: locations[0].y
|
||||
, endX: locations[1].x
|
||||
, endY: locations[1].y
|
||||
, startY: locations[0].y
|
||||
, endX: locations[1].x
|
||||
, endY: locations[1].y
|
||||
};
|
||||
return h.driver.execute("mobile: drag", [dragOpts]);
|
||||
return driver.execute("mobile: drag", [dragOpts]);
|
||||
}).elementById("com.example.android.apis:id/drag_result_text").text()
|
||||
.should.become("Dropped!")
|
||||
.nodeify(done);
|
||||
});
|
||||
// todo fix this test, it is testing nothing on big screens
|
||||
it('should drag element to point', function(done) {
|
||||
// todo fix this: got Error response status: 13, Could not scroll element into view: Views
|
||||
it('should drag element to point @skip-all-android', function (done) {
|
||||
var scrollOpts;
|
||||
h.driver
|
||||
driver
|
||||
.elementByTagName("listView")
|
||||
.then(function(el) {
|
||||
.then(function (el) {
|
||||
scrollOpts = {
|
||||
element: el.value
|
||||
, text: 'Views'
|
||||
, text: 'Views'
|
||||
};
|
||||
return h.driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
return driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
}).elementByXPath("//text[@value='Views']").click()
|
||||
.then(function() {
|
||||
.then(function () {
|
||||
scrollOpts.text = 'Drag and Drop';
|
||||
return h.driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
return driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
}).elementByXPath("//text[@value='Drag and Drop']").click()
|
||||
.then(function() {
|
||||
.then(function () {
|
||||
return Q.all([
|
||||
h.driver.elementById("com.example.android.apis:id/drag_dot_3"),
|
||||
h.driver.elementById("com.example.android.apis:id/drag_dot_2").getLocation()
|
||||
driver.elementById("com.example.android.apis:id/drag_dot_3"),
|
||||
driver.elementById("com.example.android.apis:id/drag_dot_2").getLocation()
|
||||
]);
|
||||
}).then(function(res) {
|
||||
}).then(function (res) {
|
||||
var dragOpts = {
|
||||
element: res[0].value
|
||||
, endX: res[1].x
|
||||
, endY: res[1].y
|
||||
, endX: res[1].x
|
||||
, endY: res[1].y
|
||||
};
|
||||
return h.driver.execute("mobile: drag", [dragOpts]);
|
||||
return driver.execute("mobile: drag", [dragOpts]);
|
||||
}).elementById("com.example.android.apis:id/drag_result_text").text()
|
||||
.should.become("Dropped!")
|
||||
.nodeify(done);
|
||||
});
|
||||
// todo fix this test, it is testing nothing on big screens
|
||||
it('should drag element to destEl', function(done) {
|
||||
// todo fix this: got Error response status: 13, Could not scroll element into view: Views
|
||||
it('should drag element to destEl @skip-all-android', function (done) {
|
||||
var scrollOpts;
|
||||
h.driver
|
||||
driver
|
||||
.elementByTagName("listView")
|
||||
.then(function(el) {
|
||||
.then(function (el) {
|
||||
scrollOpts = {
|
||||
element: el.value
|
||||
, text: 'Views'
|
||||
, text: 'Views'
|
||||
};
|
||||
return h.driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
return driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
}).elementByXPath("//text[@value='Views']").click()
|
||||
.then(function() {
|
||||
.then(function () {
|
||||
scrollOpts.text = 'Drag and Drop';
|
||||
return h.driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
return driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
}).elementByXPath("//text[@value='Drag and Drop']").click()
|
||||
.then(function() {
|
||||
.then(function () {
|
||||
return Q.all([
|
||||
h.driver.elementById("com.example.android.apis:id/drag_dot_3"),
|
||||
h.driver.elementById("com.example.android.apis:id/drag_dot_2")
|
||||
driver.elementById("com.example.android.apis:id/drag_dot_3"),
|
||||
driver.elementById("com.example.android.apis:id/drag_dot_2")
|
||||
]);
|
||||
}).then(function(els) {
|
||||
}).then(function (els) {
|
||||
var dragOpts = {
|
||||
element: els[0].value
|
||||
, destEl: els[1].value
|
||||
};
|
||||
return h.driver.execute("mobile: drag", [dragOpts]);
|
||||
return driver.execute("mobile: drag", [dragOpts]);
|
||||
}).elementById("com.example.android.apis:id/drag_result_text").text()
|
||||
.should.become("Dropped!")
|
||||
.nodeify(done);
|
||||
});
|
||||
// todo fix this test, success depends on emulator size
|
||||
it('should bring the element into view', function(done) {
|
||||
h.driver
|
||||
// todo fix this: got Error response status: 13, Could not scroll element into view: Views
|
||||
it('should bring the element into view @skip-all-android', function (done) {
|
||||
driver
|
||||
// .elementByName("Views").should.be.rejected // shouldn't be visible
|
||||
.elementByTagName("listView")
|
||||
.then(function(el) {
|
||||
.then(function (el) {
|
||||
var scrollOpts = {
|
||||
element: el.value
|
||||
, text: 'Views'
|
||||
, text: 'Views'
|
||||
};
|
||||
return h.driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
return driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
}).elementByName("Views").should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should pinch out/in', function(done) {
|
||||
// todo fix this: got Error response status: 13, Could not scroll element into view: Views
|
||||
it('should pinch out/in @skip-all-android', function (done) {
|
||||
var scrollOpts;
|
||||
h.driver
|
||||
driver
|
||||
.elementByTagName("listView")
|
||||
.then(function(el) {
|
||||
.then(function (el) {
|
||||
scrollOpts = {
|
||||
element: el.value
|
||||
, text: 'Views'
|
||||
, text: 'Views'
|
||||
};
|
||||
return h.driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
return driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
}).elementByXPath("//text[@value='Views']").click()
|
||||
.then(function() {
|
||||
.then(function () {
|
||||
scrollOpts.text = 'WebView';
|
||||
return h.driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
return driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
}).elementByXPath("//text[@value='WebView']").click()
|
||||
.elementById("com.example.android.apis:id/wv1")
|
||||
.then(function(el) {
|
||||
.then(function (el) {
|
||||
var pinchOpts = {
|
||||
element: el.value
|
||||
, percent: 200
|
||||
, steps: 100
|
||||
, percent: 200
|
||||
, steps: 100
|
||||
};
|
||||
return h.driver
|
||||
return driver
|
||||
.execute("mobile: pinchOpen", [pinchOpts])
|
||||
.execute("mobile: pinchClose", [pinchOpts]);
|
||||
}).nodeify(done);
|
||||
|
||||
@@ -1,33 +1,31 @@
|
||||
"use strict";
|
||||
|
||||
var path = require('path')
|
||||
, appPath = path.resolve(__dirname, "../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk")
|
||||
, appPkg = "com.example.android.apis"
|
||||
, appAct = "view.Controls1"
|
||||
, describeWd = require("../../helpers/driverblock.js").describeForApp(appPath,
|
||||
"android", appPkg, appAct)
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base")
|
||||
, desired = require("./desired"),
|
||||
_ = require('underscore');
|
||||
|
||||
describeWd('text boxes', function(h) {
|
||||
describe("apidemo - keyboard -", function () {
|
||||
var driver;
|
||||
setup(this, _.defaults({'app-activity': "view.Controls1" }, desired))
|
||||
.then(function (d) { driver = d; });
|
||||
|
||||
it('should be able to edit a text field', function(done) {
|
||||
it('should be able to edit a text field', function (done) {
|
||||
var testText = "this is awesome!";
|
||||
var el = function() { return h.driver.elementByTagName('editText'); };
|
||||
h.driver
|
||||
var el = function () { return driver.elementByTagName('editText'); };
|
||||
driver
|
||||
.resolve(el()).clear().text().should.become("")
|
||||
.then(el).sendKeys(testText).text().should.become(testText)
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
//todo: not working in nexus 7
|
||||
it('should be able to edit and clear a text field', function(done) {
|
||||
it('should be able to edit and clear a text field', function (done) {
|
||||
var testText = "this is awesome!";
|
||||
var el = function() { return h.driver.elementByTagName('editText'); };
|
||||
h.driver
|
||||
var el = function () { return driver.elementByTagName('editText'); };
|
||||
driver
|
||||
.resolve(el()).clear().text().should.become("")
|
||||
.then(el).sendKeys(testText).text().should.become(testText)
|
||||
.then(el).clear().text().should.become("")
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,26 +1,31 @@
|
||||
"use strict";
|
||||
|
||||
var path = require('path')
|
||||
, appPath = path.resolve(__dirname, "../../../sample-code/apps/gps-demo/bin/GPSTutorial1.apk")
|
||||
, appPkg = "de.impressive.artworx.tutorials.gps"
|
||||
, appAct = "GPSTest"
|
||||
, driverBlock = require("../../helpers/driverblock.js")
|
||||
, describeWd = driverBlock.describeForApp(appPath, "android", appPkg, appAct)
|
||||
, it = driverBlock.it;
|
||||
var setup = require("../common/setup-base")
|
||||
, desired = require("./desired")
|
||||
, path = require('path');
|
||||
|
||||
describeWd('geo location', function(h) {
|
||||
it('should set geo location', function(done) {
|
||||
var getText = function() { return h.driver.elementByXPath("//text[2]").text(); };
|
||||
var desired = {
|
||||
app: path.resolve(__dirname, '../../../sample-code/apps/gps-demo/bin/GPSTutorial1.apk'),
|
||||
'app-package': 'de.impressive.artworx.tutorials.gps',
|
||||
'app-activity': 'GPSTest'
|
||||
};
|
||||
|
||||
describe("apidemo - location -", function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should set geo location', function (done) {
|
||||
var getText = function () { return driver.elementByXPath("//text[2]").text(); };
|
||||
var newLat = "27.17";
|
||||
var newLong = "78.04";
|
||||
h.driver
|
||||
.resolve(getText()).then(function(text) {
|
||||
driver
|
||||
.resolve(getText()).then(function (text) {
|
||||
text.should.not.include("Latitude: " + newLat);
|
||||
text.should.not.include("Longitude: " + newLong);
|
||||
}).then(function() {
|
||||
}).then(function () {
|
||||
var locOpts = {latitude: newLat, longitude: newLong};
|
||||
return h.driver.execute("mobile: setLocation", [locOpts]);
|
||||
}).sleep(1000).then(getText).then(function(text) {
|
||||
return driver.execute("mobile: setLocation", [locOpts]);
|
||||
}).sleep(1000).then(getText).then(function (text) {
|
||||
text.should.include("Latitude: " + newLat.substr(0, 4));
|
||||
text.should.include("Longitude: " + newLong.substr(0, 4));
|
||||
}).nodeify(done);
|
||||
|
||||
@@ -1,41 +1,42 @@
|
||||
"use strict";
|
||||
|
||||
var path = require('path')
|
||||
, appPath = path.resolve(__dirname, "../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk")
|
||||
, appPkg = "com.example.android.apis"
|
||||
, appAct = ".ApiDemos"
|
||||
, describeWd = require("../../helpers/driverblock.js").describeForApp(appPath,
|
||||
"android", appPkg, appAct)
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base")
|
||||
, env = require('../../helpers/env')
|
||||
, desired = require("./desired")
|
||||
, androidReset = require('../../helpers/reset-utils').androidReset;
|
||||
|
||||
describeWd('orientation', function(h) {
|
||||
if (process.env.FAST_TESTS) {
|
||||
afterEach(function(done) {
|
||||
h.driver.getOrientation().then(function(orientation) {
|
||||
if (orientation !== "PORTRAIT") {
|
||||
return h.driver.setOrientation("PORTRAIT");
|
||||
}
|
||||
}).nodeify(done);
|
||||
describe("apidemos - orientation -", function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
if (env.FAST_TESTS) {
|
||||
beforeEach(function (done) {
|
||||
androidReset(desired['app-package'], desired['app-activity']).nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should rotate screen to landscape', function(done) {
|
||||
h.driver
|
||||
it('should rotate screen to landscape', function (done) {
|
||||
driver
|
||||
.setOrientation("PORTRAIT")
|
||||
.sleep(3000)
|
||||
.setOrientation("LANDSCAPE")
|
||||
.sleep(3000)
|
||||
.getOrientation().should.become("LANDSCAPE")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should rotate screen to portrait', function(done) {
|
||||
h.driver
|
||||
it('should rotate screen to portrait', function (done) {
|
||||
driver
|
||||
.setOrientation("LANDSCAPE")
|
||||
.sleep(3000)
|
||||
.setOrientation("PORTRAIT")
|
||||
.sleep(3000)
|
||||
.getOrientation().should.become("PORTRAIT")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('Should not error when trying to rotate to portrait again', function(done) {
|
||||
h.driver
|
||||
it('Should not error when trying to rotate to portrait again', function (done) {
|
||||
driver
|
||||
.setOrientation("PORTRAIT")
|
||||
.sleep(3000)
|
||||
.setOrientation("PORTRAIT")
|
||||
.sleep(3000)
|
||||
.getOrientation().should.become("PORTRAIT")
|
||||
|
||||
@@ -1,35 +1,33 @@
|
||||
"use strict";
|
||||
|
||||
var path = require('path')
|
||||
, appPath = path.resolve(__dirname, "../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk")
|
||||
, appPkg = "com.example.android.apis"
|
||||
, appAct = ".ApiDemos"
|
||||
, describeWd = require("../../helpers/driverblock.js").describeForApp(appPath,
|
||||
"android", appPkg, appAct)
|
||||
, it = require("../../helpers/driverblock.js").it
|
||||
var setup = require("../common/setup-base")
|
||||
, desired = require("./desired")
|
||||
, fs = require('fs');
|
||||
|
||||
describeWd('screenshot', function(h) {
|
||||
//todo: not working in nexus 7
|
||||
it('should get a local screenshot', function(done) {
|
||||
describe("apidemos - screenshot -", function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
//todo: fix that got: Command failed: remote object '/data/local/tmp/screenshot.png' does not exist
|
||||
it('should get a local screenshot @skip-all-android', function (done) {
|
||||
var localScreenshotFile = '/tmp/test_screenshot_appium.png';
|
||||
if (fs.existsSync(localScreenshotFile)) {
|
||||
fs.unlinkSync(localScreenshotFile);
|
||||
}
|
||||
h.driver.execute("mobile: localScreenshot", [{file: localScreenshotFile}])
|
||||
.then(function() {
|
||||
driver.execute("mobile: localScreenshot", [{file: localScreenshotFile}])
|
||||
.then(function () {
|
||||
var screenshot = fs.readFileSync(localScreenshotFile);
|
||||
screenshot.should.exist;
|
||||
screenshot.length.should.be.above(1000);
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should get an app screenshot', function(done) {
|
||||
h.driver.takeScreenshot()
|
||||
it('should get an app screenshot', function (done) {
|
||||
driver.takeScreenshot()
|
||||
.should.eventually.have.length.above(1000)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should not cause other commands to fail', function(done) {
|
||||
h.driver
|
||||
it('should not cause other commands to fail', function (done) {
|
||||
driver
|
||||
.execute("mobile: find", [[[[3, "Animation"]]]])
|
||||
.takeScreenshot()
|
||||
.should.eventually.have.length.above(1000)
|
||||
|
||||
@@ -1,31 +1,37 @@
|
||||
"use strict";
|
||||
|
||||
var path = require('path')
|
||||
, appPath = path.resolve(__dirname, "../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk")
|
||||
, appPkg = "com.example.android.apis"
|
||||
, appAct = ".ApiDemos"
|
||||
, describeWd = require("../../helpers/driverblock.js").describeForApp(appPath,
|
||||
"android", appPkg, appAct)
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base")
|
||||
, desired = require("./desired");
|
||||
|
||||
describeWd('get source', function(h) {
|
||||
it('should return the page source', function(done) {
|
||||
h.driver
|
||||
describe("apidemos - source -", function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should return the page source', function (done) {
|
||||
driver
|
||||
.elementByNameOrNull('Accessibility') // waiting for page to load
|
||||
.source().then(function(source) {
|
||||
.source().then(function (source) {
|
||||
source.should.exist;
|
||||
source.should.include('android.widget.FrameLayout');
|
||||
source.should.include('@class');
|
||||
var obj = JSON.parse(source);
|
||||
obj.should.exist;
|
||||
obj.hierarchy.node['@class'].should.equal("android.widget.FrameLayout");
|
||||
obj.hierarchy.node.node.node[0].node['@class'].should.equal("android.widget.FrameLayout");
|
||||
// probably no need for so precise tests
|
||||
//obj.hierarchy.node['@class'].should.equal("android.widget.FrameLayout");
|
||||
//obj.hierarchy.node.node.node[0].node['@class'].should.equal("android.widget.FrameLayout");
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should return the page source without crashing other commands', function(done) {
|
||||
h.driver
|
||||
it('should return the page source without crashing other commands', function (done) {
|
||||
driver
|
||||
.execute("mobile: find", [[[[3, "Animation"]]]])
|
||||
.source().then(function(source) {
|
||||
.source().then(function (source) {
|
||||
source.should.exist;
|
||||
source.should.include('android.widget.FrameLayout');
|
||||
source.should.include('@class');
|
||||
var obj = JSON.parse(source);
|
||||
obj.should.exist;
|
||||
obj.hierarchy.node['@class'].should.equal("android.widget.FrameLayout");
|
||||
// probably no need for so precise tests
|
||||
//obj.hierarchy.node['@class'].should.equal("android.widget.FrameLayout");
|
||||
//obj.hierarchy.node.node.node[0].node['@class'].should.equal("android.widget.FrameLayout");
|
||||
}).execute("mobile: find", [[[[3, "Animation"]]]])
|
||||
.nodeify(done);
|
||||
|
||||
@@ -5,10 +5,10 @@ var chai = require('chai')
|
||||
, serverHub = serverUrl + '/wd/hub/session'
|
||||
, request = require('request');
|
||||
|
||||
describe('JSONWP request', function() {
|
||||
describe('to a non-existent url', function() {
|
||||
it('should get 404 with text/plain body', function(done) {
|
||||
request.get(serverUrl + '/a/bad/path', function(err, res, body) {
|
||||
describe("appium - jsonwp -", function () {
|
||||
describe('to a non-existent url', function () {
|
||||
it('should get 404 with text/plain body', function (done) {
|
||||
request.get(serverUrl + '/a/bad/path', function (err, res, body) {
|
||||
should.not.exist(err);
|
||||
res.headers['content-type'].should.equal('text/plain');
|
||||
res.statusCode.should.equal(404);
|
||||
@@ -17,19 +17,19 @@ describe('JSONWP request', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('to get list of sessions', function() {
|
||||
it('should return empty list if no session active', function(done) {
|
||||
request.get(serverHub + 's', function(err, res, body) {
|
||||
describe('to get list of sessions', function () {
|
||||
it('should return empty list if no session active', function (done) {
|
||||
request.get(serverHub + 's', function (err, res, body) {
|
||||
should.not.exist(err);
|
||||
JSON.parse(body).value.should.deep.equal([]);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('to a not-yet-implemented url', function() {
|
||||
it('should respond with 501 Not Implemented', function(done) {
|
||||
describe('to a not-yet-implemented url', function () {
|
||||
it('should respond with 501 Not Implemented', function (done) {
|
||||
var url = serverHub + '/fakesessid/ime/deactivate';
|
||||
request.post(url, function(err, res, body) {
|
||||
request.post(url, function (err, res, body) {
|
||||
should.not.exist(err);
|
||||
res.statusCode.should.equal(501);
|
||||
JSON.parse(body).status.should.equal(13);
|
||||
@@ -37,20 +37,20 @@ describe('JSONWP request', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('to a variable resource that doesnt exist', function() {
|
||||
it('should respond with a 404', function(done) {
|
||||
describe('to a variable resource that doesnt exist', function () {
|
||||
it('should respond with a 404', function (done) {
|
||||
var url = serverHub + '/fakesessid';
|
||||
request.get(url, function(err, res) {
|
||||
request.get(url, function (err, res) {
|
||||
should.not.exist(err);
|
||||
res.statusCode.should.equal(404);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('that generates a server error', function() {
|
||||
it('should respond with a 500', function(done) {
|
||||
describe('that generates a server error', function () {
|
||||
it('should respond with a 500', function (done) {
|
||||
var url = serverUrl + '/wd/hub/produce_error';
|
||||
request.post(url, function(err, res, body) {
|
||||
request.post(url, function (err, res, body) {
|
||||
should.not.exist(err);
|
||||
res.statusCode.should.equal(500);
|
||||
body.should.be.ok;
|
||||
@@ -60,10 +60,10 @@ describe('JSONWP request', function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('that generates a server crash', function() {
|
||||
it('should respond with a 500', function(done) {
|
||||
describe('that generates a server crash', function () {
|
||||
it('should respond with a 500', function (done) {
|
||||
var url = serverUrl + '/wd/hub/crash';
|
||||
request.post(url, function(err, res, body) {
|
||||
request.post(url, function (err, res, body) {
|
||||
should.not.exist(err);
|
||||
res.statusCode.should.equal(500);
|
||||
body.should.be.ok;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"use strict";
|
||||
var path = require('path')
|
||||
var env = require('../../helpers/env')
|
||||
, path = require('path')
|
||||
, iosApp = path.resolve(__dirname, "..", "..", "..", "sample-code", "apps",
|
||||
"TestApp", "build", "Release-iphonesimulator", "TestApp.app")
|
||||
, androidApp = path.resolve(__dirname, "..", "..", "..", "sample-code",
|
||||
@@ -7,7 +8,7 @@ var path = require('path')
|
||||
, spawn = require('child_process').spawn
|
||||
, crazyPort = 4799;
|
||||
|
||||
var waitForLaunch = function(app, extraArgs, cb) {
|
||||
var waitForLaunch = function (app, extraArgs, cb) {
|
||||
var args = [".", "-p", crazyPort, "-l", "-dd", "-m"];
|
||||
if (app) {
|
||||
args = args.concat(["--app", app]);
|
||||
@@ -18,24 +19,24 @@ var waitForLaunch = function(app, extraArgs, cb) {
|
||||
proc.stderr.setEncoding('utf8');
|
||||
var calledBack = false;
|
||||
var output = '';
|
||||
var tm = setTimeout(function() {
|
||||
var tm = setTimeout(function () {
|
||||
calledBack = true;
|
||||
proc.kill();
|
||||
cb(new Error("Appium never started. Output was: " + output));
|
||||
}, 60000);
|
||||
proc.stdout.on('data', function(data) {
|
||||
proc.stdout.on('data', function (data) {
|
||||
output += data;
|
||||
if (!calledBack &&/Appium REST http interface listener started on/.test(data)) {
|
||||
if (!calledBack && /Appium REST http interface listener started on/.test(data)) {
|
||||
clearTimeout(tm);
|
||||
proc.kill();
|
||||
calledBack = true;
|
||||
cb();
|
||||
}
|
||||
});
|
||||
proc.stderr.on('data', function(data) {
|
||||
proc.stderr.on('data', function (data) {
|
||||
output += data;
|
||||
});
|
||||
proc.on('exit', function() {
|
||||
proc.on('exit', function () {
|
||||
if (!calledBack) {
|
||||
calledBack = true;
|
||||
cb(new Error("Appium never started. Output was: " + output));
|
||||
@@ -43,30 +44,31 @@ var waitForLaunch = function(app, extraArgs, cb) {
|
||||
});
|
||||
};
|
||||
|
||||
describe('Pre-launching apps', function() {
|
||||
it('should work for ios', function(done) {
|
||||
describe("appium - prelaunch -", function () {
|
||||
this.timeout(env.MOCHA_TIMEOUT);
|
||||
it('should work for ios', function (done) {
|
||||
waitForLaunch(iosApp, [], done);
|
||||
});
|
||||
|
||||
it('should work with force iphone', function(done) {
|
||||
it('should work with force iphone', function (done) {
|
||||
waitForLaunch(iosApp, ['--force-iphone'], done);
|
||||
});
|
||||
|
||||
it('should work with force ipad', function(done) {
|
||||
it('should work with force ipad', function (done) {
|
||||
waitForLaunch(iosApp, ['--force-ipad'], done);
|
||||
});
|
||||
|
||||
it('should work for android', function(done) {
|
||||
it('should work for android @skip-all-ios', function (done) {
|
||||
var args = ["--app-pkg", "com.example.android.apis", "--app-activity",
|
||||
".ApiDemos"];
|
||||
waitForLaunch(androidApp, args, done);
|
||||
});
|
||||
|
||||
it('should work for safari', function(done) {
|
||||
it('should work for safari', function (done) {
|
||||
waitForLaunch('safari', [], done);
|
||||
});
|
||||
|
||||
it('should work for safari via --safari', function(done) {
|
||||
it('should work for safari via --safari', function (done) {
|
||||
waitForLaunch(null, ['--safari'], done);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
var wvHelpers = require("../../helpers/webview.js")
|
||||
, webviewTests = wvHelpers.buildTests;
|
||||
|
||||
webviewTests('chrome');
|
||||
describe("chrome", function () {
|
||||
require('../common/webview-base')('chrome');
|
||||
});
|
||||
|
||||
28
test/functional/common/setup-base.js
Normal file
28
test/functional/common/setup-base.js
Normal file
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
var env = require('../../helpers/env')
|
||||
, sessionUtils = require('../../helpers/session-utils')
|
||||
, wd = require('wd')
|
||||
// , domain = require('domain')
|
||||
, chai = require('chai')
|
||||
, chaiAsPromised = require('chai-as-promised');
|
||||
|
||||
chai.use(chaiAsPromised);
|
||||
chai.should();
|
||||
chaiAsPromised.transferPromiseness = wd.transferPromiseness;
|
||||
require("colors");
|
||||
|
||||
module.exports = function (context, desired, opts) {
|
||||
context.timeout(env.MOCHA_TIMEOUT);
|
||||
|
||||
var session = sessionUtils.initSession(desired, opts);
|
||||
|
||||
if (env.FAST_TESTS) {
|
||||
before(function (done) { session.setUp().nodeify(done); });
|
||||
after(function (done) { session.tearDown().nodeify(done); });
|
||||
} else {
|
||||
beforeEach(function (done) { session.setUp().nodeify(done); });
|
||||
beforeEach(function (done) { session.tearDown().nodeify(done); });
|
||||
}
|
||||
|
||||
return session.promisedBrowser;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
// todo: this was converted to promise chain api, but not tested.
|
||||
var describeWd = require('../../helpers/driverblock.js').describeForApp('Contacts', 'firefox')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base");
|
||||
|
||||
describeWd('firefoxos', function(h) {
|
||||
return it('should load app', function(done) {
|
||||
describe("firefoxos - contacts -", function () {
|
||||
var driver;
|
||||
setup(this, {app: 'Contacts'}).then(function (d) { driver = d; });
|
||||
|
||||
it('should load app', function (done) {
|
||||
var firstName = "Name";
|
||||
var lastName = Date.now().toString();
|
||||
h.driver
|
||||
driver
|
||||
.url().should.become("app://communications.gaiamobile.org/contacts/index.html")
|
||||
.elementById('add-contact-button').click()
|
||||
.elementById('givenName').sendKeys(firstName)
|
||||
|
||||
@@ -1,25 +1,30 @@
|
||||
/*global beforeEach:true */
|
||||
"use strict";
|
||||
|
||||
var path = require('path')
|
||||
, describeWd = null
|
||||
, appPkg = "io.appium.gappium.sampleapp"
|
||||
, appAct = ".HelloGappium"
|
||||
, appPath = path.resolve(__dirname, "../../../sample-code/apps/" + appPkg + "/platforms/ios/build/HelloGappium.app")
|
||||
, driverBlock = require("../../helpers/driverblock.js")
|
||||
, it = driverBlock.it;
|
||||
var env = require("../../helpers/env")
|
||||
, setup = require("../common/setup-base")
|
||||
, path = require('path');
|
||||
|
||||
// export env APPIUM_CORDOVA="android" to run tests against android version
|
||||
if (typeof process.env.APPIUM_CORDOVA !== "undefined" && process.env.APPIUM_CORDOVA === "android") {
|
||||
appPath = path.resolve(__dirname, "../../../sample-code/apps/" + appPkg + "/platforms/android/bin/HelloGappium-debug.apk");
|
||||
describeWd = driverBlock.describeForApp(appPath, "selendroid", appPkg, appAct);
|
||||
var desired;
|
||||
if (env.DEVICE === 'selendroid' || env.DEVICE === 'android') {
|
||||
var appPath = path.resolve(__dirname, '../../../sample-code/apps/io.appium.gappium.sampleapp/platforms/' +
|
||||
"android/bin/HelloGappium-debug.apk"),
|
||||
desired = {
|
||||
app: appPath,
|
||||
'app-package': 'io.appium.gappium.sampleapp',
|
||||
'app-activity': '.HelloGappium',
|
||||
};
|
||||
} else {
|
||||
describeWd = driverBlock.describeForApp(appPath, "ios", appPkg, appAct);
|
||||
var appPath = path.resolve(__dirname, '../../../sample-code/apps/io.appium.gappium.sampleapp/platforms/' +
|
||||
"ios/build" + (env.EMU ? '/emulator' : '') + "/HelloGappium.app"),
|
||||
desired = {
|
||||
app: appPath
|
||||
};
|
||||
}
|
||||
|
||||
var activateWebView = function(h) {
|
||||
var activateWebView = function (driver) {
|
||||
// unify (ios vs selendroid) web view selection
|
||||
return h.driver.windowHandles().then(function(handles) {
|
||||
return driver.windowHandles().then(function (handles) {
|
||||
for (var handle in handles) {
|
||||
var hdl = handles[handle];
|
||||
if (hdl.indexOf('WEBVIEW') > -1) {
|
||||
@@ -27,32 +32,37 @@ var activateWebView = function(h) {
|
||||
}
|
||||
}
|
||||
return handles[0];
|
||||
}).then(function(handle) {
|
||||
return h.driver.window(handle).catch(function() {});
|
||||
}).then(function (handle) {
|
||||
return driver.window(handle).catch(function () {});
|
||||
});
|
||||
};
|
||||
|
||||
describeWd('HelloGappium', function(h) {
|
||||
describe("gappium", function () {
|
||||
|
||||
beforeEach(function(done) {
|
||||
activateWebView(h).nodeify(done);
|
||||
});
|
||||
describe('HelloGappium', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should open the app and navigate through the dialogs', function(done) {
|
||||
h.driver
|
||||
.sleep(3000) // timeout to visualize test execution
|
||||
.elementByCssSelector('.search-key')
|
||||
.sendKeys('j')
|
||||
.elementsByCssSelector('.topcoat-list a')
|
||||
.then(function(employees) {
|
||||
employees.length.should.equal(5);
|
||||
return employees[3].click();
|
||||
}).elementsByCssSelector('.actions a')
|
||||
.then(function(options) {
|
||||
options.length.should.equal(6);
|
||||
options[3].click();
|
||||
}).sleep(2000)
|
||||
.nodeify(done); // timeout to visualize test execution
|
||||
beforeEach(function (done) {
|
||||
activateWebView(driver).nodeify(done);
|
||||
});
|
||||
|
||||
it('should open the app and navigate through the dialogs', function (done) {
|
||||
driver
|
||||
.sleep(3000) // timeout to visualize test execution
|
||||
.elementByCssSelector('.search-key')
|
||||
.sendKeys('j')
|
||||
.elementsByCssSelector('.topcoat-list a')
|
||||
.then(function (employees) {
|
||||
employees.length.should.equal(5);
|
||||
return employees[3].click();
|
||||
}).elementsByCssSelector('.actions a')
|
||||
.then(function (options) {
|
||||
options.length.should.equal(6);
|
||||
options[3].click();
|
||||
}).sleep(2000)
|
||||
.nodeify(done); // timeout to visualize test execution
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
var wvHelpers = require("../../helpers/webview.js")
|
||||
, webviewTests = wvHelpers.buildTests;
|
||||
|
||||
webviewTests('iwebview');
|
||||
describe('iwebview', function () {
|
||||
var app = 'iwebview';
|
||||
require('../common/webview-base')(app);
|
||||
});
|
||||
|
||||
@@ -1,51 +1,68 @@
|
||||
"use strict";
|
||||
|
||||
var chai = require('chai')
|
||||
, describeWd = require("../../helpers/driverblock.js").describeForSettings
|
||||
, env = {} // anticipate @sebv changes
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
|
||||
env.DEVICE = process.env.DEVICE || "IOS6"; // anticipate @sebv changes
|
||||
var env = require("../../helpers/env")
|
||||
, setup = require("../common/setup-base")
|
||||
, chai = require('chai')
|
||||
, _ = require('underscore');
|
||||
|
||||
chai.should();
|
||||
|
||||
describeWd('settings app', function(h) {
|
||||
it('should turn off autocomplete', function(done) {
|
||||
var ios7 = env.DEVICE.indexOf("7") !== -1;
|
||||
var clickGeneral = {strategy: "tag name", selector: "tableCell", index: ios7 ? 0 : 1};
|
||||
var clickKeyboard = {strategy: "tag name", selector: "tableCell", index: ios7 ? 3 : 1};
|
||||
var switchEl;
|
||||
h.driver
|
||||
.execute("mobile: findAndAct", [clickGeneral])
|
||||
.sleep(1000)
|
||||
.execute("mobile: findAndAct", [clickKeyboard])
|
||||
.elementByXPath('//switch[@name="Auto-Correction"]')
|
||||
.then(function(el) { switchEl = el; return el; })
|
||||
.getValue().then(function(checked) {
|
||||
if (checked === 1) return switchEl.click();
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
var checkLocServ = function(h, expected, cb) {
|
||||
h.driver
|
||||
.execute("mobile: findAndAct", [{strategy: "tag name", selector: "tableCell", index: 2}])
|
||||
.sleep(1000)
|
||||
.execute("mobile: findAndAct", [{strategy: "tag name", selector: "tableCell", index: 0}])
|
||||
.elementByTagName('switch')
|
||||
.getValue().then(function(checked) {
|
||||
checked.should.eql(expected);
|
||||
}).nodeify(cb);
|
||||
var desired = {
|
||||
app: 'settings'
|
||||
, device: 'iPhone Simulator'
|
||||
};
|
||||
|
||||
describeWd('settings app with location services', function(h) {
|
||||
it('should respond to positive locationServicesEnabled cap', function(done) {
|
||||
checkLocServ(h, 1, done);
|
||||
});
|
||||
}, null, null, {locationServicesEnabled: true});
|
||||
describe("prefs @skip-ios6", function () {
|
||||
|
||||
describeWd('settings app without location services', function(h) {
|
||||
it('should respond to negative locationServicesEnabled cap', function(done) {
|
||||
checkLocServ(h, 0, done);
|
||||
describe('settings app', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should turn off autocomplete', function (done) {
|
||||
var ios7 = env.DEVICE.indexOf("7") !== -1;
|
||||
var clickGeneral = {strategy: "tag name", selector: "tableCell", index: ios7 ? 0 : 1};
|
||||
var clickKeyboard = {strategy: "tag name", selector: "tableCell", index: ios7 ? 3 : 1};
|
||||
var switchEl;
|
||||
driver
|
||||
.execute("mobile: findAndAct", [clickGeneral])
|
||||
.sleep(1000)
|
||||
.execute("mobile: findAndAct", [clickKeyboard])
|
||||
.elementByXPath('//switch[@name="Auto-Correction"]')
|
||||
.then(function (el) { switchEl = el; return el; })
|
||||
.getValue().then(function (checked) {
|
||||
if (checked === 1) return switchEl.click();
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
}, null, null, {locationServicesEnabled: false});
|
||||
|
||||
var checkLocServ = function (driver, expected, cb) {
|
||||
driver
|
||||
.execute("mobile: findAndAct", [{strategy: "tag name", selector: "tableCell", index: 2}])
|
||||
.sleep(1000)
|
||||
.execute("mobile: findAndAct", [{strategy: "tag name", selector: "tableCell", index: 0}])
|
||||
.elementByTagName('switch')
|
||||
.getValue().then(function (checked) {
|
||||
checked.should.eql(expected);
|
||||
}).nodeify(cb);
|
||||
};
|
||||
|
||||
describe('settings app with location services', function () {
|
||||
var driver;
|
||||
setup(this, _.defaults({locationServicesEnabled: true}, desired))
|
||||
.then(function (d) { driver = d; });
|
||||
|
||||
it('should respond to positive locationServicesEnabled cap', function (done) {
|
||||
checkLocServ(driver, 1, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('settings app without location services', function () {
|
||||
var driver;
|
||||
setup(this, _.defaults({locationServicesEnabled: false}, desired))
|
||||
.then(function (d) { driver = d; });
|
||||
|
||||
it('should respond to negative locationServicesEnabled cap', function (done) {
|
||||
checkLocServ(driver, 0, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var desc = require("../../helpers/driverblock.js").describeForSafari()
|
||||
, it = require("../../helpers/driverblock.js").it
|
||||
, wvHelpers = require("../../helpers/webview.js")
|
||||
, webviewTests = wvHelpers.buildTests
|
||||
, loadWebView = wvHelpers.loadWebView
|
||||
, spinTitle = wvHelpers.spinTitle
|
||||
, _ = require('underscore');
|
||||
|
||||
|
||||
var devices = ["iPad", "iPhone"];
|
||||
_.each(devices, function(sim) {
|
||||
|
||||
desc('windows and frames (' + sim + ')', function(h) {
|
||||
|
||||
it('getting current window should work initially', function(done) {
|
||||
h.driver
|
||||
.windowHandle().then(function(handleId) {
|
||||
parseInt(handleId, 10).should.be.above(0);
|
||||
}).nodeify(done);
|
||||
});
|
||||
describe('within webview', function() {
|
||||
beforeEach(function(done) {
|
||||
loadWebView("safari",h.driver).nodeify(done);
|
||||
});
|
||||
it("should throw nosuchwindow if there's not one", function(done) {
|
||||
h.driver
|
||||
.window('noexistman')
|
||||
.should.be.rejectedWith(/status: 23/)
|
||||
.nodeify(done);
|
||||
});
|
||||
it("should be able to open and close windows", function(done) {
|
||||
h.driver
|
||||
.elementById('blanklink').click()
|
||||
.then(function() { return spinTitle("I am another page title", h.driver); })
|
||||
.windowHandles()
|
||||
.then(function(handles) {
|
||||
return h.driver
|
||||
.sleep(2000).close().sleep(3000)
|
||||
.windowHandles()
|
||||
.should.eventually.be.below(handles.length);
|
||||
}).then(function() { return spinTitle("I am a page title", h.driver); })
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to go back and forward', function(done) {
|
||||
h.driver
|
||||
.elementByLinkText('i am a link')
|
||||
.click()
|
||||
.elementById('only_on_page_2')
|
||||
.back()
|
||||
.elementById('i_am_a_textbox')
|
||||
.forward()
|
||||
.elementById('only_on_page_2')
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
}, null, null, {device: sim + " Simulator"});
|
||||
});
|
||||
|
||||
webviewTests('safari');
|
||||
@@ -1,43 +1,47 @@
|
||||
"use strict";
|
||||
|
||||
var desc = require("../../helpers/driverblock.js").describeForSafari()
|
||||
, it = require("../../helpers/driverblock.js").it
|
||||
, _ = require("underscore")
|
||||
var env = require('../../helpers/env')
|
||||
, setup = require("../common/setup-base")
|
||||
, fs = require('fs');
|
||||
|
||||
_.each(["iPhone", "iPad"], function(device) {
|
||||
desc('screenshots (' + device + ')', function(h) {
|
||||
it('should get a local screenshot', function(done) {
|
||||
describe("safari - screenshot -", function () {
|
||||
|
||||
describe('screenshots (' + env.DEVICE + ')', function () {
|
||||
var driver;
|
||||
setup(this, {app: 'safari'}).then(function (d) { driver = d; });
|
||||
|
||||
it('should get a local screenshot', function (done) {
|
||||
var localScreenshotFile = '/tmp/test_screenshot_appium.png';
|
||||
if (fs.existsSync(localScreenshotFile)) {
|
||||
fs.unlinkSync(localScreenshotFile);
|
||||
}
|
||||
h.driver
|
||||
driver
|
||||
.execute("mobile: localScreenshot", [{file: localScreenshotFile}])
|
||||
.then(function() {
|
||||
.then(function () {
|
||||
var screenshot = fs.readFileSync(localScreenshotFile);
|
||||
screenshot.should.exist;
|
||||
screenshot.length.should.be.above(1000);
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should get an app screenshot', function(done) {
|
||||
h.driver
|
||||
it('should get an app screenshot', function (done) {
|
||||
driver
|
||||
.takeScreenshot()
|
||||
.should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should get an app screenshot in landscape mode', function(done) {
|
||||
h.driver.takeScreenshot().then(function(screenshot1) {
|
||||
it('should get an app screenshot in landscape mode', function (done) {
|
||||
driver.takeScreenshot().then(function (screenshot1) {
|
||||
screenshot1.should.exist;
|
||||
return h.driver
|
||||
return driver
|
||||
.setOrientation("LANDSCAPE")
|
||||
// A useless error does often exist here, let's ignore it
|
||||
.catch(function() {})
|
||||
.takeScreenshot().then(function(screenshot2) {
|
||||
.catch(function () {})
|
||||
.takeScreenshot().then(function (screenshot2) {
|
||||
screenshot2.should.exist;
|
||||
screenshot2.should.not.eql(screenshot1);
|
||||
});
|
||||
}).nodeify(done);
|
||||
}).sleep(3000) // cooldown
|
||||
.nodeify(done);
|
||||
});
|
||||
}, null, null, {device: device + ' Simulator'});
|
||||
});
|
||||
});
|
||||
|
||||
5
test/functional/safari/webview.js
Normal file
5
test/functional/safari/webview.js
Normal file
@@ -0,0 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
describe('safari - webview -', function () {
|
||||
require('../common/webview-base')('safari');
|
||||
});
|
||||
55
test/functional/safari/windows-frame.js
Normal file
55
test/functional/safari/windows-frame.js
Normal file
@@ -0,0 +1,55 @@
|
||||
"use strict";
|
||||
var env = require('../../helpers/env')
|
||||
, setup = require("../common/setup-base")
|
||||
, loadWebView = require("../../helpers/webview-utils").loadWebView
|
||||
, spinTitle = require("../../helpers/webview-utils").spinTitle;
|
||||
|
||||
describe("safari - windows-frame -", function () {
|
||||
|
||||
describe('windows and frames (' + env.DEVICE + ')', function () {
|
||||
var driver;
|
||||
setup(this, {app: 'safari'}).then(function (d) { driver = d; });
|
||||
|
||||
it('getting current window should work initially', function (done) {
|
||||
driver
|
||||
.windowHandle().then(function (handleId) {
|
||||
parseInt(handleId, 10).should.be.above(0);
|
||||
}).nodeify(done);
|
||||
});
|
||||
describe('within webview', function () {
|
||||
beforeEach(function (done) {
|
||||
loadWebView("safari", driver).nodeify(done);
|
||||
});
|
||||
it("should throw nosuchwindow if there's not one", function (done) {
|
||||
driver
|
||||
.window('noexistman')
|
||||
.should.be.rejectedWith(/status: 23/)
|
||||
.nodeify(done);
|
||||
});
|
||||
it("should be able to open and close windows", function (done) {
|
||||
driver
|
||||
.elementById('blanklink').click()
|
||||
.then(function () { return spinTitle("I am another page title", driver); })
|
||||
.windowHandles()
|
||||
.then(function (handles) {
|
||||
return driver
|
||||
.sleep(2000).close().sleep(3000)
|
||||
.windowHandles()
|
||||
.should.eventually.be.below(handles.length);
|
||||
}).then(function () { return spinTitle("I am a page title", driver); })
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to go back and forward', function (done) {
|
||||
driver
|
||||
.elementByLinkText('i am a link')
|
||||
.click()
|
||||
.elementById('only_on_page_2')
|
||||
.back()
|
||||
.elementById('i_am_a_textbox')
|
||||
.forward()
|
||||
.elementById('only_on_page_2')
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,125 +1,164 @@
|
||||
"use strict";
|
||||
|
||||
var path = require('path')
|
||||
, appPath = path.resolve(__dirname, "../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk")
|
||||
, appPkg = "com.example.android.apis"
|
||||
, appAct = ".ApiDemos"
|
||||
, appAct2 = "ApiDemos"
|
||||
, appActFull = "com.example.android.apis.ApiDemos"
|
||||
, driverBlock = require("../../helpers/driverblock.js")
|
||||
, Q = driverBlock.Q
|
||||
, describeWd = driverBlock.describeForApp(appPath, "selendroid", appPkg, appAct)
|
||||
, describeWd2 = driverBlock.describeForApp(appPath, "selendroid", appPkg, appAct2)
|
||||
, describeWdFull = driverBlock.describeForApp(appPath, "selendroid", appPkg, appActFull)
|
||||
, it = driverBlock.it;
|
||||
var setup = require("../common/setup-base")
|
||||
, sessionUtils = require('../../helpers/session-utils')
|
||||
, path = require('path')
|
||||
, Q = require("q")
|
||||
, _ = require('underscore');
|
||||
|
||||
// if it doesn't work run: adb uninstall com.example.android.apis
|
||||
var desired = {
|
||||
app: path.resolve(__dirname, "../../../sample-code/apps/ApiDemos/bin/ApiDemos-debug.apk"),
|
||||
'app-package': 'com.example.android.apis',
|
||||
'app-activity': '.ApiDemos'
|
||||
};
|
||||
|
||||
// , appAct2 = "ApiDemos"
|
||||
// , appActFull = "com.example.android.apis.ApiDemos"
|
||||
|
||||
describe('selendroid - basic -', function () {
|
||||
|
||||
describe('api', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
// todo: issue with find
|
||||
it('should find and click an element @skip-all-selendroid', function (done) {
|
||||
// selendroid appears to have some issues with implicit waits
|
||||
// hence the timeouts
|
||||
driver
|
||||
.waitForElementByName('App', 10000).click()
|
||||
.sleep(1000)
|
||||
.elementByLinkText("Action Bar").should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should be able to get logcat log type', function (done) {
|
||||
driver.logTypes().should.eventually.include('logcat')
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to get logcat logs', function (done) {
|
||||
driver.log('logcat').then(function (logs) {
|
||||
logs.length.should.be.above(0);
|
||||
logs[0].message.should.not.include("\n");
|
||||
logs[0].level.should.equal("ALL");
|
||||
logs[0].timestamp.should.exist;
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it('should be able to proxy errors', function (done) {
|
||||
driver
|
||||
.frame(null).should.be.rejected
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should be able to set location', function (done) {
|
||||
var locOpts = {latitude: "27.17", longitude: "78.04"};
|
||||
driver
|
||||
.execute("mobile: setLocation", [locOpts])
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should error out nicely with incompatible commands', function (done) {
|
||||
driver
|
||||
.execute("mobile: flick", [{}])
|
||||
.catch(function (err) {
|
||||
err.cause.value.origValue.should.contain('mobile:');
|
||||
throw err;
|
||||
}).should.be.rejectedWith(/status: 9/)
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
describeWd('basic', function(h) {
|
||||
it('should find and click an element', function(done) {
|
||||
// selendroid appears to have some issues with implicit waits
|
||||
// hence the timeouts
|
||||
h.driver
|
||||
.sleep(1000)
|
||||
.elementByName('App').click()
|
||||
.sleep(1000)
|
||||
.elementByLinkText("Action Bar").should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should be able to get logcat log type', function(done) {
|
||||
h.driver.logTypes().should.eventually.include('logcat')
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to get logcat logs', function(done) {
|
||||
h.driver.log('logcat').then(function(logs) {
|
||||
logs.length.should.be.above(0);
|
||||
logs[0].message.should.not.include("\n");
|
||||
logs[0].level.should.equal("ALL");
|
||||
logs[0].timestamp.should.exist;
|
||||
}).nodeify(done);
|
||||
describe('uninstall app', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should be able to uninstall the app', function (done) {
|
||||
driver
|
||||
.execute("mobile: removeApp", [{bundleId: desired['app-package']}])
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to proxy errors', function(done) {
|
||||
h.driver
|
||||
.frame(null).should.be.rejected
|
||||
.nodeify(done);
|
||||
describe('background app', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it("should background the app", function (done) {
|
||||
var before = new Date().getTime() / 1000;
|
||||
driver
|
||||
.execute("mobile: background", [{seconds: 3}])
|
||||
.then(function () {
|
||||
((new Date().getTime() / 1000) - before).should.be.above(2);
|
||||
// this should not be tested
|
||||
// ((new Date().getTime() / 1000) - before).should.be.below(5);
|
||||
})
|
||||
.execute("mobile: currentActivity")
|
||||
.should.eventually.include("ApiDemos")
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to set location', function(done) {
|
||||
var locOpts = {latitude: "27.17", longitude: "78.04"};
|
||||
h.driver
|
||||
.execute("mobile: setLocation", [locOpts])
|
||||
.nodeify(done);
|
||||
describe('command timeouts', function () {
|
||||
var driver;
|
||||
setup(this, _.defaults({newCommandTimeout: 3}, desired))
|
||||
.then(function (d) { driver = d; });
|
||||
|
||||
it('should die with short timeout', function (done) {
|
||||
driver
|
||||
.sleep(5000)
|
||||
.elementByName('Animation')
|
||||
.should.be.rejectedWith(/(status: (13|6))|(Not JSON response)/)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should error out nicely with incompatible commands', function(done) {
|
||||
h.driver
|
||||
.execute("mobile: flick", [{}])
|
||||
.catch(function(err) {
|
||||
err.cause.value.origValue.should.contain('mobile:'); throw err;
|
||||
}).should.be.rejectedWith(/status: 9/)
|
||||
.nodeify(done);
|
||||
|
||||
// todo: issue with find
|
||||
describe('command timeouts @skip-all-selendroid', function () {
|
||||
var driver;
|
||||
setup(this, _.defaults({newCommandTimeout: 7}, desired))
|
||||
.then(function (d) { driver = d; });
|
||||
|
||||
it('should not die if commands come in', function (done) {
|
||||
var start = Date.now();
|
||||
var find = function () {
|
||||
if ((Date.now() - start) < 5000) {
|
||||
return driver
|
||||
.elementByName('Animation').should.eventually.exist
|
||||
.sleep(500)
|
||||
.then(find);
|
||||
} else return new Q();
|
||||
};
|
||||
find().then(function () {
|
||||
return driver
|
||||
.sleep(10000)
|
||||
.elementByName('Animation').should.be.rejected;
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to uninstall the app', function(done) {
|
||||
h.driver
|
||||
.execute("mobile: removeApp", [{bundleId: appPkg}])
|
||||
.nodeify(done);
|
||||
describe('app activities with no dot', function () {
|
||||
var session;
|
||||
after(function () { session.tearDown(); });
|
||||
|
||||
it('should not launch app', function (done) {
|
||||
session = sessionUtils.initSession(_.defaults({'app-activity': 'ApiDemos'}, desired), {'no-retry': true});
|
||||
session.setUp()
|
||||
.should.be.rejected
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
it("should background the app", function(done) {
|
||||
var before = new Date().getTime() / 1000;
|
||||
h.driver
|
||||
.execute("mobile: background", [{seconds: 3}])
|
||||
.then(function() {
|
||||
((new Date().getTime() / 1000) - before).should.be.above(2);
|
||||
((new Date().getTime() / 1000) - before).should.be.below(5);
|
||||
})
|
||||
.execute("mobile: currentActivity")
|
||||
.should.eventually.include("ApiDemos")
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describeWd('command timeouts', function(h) {
|
||||
it('should die with short timeout', function(done) {
|
||||
h.driver
|
||||
.sleep(5000)
|
||||
.elementByName('Animation')
|
||||
.should.be.rejectedWith(/(status: (13|6))|(Not JSON response)/)
|
||||
.nodeify(done);
|
||||
});
|
||||
}, null, null, {newCommandTimeout: 3});
|
||||
|
||||
describeWd('command timeouts', function(h) {
|
||||
it('should not die if commands come in', function(done) {
|
||||
var start = Date.now();
|
||||
var find = function() {
|
||||
if ((Date.now() - start) < 5000) {
|
||||
return h.driver
|
||||
.elementByName('Animation').should.eventually.exist
|
||||
.sleep(500)
|
||||
.then(find);
|
||||
} else return new Q();
|
||||
};
|
||||
find().then(function() {
|
||||
return h.driver
|
||||
.sleep(10000)
|
||||
.elementByName('Animation').should.be.rejected;
|
||||
}).nodeify(done);
|
||||
});
|
||||
}, null, null, {newCommandTimeout: 7});
|
||||
|
||||
describeWd2('app activities with no dot', function(h) {
|
||||
it('should not launch app', function(done) {
|
||||
h.connError.should.exist;
|
||||
done();
|
||||
});
|
||||
}, null, null, {expectConnError: true});
|
||||
|
||||
describeWdFull('fully qualified app activities', function() {
|
||||
it('should still launch app', function(done) {
|
||||
done();
|
||||
|
||||
describe('fully qualified app activities', function () {
|
||||
var session;
|
||||
after(function () { session.tearDown(); });
|
||||
|
||||
it('should still launch app', function (done) {
|
||||
session = sessionUtils.initSession(_.defaults({'app-activity': 'com.example.android.apis.ApiDemos'}, desired));
|
||||
session.setUp()
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,42 +1,46 @@
|
||||
/*global beforeEach:true */
|
||||
"use strict";
|
||||
|
||||
var path = require('path')
|
||||
, appPath = path.resolve(__dirname, "../../../sample-code/apps/WebViewDemo/target/selendroid-test-app-0.7.0.apk")
|
||||
, appPkg = "io.selendroid.testapp"
|
||||
, appAct = ".HomeScreenActivity"
|
||||
, driverBlock = require("../../helpers/driverblock.js")
|
||||
, it = driverBlock.it
|
||||
, describeWd = driverBlock.describeForApp(appPath, "selendroid", appPkg, appAct)
|
||||
, exec = require('child_process').exec;
|
||||
var env = require('../../helpers/env')
|
||||
, setup = require("../common/setup-base")
|
||||
, path = require('path');
|
||||
|
||||
var desired = {
|
||||
app: path.resolve(__dirname, "../../../sample-code/apps/WebViewDemo/target/selendroid-test-app-0.7.0.apk"),
|
||||
'app-package': 'io.selendroid.testapp',
|
||||
'app-activity': '.HomeScreenActivity'
|
||||
};
|
||||
|
||||
// if it doesn't work run: adb uninstall io.selendroid.testapp
|
||||
|
||||
describeWd('web view', function(h) {
|
||||
beforeEach(function(done) {
|
||||
h.driver
|
||||
describe('selendroid - web_view -', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
beforeEach(function (done) {
|
||||
driver
|
||||
.waitForElementById('buttonStartWebView').click()
|
||||
.window('WEBVIEW')
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
if (process.env.FAST_TESTS) {
|
||||
afterEach(function(done) {
|
||||
h.driver
|
||||
if (env.FAST_TESTS) {
|
||||
afterEach(function (done) {
|
||||
driver
|
||||
.window('NATIVE_APP')
|
||||
.elementByIdOrNull('goBack').then(function(el) {
|
||||
.elementByIdOrNull('goBack').then(function (el) {
|
||||
if (el) return el.click().sleep(1000);
|
||||
}).nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should be web view', function(done) {
|
||||
it('should be web view', function (done) {
|
||||
// todo: add some sort of check here
|
||||
done();
|
||||
});
|
||||
|
||||
it('should find and click an element', function(done) {
|
||||
h.driver
|
||||
it('should find and click an element', function (done) {
|
||||
driver
|
||||
.elementByCssSelector('input[type=submit]').click()
|
||||
.sleep(1000)
|
||||
.elementByTagName('h1').text()
|
||||
@@ -44,25 +48,25 @@ describeWd('web view', function(h) {
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should clear input', function(done) {
|
||||
h.driver
|
||||
it('should clear input', function (done) {
|
||||
driver
|
||||
.elementById('name_input').clear().getValue().should.become("")
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should find and enter key sequence in input', function(done) {
|
||||
h.driver
|
||||
it('should find and enter key sequence in input', function (done) {
|
||||
driver
|
||||
.elementById('name_input').clear()
|
||||
.type("Mathieu").getValue().should.become("Mathieu")
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should be able to handle selendroid special keys', function(done) {
|
||||
h.driver.keys('\uE102').nodeify(done);
|
||||
it('should be able to handle selendroid special keys', function (done) {
|
||||
driver.keys('\uE102').nodeify(done);
|
||||
});
|
||||
|
||||
it('should get web source', function(done) {
|
||||
h.driver
|
||||
it('should get web source', function (done) {
|
||||
driver
|
||||
.source().should.eventually.include("body")
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require('../../helpers/driverblock.js').describeForApp('TestApp')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base"),
|
||||
desired = require('./desired');
|
||||
|
||||
describeWd('active', function(h) {
|
||||
it('should return active element', function(done) {
|
||||
h.driver
|
||||
.elementsByTagName('textField').then(function(elems) {
|
||||
describe('testapp - active -', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should return active element', function (done) {
|
||||
driver
|
||||
.elementsByTagName('textField').then(function (elems) {
|
||||
return elems[1];
|
||||
}).then(function(elem) {
|
||||
return h.driver
|
||||
}).then(function (elem) {
|
||||
return driver
|
||||
.active().equals(elem).should.be.ok;
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
@@ -2,230 +2,238 @@
|
||||
// https://github.com/hugs/appium/blob/master/sample-code/webdriver-test.py
|
||||
"use strict";
|
||||
|
||||
var driverBlock = require("../../helpers/driverblock.js")
|
||||
, Q = driverBlock.Q
|
||||
, describeWd = driverBlock.describeForApp('TestApp')
|
||||
, it = require("../../helpers/driverblock.js").it
|
||||
var env = require('../../helpers/env')
|
||||
, setup = require("../common/setup-base")
|
||||
, desired = require('./desired')
|
||||
, Q = require("q")
|
||||
, fs = require('fs')
|
||||
, path = require('path')
|
||||
, _ = require("underscore");
|
||||
|
||||
describeWd('calc app', function(h) {
|
||||
describe('testapp - basic -', function () {
|
||||
|
||||
var values = null;
|
||||
describe('using calc app', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
var clearFields = function(driver) {
|
||||
values = [];
|
||||
return driver
|
||||
.elementsByTagName('textField').then(function(elems) {
|
||||
var sequence = _(elems).map(function(elem) {
|
||||
return function() { return elem.clear(); };
|
||||
var values = null;
|
||||
|
||||
var clearFields = function (driver) {
|
||||
values = [];
|
||||
return driver
|
||||
.elementsByTagName('textField').then(function (elems) {
|
||||
var sequence = _(elems).map(function (elem) {
|
||||
return function () { return elem.clear(); };
|
||||
});
|
||||
return sequence.reduce(Q.when, new Q()); // running sequence
|
||||
}).then(function () {
|
||||
return driver.elementByTagName('button').click();
|
||||
});
|
||||
return sequence.reduce(Q.when, new Q()); // running sequence
|
||||
}).then(function() {
|
||||
return driver.elementByTagName('button').click();
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var populate = function(type, driver) {
|
||||
values = [];
|
||||
return driver
|
||||
.elementsByTagName('textField').then(function(elems) {
|
||||
var sequence = _(elems).map(function(elem) {
|
||||
var val = Math.round(Math.random()*10);
|
||||
values.push(val);
|
||||
if (type === "elem") {
|
||||
return function() { return elem.sendKeys(val); };
|
||||
} else if (type === "elem-setvalue") {
|
||||
return function() {
|
||||
return driver.execute( "mobile: setValue",
|
||||
[{element: elem.value, value: val}]);
|
||||
};
|
||||
} else if (type === "driver") {
|
||||
return function() { return elem.click().keys(val); };
|
||||
}
|
||||
var populate = function (type, driver) {
|
||||
values = [];
|
||||
return driver
|
||||
.elementsByTagName('textField').then(function (elems) {
|
||||
var sequence = _(elems).map(function (elem) {
|
||||
var val = Math.round(Math.random() * 10);
|
||||
values.push(val);
|
||||
if (type === "elem") {
|
||||
return function () { return elem.sendKeys(val); };
|
||||
} else if (type === "elem-setvalue") {
|
||||
return function () {
|
||||
return driver.execute("mobile: setValue",
|
||||
[{element: elem.value, value: val}]);
|
||||
};
|
||||
} else if (type === "driver") {
|
||||
return function () { return elem.click().keys(val); };
|
||||
}
|
||||
});
|
||||
return sequence.reduce(Q.when, new Q()); // running sequence
|
||||
});
|
||||
return sequence.reduce(Q.when, new Q()); // running sequence
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
var computeAndCheck = function(driver) {
|
||||
return driver
|
||||
.elementByTagName('button').click()
|
||||
.elementByTagName('staticText').text().then(function(text) {
|
||||
parseInt(text, 10).should.equal(values[0] + values[1]);
|
||||
});
|
||||
};
|
||||
var computeAndCheck = function (driver) {
|
||||
return driver
|
||||
.elementByTagName('button').click()
|
||||
.elementByTagName('staticText').text().then(function (text) {
|
||||
parseInt(text, 10).should.equal(values[0] + values[1]);
|
||||
});
|
||||
};
|
||||
|
||||
if (process.env.FAST_TESTS) {
|
||||
beforeEach(function(done) {
|
||||
clearFields(h.driver).nodeify(done);
|
||||
if (env.FAST_TESTS) {
|
||||
beforeEach(function (done) {
|
||||
clearFields(driver).nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should fill two fields with numbers', function (done) {
|
||||
populate("elem", driver)
|
||||
.then(computeAndCheck.bind(null, driver))
|
||||
.nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should fill two fields with numbers', function(done) {
|
||||
populate("elem", h.driver)
|
||||
.then(computeAndCheck.bind(null, h.driver))
|
||||
// using sendKeysToActiveElement
|
||||
it('should fill two fields with numbers - sendKeys', function (done) {
|
||||
populate("driver", driver)
|
||||
.then(computeAndCheck.bind(null, driver))
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should fill two fields with numbers - setValue', function (done) {
|
||||
populate("elem-setvalue", driver)
|
||||
.then(computeAndCheck.bind(null, driver))
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should confirm that button is displayed', function (done) {
|
||||
driver
|
||||
.elementByTagName('textField').isDisplayed()
|
||||
.should.eventually.be.ok
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should confirm that the disabled button is disabled', function (done) {
|
||||
driver
|
||||
.elementByName('DisabledButton').isEnabled()
|
||||
.should.not.eventually.be.ok
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should confirm that the compute sum button is enabled', function (done) {
|
||||
driver
|
||||
.elementByName('ComputeSumButton').isEnabled()
|
||||
.should.eventually.be.ok
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should return app source', function (done) {
|
||||
driver.source().then(function (source) {
|
||||
var obj = JSON.parse(source);
|
||||
obj.type.should.equal("UIAApplication");
|
||||
obj.children[0].type.should.equal("UIAWindow");
|
||||
obj.children[0].children[0].label.should.equal("TextField1");
|
||||
["SumLabel", "0"].should.include(obj.children[0].children[3].name);
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it('should interact with alert', function (done) {
|
||||
driver.elementsByTagName('button').then(function (buttons) {
|
||||
return buttons[1];
|
||||
}).then(function (button) {
|
||||
return button
|
||||
.click()
|
||||
.acceptAlert()
|
||||
.then(function () { return button.click(); })
|
||||
.alertText().then(function (text) {
|
||||
text.should.include("Cool title");
|
||||
text.should.include("this alert is so cool.");
|
||||
}).dismissAlert();
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
// using sendKeysToActiveElement
|
||||
it('should fill two fields with numbers - sendKeys', function(done) {
|
||||
populate("driver", h.driver)
|
||||
.then(computeAndCheck.bind(null, h.driver))
|
||||
|
||||
it('should find alert like other elements', function (done) {
|
||||
driver.elementsByTagName('button').then(function (buttons) {
|
||||
return buttons[1];
|
||||
}).then(function (button) {
|
||||
return button.click()
|
||||
.elementByTagName('alert')
|
||||
// maybe we could get alert body text too?
|
||||
.elementByTagName('>', 'text').text().should.become("Cool title")
|
||||
.dismissAlert();
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should fill two fields with numbers - setValue', function(done) {
|
||||
populate("elem-setvalue", h.driver)
|
||||
.then(computeAndCheck.bind(null, h.driver))
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should get tag names of elements', function (done) {
|
||||
driver
|
||||
.elementByTagName('button').getTagName().should.become("UIAButton")
|
||||
.elementByTagName('text').getTagName().should.become("UIAStaticText")
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should confirm that button is displayed', function(done) {
|
||||
h.driver
|
||||
.elementByTagName('textField').isDisplayed()
|
||||
.should.eventually.be.ok
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to get text of a button', function (done) {
|
||||
driver
|
||||
.elementByTagName('button').text().should.become("ComputeSumButton")
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should confirm that the disabled button is disabled', function(done) {
|
||||
h.driver
|
||||
.elementByName('DisabledButton').isEnabled()
|
||||
.should.not.eventually.be.ok
|
||||
.nodeify(done);
|
||||
});
|
||||
}); // end describe
|
||||
|
||||
it('should confirm that the compute sum button is enabled', function(done) {
|
||||
h.driver
|
||||
.elementByName('ComputeSumButton').isEnabled()
|
||||
.should.eventually.be.ok
|
||||
.nodeify(done);
|
||||
});
|
||||
describe('using calc app', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should return app source', function(done) {
|
||||
h.driver.source().then(function(source) {
|
||||
var obj = JSON.parse(source);
|
||||
obj.type.should.equal("UIAApplication");
|
||||
obj.children[0].type.should.equal("UIAWindow");
|
||||
obj.children[0].children[0].label.should.equal("TextField1");
|
||||
obj.children[0].children[3].name.should.equal("SumLabel");
|
||||
}).nodeify(done);
|
||||
});
|
||||
var sum = 0
|
||||
, lookup = function (textFieldNum) {
|
||||
var num = Math.round(Math.random() * 10000);
|
||||
sum += num;
|
||||
return driver
|
||||
.elementByName('TextField' + textFieldNum)
|
||||
.sendKeys(num);
|
||||
};
|
||||
|
||||
it('should interact with alert', function(done) {
|
||||
h.driver.elementsByTagName('button').then(function(buttons) {
|
||||
return buttons[1];
|
||||
}).then(function(button) {
|
||||
return button
|
||||
.click()
|
||||
.acceptAlert()
|
||||
.then(function() { return button.click(); })
|
||||
.alertText().then(function(text) {
|
||||
text.should.include("Cool title");
|
||||
text.should.include("this alert is so cool.");
|
||||
}).dismissAlert();
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should lookup two fields by name and populate them with ' +
|
||||
'random numbers to finally sum them up', function (done) {
|
||||
driver.elementByName('SumLabel').then(function (sumLabel) {
|
||||
return driver.chain()
|
||||
.then(lookup.bind(null, 1))
|
||||
.then(lookup.bind(null, 2))
|
||||
.elementByName('ComputeSumButton').click()
|
||||
.then(function () { return sumLabel.text(); })
|
||||
.then(function (text) { parseInt(text, 10).should.equal(sum); });
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it('should receive correct error', function (done) {
|
||||
driver
|
||||
.execute("mobile: doesn't exist")
|
||||
.then(function () {}, function (err) {
|
||||
err.cause.value.message.should.equal("Not yet implemented. " +
|
||||
"Please help us: http://appium.io/get-involved.html");
|
||||
throw err;
|
||||
}).should.be.rejectedWith(/status: 13/)
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should find alert like other elements', function(done) {
|
||||
h.driver.elementsByTagName('button').then(function(buttons) {
|
||||
return buttons[1];
|
||||
}).then(function(button) {
|
||||
return button.click()
|
||||
.elementByTagName('alert')
|
||||
// maybe we could get alert body text too?
|
||||
.elementByTagName('>','text').text().should.become("Cool title")
|
||||
.dismissAlert();
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should be able to get syslog log type', function (done) {
|
||||
driver.logTypes().then(function (logTypes) {
|
||||
logTypes.should.include('syslog');
|
||||
logTypes.should.include('crashlog');
|
||||
logTypes.should.not.include('logcat');
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it('should get tag names of elements', function(done) {
|
||||
h.driver
|
||||
.elementByTagName('button').getTagName().should.become("UIAButton")
|
||||
.elementByTagName('text').getTagName().should.become("UIAStaticText")
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should be able to get text of a button', function(done) {
|
||||
h.driver
|
||||
.elementByTagName('button').text().should.become("ComputeSumButton")
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
}); // end describe
|
||||
|
||||
describeWd('calc app', function(h) {
|
||||
var sum = 0
|
||||
, lookup = function(textFieldNum) {
|
||||
var num = Math.round(Math.random()*10000);
|
||||
sum += num;
|
||||
return h.driver
|
||||
.elementByName('TextField' + textFieldNum)
|
||||
.sendKeys(num);
|
||||
};
|
||||
|
||||
it('should lookup two fields by name and populate them with ' +
|
||||
'random numbers to finally sum them up', function(done) {
|
||||
h.driver.elementByName('SumLabel').then(function(sumLabel) {
|
||||
return h.driver.chain()
|
||||
.then(lookup.bind(null, 1))
|
||||
.then(lookup.bind(null, 2))
|
||||
.elementByName('ComputeSumButton').click()
|
||||
.then(function() { return sumLabel.text(); })
|
||||
.then(function(text) { parseInt(text, 10).should.equal(sum); });
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it('should receive correct error', function(done) {
|
||||
h.driver
|
||||
.execute("mobile: doesn't exist")
|
||||
.then(function() {}, function(err) {
|
||||
err.cause.value.message.should.equal( "Not yet implemented. " +
|
||||
"Please help us: http://appium.io/get-involved.html");
|
||||
throw err;
|
||||
}).should.be.rejectedWith(/status: 13/)
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should be able to get syslog log type', function(done) {
|
||||
h.driver.logTypes().then(function(logTypes) {
|
||||
logTypes.should.include('syslog');
|
||||
logTypes.should.include('crashlog');
|
||||
logTypes.should.not.include('logcat');
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it('should be able to get syslog logs', function(done) {
|
||||
h.driver
|
||||
.setImplicitWaitTimeout(4000)
|
||||
.elementByName('SumLabelz')
|
||||
.should.be.rejectedWith(/status: 7/)
|
||||
.log('syslog').then(function(logs) {
|
||||
it('should be able to get syslog logs', function (done) {
|
||||
driver
|
||||
.setImplicitWaitTimeout(4000)
|
||||
.elementByName('SumLabelz')
|
||||
.should.be.rejectedWith(/status: 7/)
|
||||
.log('syslog').then(function (logs) {
|
||||
logs.length.should.be.above(0);
|
||||
logs[0].message.should.not.include("\n");
|
||||
logs[0].level.should.equal("ALL");
|
||||
logs[0].timestamp.should.exist;
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should be able to get crashlog logs', function(done) {
|
||||
var dir = path.resolve(process.env.HOME, "Library", "Logs", "DiagnosticReports");
|
||||
var msg = 'boom';
|
||||
h.driver
|
||||
.log('crashlog').then(function(logsBefore) {
|
||||
logsBefore.length.should.eql(0);
|
||||
fs.writeFileSync(dir + '/myApp_'+ Date.parse(new Date()) + '_rocksauce.crash', msg);
|
||||
}).log('crashlog').then(function(logsAfter) {
|
||||
logsAfter.length.should.be.above(0);
|
||||
logsAfter[0].message.should.not.include("\n");
|
||||
logsAfter[0].message.should.equal(msg);
|
||||
logsAfter[0].level.should.equal("ALL");
|
||||
logsAfter[0].timestamp.should.exist;
|
||||
}).nodeify(done);
|
||||
it('should be able to get crashlog logs', function (done) {
|
||||
var dir = path.resolve(process.env.HOME, "Library", "Logs", "DiagnosticReports");
|
||||
var msg = 'boom';
|
||||
driver
|
||||
.log('crashlog').then(function (logsBefore) {
|
||||
logsBefore.length.should.eql(0);
|
||||
fs.writeFileSync(dir + '/myApp_' + Date.parse(new Date()) + '_rocksauce.crash', msg);
|
||||
}).log('crashlog').then(function (logsAfter) {
|
||||
logsAfter.length.should.be.above(0);
|
||||
logsAfter[0].message.should.not.include("\n");
|
||||
logsAfter[0].message.should.equal(msg);
|
||||
logsAfter[0].level.should.equal("ALL");
|
||||
logsAfter[0].timestamp.should.exist;
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,22 +1,31 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require('../../helpers/driverblock.js').describeForApp('TestApp')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var env = require('../../helpers/env'),
|
||||
setup = require("../common/setup-base"),
|
||||
desired = require('./desired');
|
||||
|
||||
describeWd('clear', function(h) {
|
||||
it('should clear the text field', function(done) {
|
||||
h.driver
|
||||
describe('testapp - clear -', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should clear the text field', function (done) {
|
||||
driver
|
||||
.elementByTagName('textField').sendKeys("some-value").text()
|
||||
.should.become("some-value")
|
||||
.elementByTagName('textField').clear().text().should.become('')
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should hide keyboard', function(done) {
|
||||
h.driver
|
||||
it('should hide keyboard', function (done) {
|
||||
driver
|
||||
.elementByTagName('textField').sendKeys("1")
|
||||
.elementByTagName('slider').click()
|
||||
.should.be.rejected
|
||||
.then(function () {
|
||||
if (!env.IOS7) {
|
||||
return driver
|
||||
.elementByTagName('slider').click()
|
||||
.should.be.rejected;
|
||||
}
|
||||
})
|
||||
.execute("mobile: hideKeyboard", [{keyName: "Done"}])
|
||||
.elementByTagName('slider').click()
|
||||
.nodeify(done);
|
||||
|
||||
7
test/functional/testapp/desired.js
Normal file
7
test/functional/testapp/desired.js
Normal file
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
var appUtils = require('../../helpers/app-utils');
|
||||
|
||||
module.exports = {
|
||||
app: appUtils.getAppPath('TestApp')
|
||||
};
|
||||
@@ -1,19 +1,26 @@
|
||||
"use strict";
|
||||
|
||||
var driverblock = require("../../helpers/driverblock.js")
|
||||
, describeWd = driverblock.describeForApp('TestApp')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base"),
|
||||
desired = require('./desired');
|
||||
|
||||
describeWd('device target actions', function(h) {
|
||||
it("should die in background and respond within (+/- 6 secs)", function(done) {
|
||||
var before = new Date().getTime() / 1000;
|
||||
h.driver
|
||||
.execute("mobile: background", [{seconds: 1}])
|
||||
.then(function() {}, function(err) {
|
||||
err.cause.value.message.should.contain("Instruments died");
|
||||
throw err;
|
||||
}).should.be.rejectedWith(/status: 13/)
|
||||
.then(function() { ((new Date().getTime() / 1000) - before).should.be.below(10); })
|
||||
.nodeify(done);
|
||||
describe('testapp - device -', function () {
|
||||
|
||||
describe('target actions', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it("should die in background and respond within (+/- 6 secs)", function (done) {
|
||||
var before = new Date().getTime() / 1000;
|
||||
driver
|
||||
.execute("mobile: background", [{seconds: 1}])
|
||||
.catch(function (err) {
|
||||
err.cause.value.message.should.contain("Instruments died");
|
||||
throw err;
|
||||
}).should.be.rejectedWith(/status: 13/)
|
||||
.then(function () { ((new Date().getTime() / 1000) - before).should.be.below(10); })
|
||||
.sleep(5000) // cooldown
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,32 +1,33 @@
|
||||
"use strict";
|
||||
var setup = require("../common/setup-base")
|
||||
, desired = require('./desired')
|
||||
, Q = require("q");
|
||||
|
||||
var driverblock = require("../../helpers/driverblock.js")
|
||||
, Q = driverblock.Q
|
||||
, describeWd = driverblock.describeForApp('TestApp')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
describe('testapp - find element -', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
describeWd('elementByTagName', function(h) {
|
||||
it('should find a single element on the app', function(done) {
|
||||
h.driver.elementByTagName('button').then(function(el) {
|
||||
it('should find a single element on the app', function (done) {
|
||||
driver.elementByTagName('button').then(function (el) {
|
||||
el.value.should.exist;
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should not find any invalid elements on the app and throw error', function(done) {
|
||||
h.driver
|
||||
it('should not find any invalid elements on the app and throw error', function (done) {
|
||||
driver
|
||||
.elementByTagName('buttonNotThere')
|
||||
.catch(function(err) {
|
||||
.catch(function (err) {
|
||||
err['jsonwire-error'].summary.should.eql('NoSuchElement');
|
||||
throw err;
|
||||
})
|
||||
.should.be.rejectedWith(/status: 7/)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should find alerts when they exist', function(done) {
|
||||
h.driver
|
||||
.elementsByTagName('button').then(function(els) {
|
||||
it('should find alerts when they exist', function (done) {
|
||||
driver
|
||||
.elementsByTagName('button').then(function (els) {
|
||||
return els[1].click();
|
||||
}).then(function() { return h.driver.elementByTagName('alert'); })
|
||||
.then(function(alertEl) {
|
||||
}).then(function () { return driver.elementByTagName('alert'); })
|
||||
.then(function (alertEl) {
|
||||
return Q.all([
|
||||
alertEl.elementByName('OK').should.eventually.exist,
|
||||
alertEl.elementByName('Cancel').should.eventually.exist
|
||||
@@ -34,57 +35,56 @@ describeWd('elementByTagName', function(h) {
|
||||
}).dismissAlert()
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should not find alerts when they dont exist', function(done) {
|
||||
h.driver.elementByTagName('alert')
|
||||
.catch(function(err) {
|
||||
it('should not find alerts when they dont exist', function (done) {
|
||||
driver.elementByTagName('alert')
|
||||
.catch(function (err) {
|
||||
err['jsonwire-error'].summary.should.eql('NoSuchElement');
|
||||
throw err;
|
||||
}).should.be.rejectedWith(/status: 7/)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should get an error when strategy doesnt exist', function(done) {
|
||||
h.driver.elementByCss('button')
|
||||
.catch(function(err) {
|
||||
it('should get an error when strategy doesnt exist', function (done) {
|
||||
driver.elementByCss('button')
|
||||
.catch(function (err) {
|
||||
err.cause.value.message.should.equal("Invalid locator strategy: css selector");
|
||||
throw err;
|
||||
}).should.be.rejectedWith(/status: 9/)
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should find all elements by tag name in the app', function(done) {
|
||||
h.driver
|
||||
.elementsByTagName('button').then(function(els) {
|
||||
it('should find all elements by tag name in the app', function (done) {
|
||||
driver
|
||||
.elementsByTagName('button').then(function (els) {
|
||||
els.length.should.equal(4);
|
||||
els[0].value.should.exist;
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should not find any elements on the app but fail gracefully', function(done) {
|
||||
h.driver.elementsByTagName('buttonNotThere').should.eventually.have.length(0)
|
||||
it('should not find any elements on the app but fail gracefully', function (done) {
|
||||
driver.elementsByTagName('buttonNotThere').should.eventually.have.length(0)
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should find element by valid name', function(done) {
|
||||
h.driver.elementByName('ComputeSumButton').should.eventually.exist
|
||||
it('should find element by valid name', function (done) {
|
||||
driver.elementByName('ComputeSumButton').should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should not find element by invalid name but return respective error code', function(done) {
|
||||
h.driver.elementByName('InvalidNameForElement')
|
||||
.catch(function(err) {
|
||||
it('should not find element by invalid name but return respective error code', function (done) {
|
||||
driver.elementByName('InvalidNameForElement')
|
||||
.catch(function (err) {
|
||||
err['jsonwire-error'].summary.should.eql('NoSuchElement');
|
||||
throw err;
|
||||
}).should.be.rejectedWith(/status: 7/)
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should find multiple elements by valid name', function(done) {
|
||||
h.driver.elementsByName('AppElem').should.eventually.have.length(3)
|
||||
it('should find multiple elements by valid name', function (done) {
|
||||
driver.elementsByName('AppElem').should.eventually.have.length(3)
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
// it('should find an element within its parent', function(done) {
|
||||
// h.driver
|
||||
// it('should find an element within its parent', function (done) {
|
||||
// driver
|
||||
// .elementByTagName('button').should.eventually.exist
|
||||
// .elementByTagName('UIALabel').should.eventually.exist
|
||||
// .nodeify(done);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require('../../helpers/driverblock.js').describeForApp('TestApp')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base"),
|
||||
desired = require('./desired');
|
||||
|
||||
describeWd('getAttribute', function(h) {
|
||||
it('should get element attribute', function(done) {
|
||||
h.driver
|
||||
describe('testapp - get attribute -', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should get element attribute', function (done) {
|
||||
driver
|
||||
.elementByTagName('button').getAttribute("name").should.become("ComputeSumButton")
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
@@ -1,43 +1,46 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('TestApp')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base"),
|
||||
desired = require('./desired');
|
||||
|
||||
describeWd('check location', function(h) {
|
||||
it('should return the right x/y coordinates', function(done) {
|
||||
h.driver
|
||||
.elementByTagName('button').getLocation().then(function(location) {
|
||||
describe('testapp - location -', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should return the right x/y coordinates', function (done) {
|
||||
driver
|
||||
.elementByTagName('button').getLocation().then(function (location) {
|
||||
location.x.should.equal(94);
|
||||
location.y.should.equal(122);
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should not error with valid lat/lon and no options', function(done) {
|
||||
it('should not error with valid lat/lon and no options', function (done) {
|
||||
var locationOpts = {
|
||||
latitude: -30
|
||||
, longitude: 30
|
||||
, longitude: 30
|
||||
};
|
||||
h.driver.execute('mobile: setLocation', [locationOpts])
|
||||
driver.execute('mobile: setLocation', [locationOpts])
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should not error with valid lat/lon and valid options', function(done) {
|
||||
it('should not error with valid lat/lon and valid options', function (done) {
|
||||
var locationOpts = {
|
||||
latitude: -30
|
||||
, longitude: 30
|
||||
, altitude: 1000
|
||||
, longitude: 30
|
||||
, altitude: 1000
|
||||
};
|
||||
h.driver.execute('mobile: setLocation', [locationOpts])
|
||||
driver.execute('mobile: setLocation', [locationOpts])
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should error with invalid lat/lon and no options', function(done) {
|
||||
it('should error with invalid lat/lon and no options', function (done) {
|
||||
var locationOpts = {
|
||||
latitude: -150
|
||||
, longitude: 30
|
||||
, longitude: 30
|
||||
};
|
||||
h.driver.execute('mobile: setLocation', [locationOpts])
|
||||
driver.execute('mobile: setLocation', [locationOpts])
|
||||
.should.be.rejected
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
@@ -1,18 +1,26 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('TestApp')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var alertUtils = require('../../helpers/alert-utils'),
|
||||
setup = require("../common/setup-base"),
|
||||
desired = require('./desired');
|
||||
|
||||
describeWd('pinchOpen and pinchClose gesture', function(h) {
|
||||
it('should pinchOpen and pinchClose map after tapping Test Gesture', function(done) {
|
||||
h.driver
|
||||
.elementsByTagName('button').then(function(buttons) { return buttons[3].click(); })
|
||||
.elementByXPath('//window[1]/UIAMapView[1]')
|
||||
.execute("mobile: pinchOpen", [{startX: 114.0, startY: 198.0, endX: 257.0,
|
||||
endY: 256.0, duration: 5.0}])
|
||||
.elementByXPath('//window[1]/UIAMapView[1]')
|
||||
.execute("mobile: pinchClose", [{startX: 114.0, startY: 198.0, endX: 257.0,
|
||||
endY: 256.0, duration: 5.0}])
|
||||
.nodeify(done);
|
||||
describe('testapp - pinch gesture -', function () {
|
||||
|
||||
describe('pinchOpen and pinchClose gesture', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should pinchOpen and pinchClose map after tapping Test Gesture', function (done) {
|
||||
driver
|
||||
.elementsByTagName('button').then(function (buttons) { return buttons[3].click(); })
|
||||
.sleep(1000).then(function () { alertUtils.okIfAlert(driver); })
|
||||
.elementByXPath('//window[1]/UIAMapView[1]')
|
||||
.execute("mobile: pinchOpen", [{startX: 114.0, startY: 198.0, endX: 257.0,
|
||||
endY: 256.0, duration: 5.0}])
|
||||
.elementByXPath('//window[1]/UIAMapView[1]')
|
||||
.execute("mobile: pinchClose", [{startX: 114.0, startY: 198.0, endX: 257.0,
|
||||
endY: 256.0, duration: 5.0}])
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('TestApp')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var alertUtils = require('../../helpers/alert-utils'),
|
||||
setup = require("../common/setup-base"),
|
||||
desired = require('./desired');
|
||||
|
||||
describeWd('rotation gesture', function(h) {
|
||||
it('should rotate map after tapping Test Gesture', function(done) {
|
||||
h.driver.elementsByTagName('button')
|
||||
.then(function(buttons) { return buttons[3].click(); })
|
||||
describe('testapp - rotation gesture -', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should rotate map after tapping Test Gesture', function (done) {
|
||||
driver.elementsByTagName('button')
|
||||
.then(function (buttons) { return buttons[3].click(); })
|
||||
.sleep(1000).then(function () { alertUtils.okIfAlert(driver); })
|
||||
.elementsByTagName('Map')
|
||||
.execute("mobile: rotate", [{x: 114, y: 198, duration: 5, radius: 3,
|
||||
rotation: 220, touchCount: 2}])
|
||||
|
||||
@@ -2,20 +2,23 @@
|
||||
// https://github.com/hugs/appium/blob/master/sample-code/webdriver-test.py
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('TestApp')
|
||||
, it = require("../../helpers/driverblock.js").it
|
||||
, appiumPort = process.env.APPIUM_PORT || 4723
|
||||
var env = require('../../helpers/env')
|
||||
, setup = require("../common/setup-base")
|
||||
, desired = require('./desired')
|
||||
, request = require("request");
|
||||
|
||||
describeWd('check getSessions', function(h) {
|
||||
it('should return appear in the sessions returned', function(done) {
|
||||
describe('testapp - sessions -', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should return appear in the sessions returned', function (done) {
|
||||
request({
|
||||
url: "http://localhost:" + appiumPort + "/wd/hub/sessions"
|
||||
, method: "GET"
|
||||
, json: true
|
||||
}, function(err, response, body) {
|
||||
h.driver.sessionID.should.equal(body.value[0].id);
|
||||
url: "http://localhost:" + env.APPIUM_PORT + "/wd/hub/sessions"
|
||||
, method: "GET"
|
||||
, json: true
|
||||
}, function (err, response, body) {
|
||||
driver.sessionID.should.equal(body.value[0].id);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,33 +2,37 @@
|
||||
// https://github.com/hugs/appium/blob/master/sample-code/webdriver-test.py
|
||||
"use strict";
|
||||
|
||||
var driverblock = require("../../helpers/driverblock.js")
|
||||
, Q = driverblock.Q
|
||||
, it = driverblock.it
|
||||
, describeWd = require("../../helpers/driverblock.js").describeForApp('TestApp')
|
||||
var setup = require("../common/setup-base")
|
||||
, desired = require('./desired')
|
||||
, Q = require("q")
|
||||
, _ = require('underscore');
|
||||
|
||||
describeWd('calc app', function(h) {
|
||||
var values = [];
|
||||
var populate = function(driver) {
|
||||
return driver.elementsByTagName('textField').then(function(elems) {
|
||||
var sequence = _(elems).map(function(elem) {
|
||||
var val = Math.round(Math.random()*10);
|
||||
values.push(val);
|
||||
return function() { return elem.sendKeys(val); };
|
||||
});
|
||||
return sequence.reduce(Q.when, new Q()); // running sequence
|
||||
});
|
||||
};
|
||||
describe('testapp - simple -', function () {
|
||||
|
||||
it('should fill two fields with numbers', function(done) {
|
||||
var driver = h.driver;
|
||||
populate(driver).then(function() {
|
||||
return driver
|
||||
.elementByTagName('button').click()
|
||||
.elementByTagName('staticText').text().then(function(text) {
|
||||
parseInt(text, 10).should.equal(values[0] + values[1]);
|
||||
describe('using calc app', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
var values = [];
|
||||
var populate = function (driver) {
|
||||
return driver.elementsByTagName('textField').then(function (elems) {
|
||||
var sequence = _(elems).map(function (elem) {
|
||||
var val = Math.round(Math.random() * 10);
|
||||
values.push(val);
|
||||
return function () { return elem.sendKeys(val); };
|
||||
});
|
||||
}).nodeify(done);
|
||||
return sequence.reduce(Q.when, new Q()); // running sequence
|
||||
});
|
||||
};
|
||||
|
||||
it('should fill two fields with numbers', function (done) {
|
||||
populate(driver).then(function () {
|
||||
return driver
|
||||
.elementByTagName('button').click()
|
||||
.elementByTagName('staticText').text().then(function (text) {
|
||||
parseInt(text, 10).should.equal(values[0] + values[1]);
|
||||
});
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require('../../helpers/driverblock.js').describeForApp('TestApp')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base"),
|
||||
desired = require('./desired');
|
||||
|
||||
describeWd('element size', function(h) {
|
||||
it('should return the right element size', function(done) {
|
||||
h.driver.elementByTagName('button').getSize().then(function(size) {
|
||||
size.width.should.eql(113);
|
||||
size.height.should.eql(37);
|
||||
}).nodeify(done);
|
||||
});
|
||||
describe('testapp - size -', function () {
|
||||
|
||||
it('should return the window size', function(done) {
|
||||
h.driver.getWindowSize().then(function(size) {
|
||||
size.width.should.be.above(319);
|
||||
size.height.should.be.above(479);
|
||||
}).nodeify(done);
|
||||
describe('element size', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should return the right element size', function (done) {
|
||||
driver.elementByTagName('button').getSize().then(function (size) {
|
||||
size.width.should.eql(113);
|
||||
size.height.should.eql(37);
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it('should return the window size', function (done) {
|
||||
driver.getWindowSize().then(function (size) {
|
||||
size.width.should.be.above(319);
|
||||
size.height.should.be.above(479);
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require('../../helpers/driverblock.js').describeForApp('TestApp')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base"),
|
||||
desired = require('./desired');
|
||||
|
||||
describeWd('get source', function(h) {
|
||||
return it('should return the page source', function(done) {
|
||||
h.driver.source().then(function(source) {
|
||||
describe('testapp - source -', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
return it('should return the page source', function (done) {
|
||||
driver.source().then(function (source) {
|
||||
var obj = JSON.parse(source);
|
||||
obj.should.exist;
|
||||
obj.type.should.equal("UIAApplication");
|
||||
|
||||
@@ -6,127 +6,155 @@
|
||||
* this test
|
||||
*/
|
||||
|
||||
var describeWd = require('../../helpers/driverblock.js').describeForApp('TestApp')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base"),
|
||||
desired = require('./desired'),
|
||||
_ = require('underscore');
|
||||
|
||||
describeWd('command timeout', function(h) {
|
||||
it('should be settable and gettable', function(done) {
|
||||
h.driver
|
||||
.execute("mobile: setCommandTimeout", [{timeout: 37}])
|
||||
.execute("mobile: getCommandTimeout").should.become(37)
|
||||
.nodeify(done);
|
||||
describe('testapp - timeouts -', function () {
|
||||
|
||||
afterEach(function (done) { setTimeout(done, 3000); });
|
||||
|
||||
describe('command timeout settings', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should be settable and gettable', function (done) {
|
||||
driver
|
||||
.execute("mobile: setCommandTimeout", [{timeout: 37}])
|
||||
.execute("mobile: getCommandTimeout").should.become(37)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('short timeout', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should die with short command timeout', function (done) {
|
||||
var params = {timeout: 3};
|
||||
driver
|
||||
.execute("mobile: setCommandTimeout", [params])
|
||||
.sleep(5500)
|
||||
.elementByName('dont exist dogg')
|
||||
.should.be.rejectedWith(/status: (13|6)/)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mobile reset', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should die with short command timeout even after mobile reset', function (done) {
|
||||
var params = {timeout: 3};
|
||||
driver
|
||||
.execute("mobile: setCommandTimeout", [params])
|
||||
.execute("mobile: reset")
|
||||
.sleep(6500)
|
||||
.elementByName('dont exist dogg')
|
||||
.should.be.rejectedWith(/status: (13|6)/)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('command timeout set to 0', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('when set to 0 should disable itself', function (done) {
|
||||
driver
|
||||
.execute("mobile: setCommandTimeout", [{timeout: 0}])
|
||||
.sleep(3000)
|
||||
.elementByTagName('button').should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('command timeout set to false', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('when set to false should disable itself', function (done) {
|
||||
driver
|
||||
.execute("mobile: setCommandTimeout", [{timeout: false}])
|
||||
.sleep(3000)
|
||||
.elementByTagName('button').should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('command timeout via desired caps', function () {
|
||||
var driver;
|
||||
setup(this, _.defaults({newCommandTimeout: 3}, desired))
|
||||
.then(function (d) { driver = d; });
|
||||
|
||||
it('should die with short command timeout', function (done) {
|
||||
driver
|
||||
.sleep(5500)
|
||||
.elementByName('dont exist dogg')
|
||||
.should.be.rejectedWith(/status: (13|6)/)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('command timeout disabled via desired caps (0)', function () {
|
||||
var driver;
|
||||
setup(this, _.defaults({newCommandTimeout: 0}, desired))
|
||||
.then(function (d) { driver = d; });
|
||||
|
||||
it('when set to 0 should disable itself', function (done) {
|
||||
driver
|
||||
.sleep(5000)
|
||||
.elementByTagName('button').should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('command timeout disabled via desired caps (false)', function () {
|
||||
var driver;
|
||||
setup(this, _.defaults({newCommandTimeout: false}, desired))
|
||||
.then(function (d) { driver = d; });
|
||||
|
||||
it('when set to false should disable itself', function (done) {
|
||||
driver
|
||||
.execute("mobile: setCommandTimeout", [{timeout: false}])
|
||||
.sleep(5000)
|
||||
.elementByTagName('button').should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('check implicit wait', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
var impWaitSecs = 4;
|
||||
var impWaitCheck = function () {
|
||||
var before = new Date().getTime() / 1000;
|
||||
return driver
|
||||
.elementsByTagName('notgonnabethere').then(function (missing) {
|
||||
var after = new Date().getTime() / 1000;
|
||||
(after - before).should.be.below(impWaitSecs + 2);
|
||||
(after - before).should.be.above(impWaitSecs);
|
||||
missing.should.have.length(0);
|
||||
});
|
||||
};
|
||||
|
||||
it('should set the implicit wait for finding elements', function (done) {
|
||||
driver
|
||||
.setImplicitWaitTimeout(impWaitSecs * 1000)
|
||||
.then(impWaitCheck)
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should work even with a reset in the middle', function (done) {
|
||||
driver
|
||||
.setImplicitWaitTimeout(impWaitSecs * 1000)
|
||||
.then(impWaitCheck)
|
||||
.execute("mobile: reset")
|
||||
.sleep(3000) // cooldown
|
||||
.then(impWaitCheck)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describeWd('command timeout', function(h) {
|
||||
it('should die with short command timeout', function(done) {
|
||||
var params = {timeout: 3};
|
||||
h.driver
|
||||
.execute("mobile: setCommandTimeout", [params])
|
||||
.sleep(5500)
|
||||
.elementByName('dont exist dogg')
|
||||
.catch(function(err) {
|
||||
[13, 6].should.include(err.status);
|
||||
throw err;
|
||||
}).should.be.rejected
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describeWd('command timeout', function(h) {
|
||||
it('should die with short command timeout even after mobile reset', function(done) {
|
||||
var params = {timeout: 3};
|
||||
h.driver
|
||||
.execute("mobile: setCommandTimeout", [params])
|
||||
.execute("mobile: reset")
|
||||
.sleep(6500)
|
||||
.elementByName('dont exist dogg')
|
||||
.catch(function(err) {
|
||||
[13, 6].should.include(err.status);
|
||||
throw err;
|
||||
}).should.be.rejected
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describeWd('command timeout', function(h) {
|
||||
it('when set to 0 should disable itself', function(done) {
|
||||
h.driver
|
||||
.execute("mobile: setCommandTimeout", [{timeout: 0}])
|
||||
.sleep(3000)
|
||||
.elementByTagName('button').should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describeWd('command timeout', function(h) {
|
||||
it('when set to false should disable itself', function(done) {
|
||||
h.driver
|
||||
.execute("mobile: setCommandTimeout", [{timeout: false}])
|
||||
.sleep(3000)
|
||||
.elementByTagName('button').should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describeWd('command timeout via desired caps', function(h) {
|
||||
it('should die with short command timeout', function(done) {
|
||||
h.driver
|
||||
.sleep(5500)
|
||||
.elementByName('dont exist dogg')
|
||||
.catch(function(err) {
|
||||
[13, 6].should.include(err.status);
|
||||
throw err;
|
||||
}).should.be.rejected
|
||||
.nodeify(done);
|
||||
});
|
||||
}, null, null, {newCommandTimeout: 3});
|
||||
|
||||
describeWd('command timeout disabled via desired caps', function(h) {
|
||||
it('when set to 0 should disable itself', function(done) {
|
||||
h.driver
|
||||
.sleep(3000)
|
||||
.elementByTagName('button').should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
}, null, null, {newCommandTimeout: 0});
|
||||
|
||||
describeWd('command timeout disabled via desired caps', function(h) {
|
||||
it('when set to false should disable itself', function(done) {
|
||||
h.driver
|
||||
.execute("mobile: setCommandTimeout", [{timeout: false}])
|
||||
.sleep(3000)
|
||||
.elementByTagName('button').should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
}, null, null, {newCommandTimeout: false});
|
||||
|
||||
describeWd('check implicit wait', function(h) {
|
||||
var impWaitSecs = 4;
|
||||
var impWaitCheck = function() {
|
||||
var before = new Date().getTime() / 1000;
|
||||
return h.driver
|
||||
.elementsByTagName('notgonnabethere').then(function(missing) {
|
||||
var after = new Date().getTime() / 1000;
|
||||
(after - before).should.be.below(impWaitSecs + 2);
|
||||
(after - before).should.be.above(impWaitSecs);
|
||||
missing.should.have.length(0);
|
||||
});
|
||||
};
|
||||
|
||||
it('should set the implicit wait for finding elements', function(done) {
|
||||
h.driver
|
||||
.setImplicitWaitTimeout(impWaitSecs * 1000)
|
||||
.then(impWaitCheck)
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should work even with a reset in the middle', function(done) {
|
||||
h.driver
|
||||
.setImplicitWaitTimeout(impWaitSecs * 1000)
|
||||
.then(impWaitCheck)
|
||||
.execute("mobile: reset")
|
||||
.then(impWaitCheck)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,34 +1,43 @@
|
||||
"use strict";
|
||||
|
||||
var driverBlock = require("../../helpers/driverblock.js")
|
||||
, Q = driverBlock.Q
|
||||
, path = require('path')
|
||||
, appPath = path.resolve(__dirname, "../../../sample-code/apps/ToggleTest/bin/ToggleTest-debug.apk")
|
||||
, appPkg = "com.example.toggletest"
|
||||
, appAct = ".MainActivity"
|
||||
, it = driverBlock.it;
|
||||
var setup = require("../common/setup-base")
|
||||
, appUtils = require('../../helpers/app-utils');
|
||||
|
||||
module.exports = {
|
||||
app: appUtils.getAppPath('TestApp')
|
||||
};
|
||||
|
||||
var desired = {
|
||||
app: appUtils.getAppPath('ToggleTest'),
|
||||
'app-package': 'com.example.toggletest',
|
||||
'app-activity': '.MainActivity',
|
||||
newCommandTimeout: 90
|
||||
};
|
||||
|
||||
var toggleTest = function (promisedBrowser, displayName, toggleElementName, toggleMethod) {
|
||||
return function () {
|
||||
var driver;
|
||||
promisedBrowser.then(function (d) { driver = d; });
|
||||
|
||||
var toggleTest = function(h, displayName, toggleElementName, toggleMethod) {
|
||||
return function() {
|
||||
var initialValue;
|
||||
it('should toggle ' + displayName, function(done) {
|
||||
h.driver
|
||||
.elementByName(toggleElementName).text().then(function(txt) {
|
||||
it('should toggle ' + displayName, function (done) {
|
||||
driver
|
||||
.elementByName(toggleElementName).text().then(function (txt) {
|
||||
initialValue = txt;
|
||||
return h.driver.execute("mobile: " + toggleMethod);
|
||||
return driver.execute("mobile: " + toggleMethod);
|
||||
})
|
||||
.then(function() {
|
||||
return h.driver.elementByName(toggleElementName).text().then(function(txt) {
|
||||
.then(function () {
|
||||
return driver.elementByName(toggleElementName).text().then(function (txt) {
|
||||
txt.should.equal(initialValue === "ON" ? "OFF" : "ON");
|
||||
});
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should toggle ' + displayName + ' back to initial value', function(done) {
|
||||
h.driver.execute("mobile: " + toggleMethod)
|
||||
.then(function() {
|
||||
return h.driver.elementByName(toggleElementName).text().then(function(txt) {
|
||||
it('should toggle ' + displayName + ' back to initial value', function (done) {
|
||||
driver.execute("mobile: " + toggleMethod)
|
||||
.then(function () {
|
||||
return driver.elementByName(toggleElementName).text().then(function (txt) {
|
||||
txt.should.equal(initialValue);
|
||||
});
|
||||
})
|
||||
@@ -37,16 +46,12 @@ var toggleTest = function(h, displayName, toggleElementName, toggleMethod) {
|
||||
};
|
||||
};
|
||||
|
||||
var runForPlatform = function(platform) {
|
||||
var describeWd = driverBlock.describeForApp(appPath, platform, appPkg, appAct);
|
||||
|
||||
describeWd('toggles', function(h) {
|
||||
describe('toggle cellular data', toggleTest(h, "cellular data", "data_toggle", "toggleData"));
|
||||
describe('toggle Flight Mode', toggleTest(h, "Flight Mode", "flight_toggle", "toggleFlightMode"));
|
||||
describe('toggle Wi-Fi', toggleTest(h, "Wi-Fi", "wifi_toggle", "toggleWiFi"));
|
||||
describe('toggle Location Services', toggleTest(h, "Location Services", "gps_toggle", "toggleLocationServices"));
|
||||
}, null, null, {newCommandTimeout: 90});
|
||||
};
|
||||
|
||||
module.exports.runForPlatform = runForPlatform;
|
||||
// disabling because it is very flaky
|
||||
describe('toggles @skip-all-android', function () {
|
||||
var promisedBrowser = setup(this, desired);
|
||||
|
||||
describe('toggle cellular data', toggleTest(promisedBrowser, "cellular data", "data_toggle", "toggleData"));
|
||||
describe('toggle Flight Mode', toggleTest(promisedBrowser, "Flight Mode", "flight_toggle", "toggleFlightMode"));
|
||||
describe('toggle Wi-Fi', toggleTest(promisedBrowser, "Wi-Fi", "wifi_toggle", "toggleWiFi"));
|
||||
describe('toggle Location Services', toggleTest(promisedBrowser, "Location Services", "gps_toggle", "toggleLocationServices"));
|
||||
});
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var test = require("./toggle.js");
|
||||
|
||||
test.runForPlatform("android");
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var test = require("./toggle.js");
|
||||
|
||||
test.runForPlatform("selendroid");
|
||||
|
||||
@@ -1,55 +1,70 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('UICatalog')
|
||||
, it = require("../../helpers/driverblock.js").it
|
||||
, appiumPort = process.env.APPIUM_PORT || 4723
|
||||
var env = require('../../helpers/env')
|
||||
, setup = require("../common/setup-base")
|
||||
, desired = require('./desired')
|
||||
, io = require('socket.io-client');
|
||||
|
||||
// setup websocket client...
|
||||
var options ={
|
||||
transports: ['websocket'],
|
||||
'force new connection': true
|
||||
};
|
||||
// setup websocket client...
|
||||
var options = {
|
||||
transports: ['websocket'],
|
||||
'force new connection': true
|
||||
};
|
||||
|
||||
describeWd('alert dialog detection', function(h) {
|
||||
it('should detect Show Simple', function(done) {
|
||||
var client = io.connect('http://127.0.0.1:' + appiumPort, options);
|
||||
client.on('alert', function() {
|
||||
client.disconnect();
|
||||
done();
|
||||
describe('uicatalog - alerts -', function () {
|
||||
|
||||
var alertTag = env.IOS7 ? '@label' : '@value';
|
||||
|
||||
describe('alert dialog detection', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should detect Show Simple', function (done) {
|
||||
var client = io.connect('http://127.0.0.1:' + env.APPIUM_PORT, options);
|
||||
client.on('alert', function () {
|
||||
client.disconnect();
|
||||
done();
|
||||
});
|
||||
driver
|
||||
.elementByXPath("//text[contains(@label,'Alerts')]").click()
|
||||
.sleep(10000)
|
||||
.elementsByXPath("//text[contains(" + alertTag + ",'Show Simple')]")
|
||||
.then(function (els) { return els[1]; }).click()
|
||||
.done();
|
||||
});
|
||||
});
|
||||
describe('alert dialog detection', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should detect Show OK-Cancel', function (done) {
|
||||
var client = io.connect('http://127.0.0.1:' + env.APPIUM_PORT, options);
|
||||
client.on('alert', function () {
|
||||
client.disconnect();
|
||||
done();
|
||||
});
|
||||
driver
|
||||
.elementByXPath("//text[contains(@label,'Alerts')]").click()
|
||||
.elementsByXPath("//text[contains(" + alertTag + ",'Show OK-Cancel')]")
|
||||
.then(function (els) { return els[1]; }).click()
|
||||
.done();
|
||||
});
|
||||
});
|
||||
describe('alert dialog detection', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should detect Show Custom', function (done) {
|
||||
var client = io.connect('http://127.0.0.1:' + env.APPIUM_PORT, options);
|
||||
client.on('alert', function () {
|
||||
client.disconnect();
|
||||
done();
|
||||
});
|
||||
driver
|
||||
.elementByXPath("//text[contains(@label,'Alerts')]").click()
|
||||
.elementsByXPath("//text[contains(" + alertTag + ",'Show Custom')]")
|
||||
.then(function (els) { return els[1]; }).click()
|
||||
.done();
|
||||
});
|
||||
h.driver
|
||||
.elementByXPath("//text[contains(@label,'Alerts')]").click()
|
||||
.elementsByXPath("//text[contains(@value,'Show Simple')]")
|
||||
.then(function(els) { return els[1]; }).click()
|
||||
.done();
|
||||
});
|
||||
});
|
||||
describeWd('alert dialog detection', function(h) {
|
||||
it('should detect Show OK-Cancel', function(done) {
|
||||
var client = io.connect('http://127.0.0.1:' + appiumPort, options);
|
||||
client.on('alert', function() {
|
||||
client.disconnect();
|
||||
done();
|
||||
});
|
||||
h.driver
|
||||
.elementByXPath("//text[contains(@label,'Alerts')]").click()
|
||||
.elementsByXPath("//text[contains(@value,'Show OK-Cancel')]")
|
||||
.then(function(els) { return els[1]; }).click()
|
||||
.done();
|
||||
});
|
||||
});
|
||||
describeWd('alert dialog detection', function(h) {
|
||||
it('should detect Show Custom', function(done) {
|
||||
var client = io.connect('http://127.0.0.1:' + appiumPort, options);
|
||||
client.on('alert', function() {
|
||||
client.disconnect();
|
||||
done();
|
||||
});
|
||||
h.driver
|
||||
.elementByXPath("//text[contains(@label,'Alerts')]").click()
|
||||
.elementsByXPath("//text[contains(@value,'Show Custom')]")
|
||||
.then(function(els) { return els[1]; }).click()
|
||||
.done();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,79 +1,95 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('UICatalog')
|
||||
, path = require('path')
|
||||
, appUrl = 'http://appium.s3.amazonaws.com/UICatalog6.0.app.zip'
|
||||
, appZip = path.resolve(__dirname, "../../../assets/UICatalog6.0.app.zip")
|
||||
, describeZip = require('../../helpers/driverblock.js').describeForApp(appZip)
|
||||
, describeUrl = require('../../helpers/driverblock.js').describeForApp(appUrl);
|
||||
var env = require('../../helpers/env')
|
||||
, setup = require("../common/setup-base")
|
||||
, desired = require('./desired')
|
||||
, path = require('path');
|
||||
|
||||
describeWd('basic', function(h) {
|
||||
describe('uicatalog - basic -', function () {
|
||||
|
||||
if (process.env.FAST_TESTS) {
|
||||
beforeEach(function(done) {
|
||||
h.driver
|
||||
.elementByNameOrNull('Back')
|
||||
.then(function(el) { if (el) return el.click(); })
|
||||
describe('api', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
if (env.FAST_TESTS) {
|
||||
beforeEach(function (done) {
|
||||
driver
|
||||
.elementByNameOrNull('Back')
|
||||
.then(function (el) { if (el) return el.click(); })
|
||||
.nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should confirm element is not visible', function (done) {
|
||||
driver
|
||||
.elementByTagName('tableCell').click()
|
||||
.elementByName("UIButtonTypeContactAdd").isDisplayed()
|
||||
.should.not.eventually.be.ok
|
||||
.nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should confirm element is not visible', function(done) {
|
||||
h.driver
|
||||
.elementByTagName('tableCell').click()
|
||||
.elementByName("UIButtonTypeContactAdd").isDisplayed()
|
||||
.should.not.eventually.be.ok
|
||||
.nodeify(done);
|
||||
|
||||
it('should confirm element is visible', function (done) {
|
||||
driver
|
||||
.elementByTagName('tableCell').click()
|
||||
.elementByName("UIButtonTypeRoundedRect").isDisplayed()
|
||||
.should.eventually.be.ok
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should confirm element is selected @skip-ios7', function (done) {
|
||||
driver
|
||||
.elementByXPath("text[contains(@text, 'Picker')]").click()
|
||||
.elementByXPath("button[contains(@text, 'UIPicker')]").isSelected()
|
||||
.should.eventually.be.ok
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should confirm element is not selected returns false', function (done) {
|
||||
driver
|
||||
.elementByXPath("text[contains(@text, 'Picker')]").click()
|
||||
.elementByXPath("button[contains(@text, 'Custom')]").isSelected()
|
||||
.should.not.eventually.be.ok
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('should confirm element is visible', function(done) {
|
||||
h.driver
|
||||
.elementByTagName('tableCell').click()
|
||||
.elementByName("UIButtonTypeRoundedRect").isDisplayed()
|
||||
.should.eventually.be.ok
|
||||
.nodeify(done);
|
||||
});
|
||||
describe('load zipped app', function () {
|
||||
var driver;
|
||||
var appZip = path.resolve(__dirname, "../../../assets/UICatalog6.0.app.zip");
|
||||
setup(this, {app: appZip})
|
||||
.then(function (d) { driver = d; });
|
||||
|
||||
it('should confirm element is selected', function(done) {
|
||||
h.driver
|
||||
.elementByXPath("text[contains(@text, 'Picker')]").click()
|
||||
.elementByXPath("button[contains(@text, 'UIPicker')]").isSelected()
|
||||
.should.eventually.be.ok
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should confirm element is not selected returns false', function(done) {
|
||||
h.driver
|
||||
.elementByXPath("text[contains(@text, 'Picker')]").click()
|
||||
.elementByXPath("button[contains(@text, 'Custom')]").isSelected()
|
||||
.should.not.eventually.be.ok
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describeZip('appium ios', function(h) {
|
||||
it('should load a zipped app via path', function(done) {
|
||||
h.driver.elementByTagName('tableView')
|
||||
.should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describeUrl('appium ios', function(h) {
|
||||
it('should load a zipped app via url', function(done) {
|
||||
h.driver
|
||||
.elementByTagName('tableView')
|
||||
it('should load a zipped app via path', function (done) {
|
||||
driver.elementByTagName('tableView')
|
||||
.should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describeWd('appium ios', function(h) {
|
||||
it('should go back to using app from before', function(done) {
|
||||
h.driver
|
||||
.elementsByTagName('tableView')
|
||||
.should.eventually.have.length.above(0)
|
||||
.nodeify(done);
|
||||
describe('load zipped app via url', function () {
|
||||
var driver;
|
||||
var appUrl = 'http://appium.s3.amazonaws.com/UICatalog6.0.app.zip';
|
||||
setup(this, {app: appUrl})
|
||||
.then(function (d) { driver = d; });
|
||||
|
||||
it('should load a zipped app via url', function (done) {
|
||||
driver
|
||||
.elementByTagName('tableView')
|
||||
.should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('appium ios', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should go back to using app from before', function (done) {
|
||||
driver
|
||||
.elementsByTagName('tableView')
|
||||
.should.eventually.have.length.above(0)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
52
test/functional/uicatalog/controls.js
vendored
52
test/functional/uicatalog/controls.js
vendored
@@ -1,45 +1,53 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('UICatalog')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var env = require('../../helpers/env')
|
||||
, setup = require("../common/setup-base")
|
||||
, desired = require('./desired');
|
||||
|
||||
describeWd('execute', function(h) {
|
||||
describe('uicatalog - controls -', function () {
|
||||
|
||||
if (process.env.FAST_TESTS) {
|
||||
beforeEach(function(done) {
|
||||
h.driver
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
if (env.FAST_TESTS) {
|
||||
afterEach(function (done) {
|
||||
driver
|
||||
.elementByNameOrNull('Back')
|
||||
.then(function(el) { if (el) return el.click(); })
|
||||
.then(function (el) { if (el) return el.click(); })
|
||||
.nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should be able to get and set a picker value', function(done) {
|
||||
h.driver
|
||||
it('should be able to get and set a picker value', function (done) {
|
||||
var picketIdx = env.IOS7 ? 0 : 2; // TODO: why?
|
||||
driver
|
||||
.elementByXPath("//text[contains(@label,'Pickers')]").click()
|
||||
.elementsByTagName("picker").then(function(els) { return els[2]; })
|
||||
.elementByTagName('>', "pickerwheel").then(function(wheel) {
|
||||
.elementsByTagName("picker").at(picketIdx)
|
||||
.elementByTagName('>', "pickerwheel")
|
||||
.then(function (wheel) {
|
||||
return wheel
|
||||
.getAttribute("values").then(function(values) { return values[1]; })
|
||||
.should.become("Chris Armstrong")
|
||||
.then(function() {
|
||||
.getAttribute("values").then(function (values) {
|
||||
return values[1];
|
||||
}).should.become("Chris Armstrong")
|
||||
.then(function () {
|
||||
return wheel.type("Serena Auroux")
|
||||
.getAttribute("value").should.become("Serena Auroux. 3 of 7");
|
||||
});
|
||||
}).nodeify(done);
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should be able to get and set a slider value', function(done) {
|
||||
h.driver
|
||||
it('should be able to get and set a slider value', function (done) {
|
||||
driver
|
||||
.elementByXPath("//text[contains(@label,'Controls')]").click()
|
||||
.elementByTagName("slider").then(function(slider) {
|
||||
.elementByTagName("slider").then(function (slider) {
|
||||
return slider
|
||||
.getAttribute("value").should.become('50%')
|
||||
.then(function() {
|
||||
return slider.sendKeys(0.8).getAttribute("value")
|
||||
.should.become('80%');
|
||||
.then(function () {
|
||||
return slider.sendKeys(0.8).getAttribute("value").then(function (val) {
|
||||
['80%', '82%'].should.include(val); // irregular 82% occurence
|
||||
});
|
||||
});
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
7
test/functional/uicatalog/desired.js
Normal file
7
test/functional/uicatalog/desired.js
Normal file
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
var appUtils = require('../../helpers/app-utils');
|
||||
|
||||
module.exports = {
|
||||
app: appUtils.getAppPath('UICatalog')
|
||||
};
|
||||
@@ -1,23 +1,36 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('UICatalog')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var env = require('../../helpers/env'),
|
||||
setup = require("../common/setup-base"),
|
||||
desired = require('./desired');
|
||||
|
||||
describeWd('device target actions', function(h) {
|
||||
it("should lock the device for 4 of seconds (+/- 2 secs)", function(done) {
|
||||
var before = new Date().getTime() / 1000;
|
||||
h.driver
|
||||
.execute("mobile: lock", [{seconds: 4}])
|
||||
.then(function() {
|
||||
((new Date().getTime() / 1000) - before).should.be.below(7);
|
||||
}).nodeify(done);
|
||||
describe('uicatalog - device -', function () {
|
||||
|
||||
describe('lock device', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
var allowance = env.IOS7 ? 5 : 2;
|
||||
it("should lock the device for 4 of seconds (+/- " + allowance + " secs)", function (done) {
|
||||
var before = new Date().getTime() / 1000;
|
||||
driver
|
||||
.execute("mobile: lock", [{seconds: 4}])
|
||||
.then(function () {
|
||||
var now = (new Date().getTime() / 1000);
|
||||
(now - before).should.be.above(4);
|
||||
(now - before).should.be.below(4 + allowance + 1);
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
it("should background the app for 4 of seconds (+/- 6 secs)", function(done) {
|
||||
var before = new Date().getTime() / 1000;
|
||||
h.driver
|
||||
.execute("mobile: background", [{seconds: 4}])
|
||||
.then(function() {
|
||||
((new Date().getTime() / 1000) - before).should.be.below(11);
|
||||
}).nodeify(done);
|
||||
describe('background app', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
it("should background the app for 4 of seconds (+/- 6 secs)", function (done) {
|
||||
var before = new Date().getTime() / 1000;
|
||||
driver
|
||||
.execute("mobile: background", [{seconds: 4}])
|
||||
.then(function () {
|
||||
((new Date().getTime() / 1000) - before).should.be.below(11);
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('UICatalog')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base"),
|
||||
desired = require('./desired');
|
||||
|
||||
describeWd('execute', function(h) {
|
||||
it('should do UIAutomation commands if not in web frame', function(done) {
|
||||
h.driver
|
||||
describe('uicatalog - execute -', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should do UIAutomation commands if not in web frame', function (done) {
|
||||
driver
|
||||
.execute("UIATarget.localTarget().frontMostApp().bundleID()")
|
||||
.should.eventually.include(".UICatalog")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should not fail if UIAutomation command blows up', function(done) {
|
||||
h.driver
|
||||
it('should not fail if UIAutomation command blows up', function (done) {
|
||||
driver
|
||||
.execute("UIATarget.foobarblah()")
|
||||
.should.be.rejectedWith(/status: 17/)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should not fail with quotes', function(done) {
|
||||
h.driver.execute('console.log(\'hi\\\'s\');')
|
||||
it('should not fail with quotes', function (done) {
|
||||
driver.execute('console.log(\'hi\\\'s\');')
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,72 +1,76 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('UICatalog')
|
||||
, it = require("../../helpers/driverblock.js").it
|
||||
var env = require('../../helpers/env')
|
||||
, setup = require("../common/setup-base")
|
||||
, desired = require('./desired')
|
||||
, _ = require("underscore");
|
||||
|
||||
describeWd('findAndAct', function(h) {
|
||||
if (process.env.FAST_TESTS) {
|
||||
beforeEach(function(done) {
|
||||
h.driver
|
||||
describe('uicatalog - find and act -', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
if (env.FAST_TESTS) {
|
||||
beforeEach(function (done) {
|
||||
driver
|
||||
.elementByNameOrNull('Back')
|
||||
.then(function(el) { if (el) return el.click(); })
|
||||
.then(function (el) { if (el) return el.click(); })
|
||||
.nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
_.each({'tag name': 'cell', xpath: '//cell'}, function(sel, strat) {
|
||||
it('should tap immediately on an element by ' + strat, function(done) {
|
||||
_.each({'tag name': 'cell', xpath: '//cell'}, function (sel, strat) {
|
||||
it('should tap immediately on an element by ' + strat, function (done) {
|
||||
var opts = {strategy: strat, selector: sel};
|
||||
h.driver
|
||||
driver
|
||||
.execute("mobile: findAndAct", [opts])
|
||||
.elementByName("Gray").should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
it('should fail gracefully for not found elements', function(done) {
|
||||
it('should fail gracefully for not found elements', function (done) {
|
||||
var opts = {strategy: 'name', selector: 'doesntexistwot'};
|
||||
h.driver
|
||||
driver
|
||||
.execute("mobile: findAndAct", [opts])
|
||||
.should.be.rejectedWith(/status: 7/)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should fail gracefully for bad strategies', function(done) {
|
||||
it('should fail gracefully for bad strategies', function (done) {
|
||||
var opts = {strategy: 'tag namex', selector: 'button'};
|
||||
h.driver
|
||||
driver
|
||||
.execute("mobile: findAndAct", [opts])
|
||||
.catch(function(err) {
|
||||
.catch(function (err) {
|
||||
err.cause.value.origValue.should.include("tag namex");
|
||||
throw err;
|
||||
}).should.be.rejectedWith(/status: 13/)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should work with actions that return values', function(done) {
|
||||
it('should work with actions that return values', function (done) {
|
||||
var opts = {strategy: 'tag name', selector: 'cell', action: 'name'};
|
||||
h.driver
|
||||
driver
|
||||
.execute("mobile: findAndAct", [opts])
|
||||
.should.become("Buttons, Various uses of UIButton")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should work with actions that take params', function(done) {
|
||||
it('should work with actions that take params', function (done) {
|
||||
var opts = {strategy: 'tag name', selector: 'textfield', action:
|
||||
'setValue', params: ['some great text']};
|
||||
h.driver
|
||||
.elementsByTagName('cell').then(function(els) { return els[2]; })
|
||||
driver
|
||||
.elementsByTagName('cell').then(function (els) { return els[2]; })
|
||||
.click()
|
||||
.execute("mobile: findAndAct", [opts]).then(function() {
|
||||
.execute("mobile: findAndAct", [opts]).then(function () {
|
||||
opts.action = 'value';
|
||||
opts.params = [];
|
||||
}).execute("mobile: findAndAct", [opts])
|
||||
.should.become("some great text")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should work with indexes', function(done) {
|
||||
it('should work with indexes', function (done) {
|
||||
var opts = {strategy: 'tag name', selector: 'textfield', action:
|
||||
'setValue', params: ['some great text'], index: 1};
|
||||
h.driver
|
||||
.elementsByTagName('cell').then(function(els) { return els[2]; })
|
||||
driver
|
||||
.elementsByTagName('cell').then(function (els) { return els[2]; })
|
||||
.click()
|
||||
.execute("mobile: findAndAct", [opts]).then(function() {
|
||||
.execute("mobile: findAndAct", [opts]).then(function () {
|
||||
opts.action = 'value';
|
||||
opts.params = [];
|
||||
}).execute("mobile: findAndAct", [opts])
|
||||
|
||||
@@ -1,150 +1,150 @@
|
||||
"use strict";
|
||||
|
||||
var driverblock = require("../../helpers/driverblock.js")
|
||||
, Q = driverblock.Q
|
||||
, describeWd = driverblock.describeForApp('UICatalog')
|
||||
, it = driverblock.it
|
||||
var setup = require("../common/setup-base")
|
||||
, desired = require('./desired')
|
||||
, Q = require("q")
|
||||
, _ = require("underscore")
|
||||
, spinWait = require("../../helpers/spin.js").spinWait;
|
||||
|
||||
describeWd('find elements', function(h) {
|
||||
describe('uicatalog - find element -', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should find a single element by id', function(done) {
|
||||
it('should find a single element by id', function (done) {
|
||||
// ButtonsExplain: 'Various uses of UIButton'
|
||||
h.driver
|
||||
driver
|
||||
.elementById('ButtonsExplain')
|
||||
.should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should find a single element by name', function(done) {
|
||||
h.driver
|
||||
it('should find a single element by name', function (done) {
|
||||
driver
|
||||
.execute("mobile: findElementNameContains", [{name: 'uses of UIButton'}])
|
||||
.getAttribute('name').should.become("Buttons, Various uses of UIButton")
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should find an element within its parent', function(done) {
|
||||
h.driver
|
||||
.elementByTagName('tableView').then(function(el) {
|
||||
it('should find an element within its parent @skip-ios7', function (done) {
|
||||
driver
|
||||
.elementByTagName('tableView').then(function (el) {
|
||||
el.should.exist;
|
||||
return el.elementByTagName('text').text()
|
||||
.should.become("Buttons, Various uses of UIButton");
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it('should not find an element not within itself', function(done) {
|
||||
h.driver
|
||||
.elementByTagName('tableView').then(function(el) {
|
||||
it('should not find an element not within itself', function (done) {
|
||||
driver
|
||||
.elementByTagName('tableView').then(function (el) {
|
||||
el.should.exist;
|
||||
return el.elementByTagName('navigationBar')
|
||||
.should.be.rejectedWith(/status: 7/);
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it('should find some elements within itself', function(done) {
|
||||
h.driver
|
||||
.elementByTagName('tableCell').then(function(el) {
|
||||
it('should find some elements within itself', function (done) {
|
||||
driver
|
||||
.elementByTagName('tableCell').then(function (el) {
|
||||
el.should.exist;
|
||||
return el.elementsByTagName('text')
|
||||
return el.elementsByTagName('text')
|
||||
.should.eventually.have.length(1);
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
it('should not find elements not within itself', function(done) {
|
||||
h.driver
|
||||
.elementByTagName('tableCell').then(function(el) {
|
||||
it('should not find elements not within itself', function (done) {
|
||||
driver
|
||||
.elementByTagName('tableCell').then(function (el) {
|
||||
el.should.exist;
|
||||
el.elementsByTagName('navigationBar')
|
||||
.should.eventually.have.length(0);
|
||||
}).nodeify(done);
|
||||
});
|
||||
|
||||
describe('findElementsByTagName', function() {
|
||||
it('should return all image elements with internally generated ids', function(done) {
|
||||
h.driver.elementsByTagName('image').then(function(els) {
|
||||
describe('findElementsByTagName', function () {
|
||||
it('should return all image elements with internally generated ids', function (done) {
|
||||
driver.elementsByTagName('image').then(function (els) {
|
||||
els.length.should.be.above(0);
|
||||
_(els).each(function(el) {
|
||||
_(els).each(function (el) {
|
||||
el.should.exist;
|
||||
});
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('findElement(s)ByXpath', function() {
|
||||
var setupXpath = function(driver) {
|
||||
describe('findElement(s)ByXpath', function () {
|
||||
var setupXpath = function (driver) {
|
||||
return driver.elementByTagName('tableCell').click();
|
||||
};
|
||||
|
||||
it('should return the last button', function(done) {
|
||||
h.driver
|
||||
.resolve(setupXpath(h.driver))
|
||||
it('should return the last button', function (done) {
|
||||
driver
|
||||
.resolve(setupXpath(driver))
|
||||
.elementByXPath("//button[last()]").text()
|
||||
.should.become("Add contact")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should return a single element', function(done) {
|
||||
h.driver
|
||||
.resolve(setupXpath(h.driver))
|
||||
});
|
||||
it('should return a single element', function (done) {
|
||||
driver
|
||||
.resolve(setupXpath(driver))
|
||||
.elementByXPath("//button").text()
|
||||
.should.become("Back")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should return multiple elements', function(done) {
|
||||
h.driver
|
||||
.resolve(setupXpath(h.driver))
|
||||
it('should return multiple elements', function (done) {
|
||||
driver
|
||||
.resolve(setupXpath(driver))
|
||||
.elementsByXPath("//button")
|
||||
.should.eventually.have.length.above(5)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should filter by name', function(done) {
|
||||
h.driver
|
||||
.resolve(setupXpath(h.driver))
|
||||
it('should filter by name', function (done) {
|
||||
driver
|
||||
.resolve(setupXpath(driver))
|
||||
.elementByXPath("button[@name='Rounded']").text()
|
||||
.should.become("Rounded")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should know how to restrict root-level elements', function(done) {
|
||||
h.driver
|
||||
.resolve(setupXpath(h.driver))
|
||||
it('should know how to restrict root-level elements', function (done) {
|
||||
driver
|
||||
.resolve(setupXpath(driver))
|
||||
.elementByXPath("/button")
|
||||
.should.be.rejectedWith(/status: 7/)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should search an extended path by child', function(done) {
|
||||
h.driver
|
||||
.resolve(setupXpath(h.driver))
|
||||
.then(function() {
|
||||
return spinWait(function() {
|
||||
return h.driver.elementByXPath("navigationBar/text")
|
||||
it('should search an extended path by child', function (done) {
|
||||
driver
|
||||
.resolve(setupXpath(driver))
|
||||
.then(function () {
|
||||
return spinWait(function () {
|
||||
return driver.elementByXPath("navigationBar/text")
|
||||
.text().should.become('Buttons');
|
||||
});
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should search an extended path by descendant', function(done) {
|
||||
h.driver
|
||||
.resolve(setupXpath(h.driver))
|
||||
.elementsByXPath("cell//button").then(function(els) {
|
||||
return Q.all( _(els).map(function(el) { return el.text(); }) );
|
||||
}).then(function(texts) {
|
||||
it('should search an extended path by descendant', function (done) {
|
||||
driver
|
||||
.resolve(setupXpath(driver))
|
||||
.elementsByXPath("cell//button").then(function (els) {
|
||||
return Q.all(_(els).map(function (el) { return el.text(); }));
|
||||
}).then(function (texts) {
|
||||
texts.should.not.include("Button");
|
||||
texts.should.include("Gray");
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should filter by indices', function(done) {
|
||||
h.driver
|
||||
.resolve(setupXpath(h.driver))
|
||||
.then(function() {
|
||||
return spinWait(function() {
|
||||
return h.driver
|
||||
it('should filter by indices @skip-ios7', function (done) {
|
||||
driver
|
||||
.resolve(setupXpath(driver))
|
||||
.then(function () {
|
||||
return spinWait(function () {
|
||||
return driver
|
||||
.elementByXPath("cell[2]//text[1]").text()
|
||||
.should.become("ButtonsViewController.m:\r(UIButton *)grayButton");
|
||||
});
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should filter by partial text', function(done) {
|
||||
h.driver
|
||||
.resolve(setupXpath(h.driver))
|
||||
it('should filter by partial text', function (done) {
|
||||
driver
|
||||
.resolve(setupXpath(driver))
|
||||
.elementByXPath("cell//button[contains(@name, 'Gr')]").text()
|
||||
.should.become("Gray")
|
||||
.nodeify(done);
|
||||
|
||||
@@ -1,93 +1,103 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('UICatalog')
|
||||
, it = require("../../helpers/driverblock.js").it
|
||||
var env = require('../../helpers/env')
|
||||
, setup = require("../common/setup-base")
|
||||
, desired = require('./desired')
|
||||
, spinWait = require('../../helpers/spin.js').spinWait
|
||||
, textBlock = "Now is the time for all good developers to come to serve their country.\n\nNow is the time for all good developers to come to serve their country.\n\nThis text view can also use attributed strings.";
|
||||
, textBlock = "Now is the time for all good developers to come to serve their country.\n";
|
||||
|
||||
var SLOW_DOWN_MS = 250;
|
||||
// sebv: had to cut down original textBlock, cause text retrieved depends on device size
|
||||
// textBlock = "Now is the time for all good developers to come to serve their country.\n\nNow is the time for all good developers to come to serve their country.\n\nThis text view can also use attributed strings.";
|
||||
|
||||
describeWd('gesture', function(h) {
|
||||
describe('flick', function() {
|
||||
var SLOW_DOWN_MS = 1000;
|
||||
|
||||
if (process.env.FAST_TESTS) {
|
||||
afterEach(function(done) {
|
||||
h.driver
|
||||
describe('uicatalog - gestures -', function () {
|
||||
|
||||
describe('flick @skip-ios7', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
if (env.FAST_TESTS) {
|
||||
afterEach(function (done) {
|
||||
driver
|
||||
.flick(0, 100, false)
|
||||
.flick(0, 100, false)
|
||||
.sleep(SLOW_DOWN_MS)
|
||||
.nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should work via webdriver method', function(done) {
|
||||
h.driver
|
||||
it('should work via webdriver method', function (done) {
|
||||
driver
|
||||
.elementByTagName('tableCell').getLocation()
|
||||
.then(function(location1) {
|
||||
return h.driver
|
||||
.then(function (location1) {
|
||||
return driver
|
||||
.flick(0, -100, false)
|
||||
.elementByTagName('tableCell').getLocation()
|
||||
.then(function(location2) {
|
||||
.then(function (location2) {
|
||||
location2.x.should.equal(location1.x);
|
||||
location2.y.should.not.equal(location1.y);
|
||||
});
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should work via mobile only method', function(done) {
|
||||
h.driver
|
||||
it('should work via mobile only method', function (done) {
|
||||
driver
|
||||
.elementByTagName('tableCell').getLocation()
|
||||
.then(function(location1) {
|
||||
return h.driver
|
||||
.then(function (location1) {
|
||||
return driver
|
||||
.execute("mobile: flick", [{endX: 0, endY: 0}])
|
||||
.elementByTagName('tableCell').getLocation()
|
||||
.then(function(location2) {
|
||||
.then(function (location2) {
|
||||
location2.x.should.equal(location1.x);
|
||||
location2.y.should.not.equal(location1.y);
|
||||
});
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should not complete instantaneously', function(done) {
|
||||
it('should not complete instantaneously', function (done) {
|
||||
var start = Date.now();
|
||||
h.driver
|
||||
driver
|
||||
.execute("mobile: flick", [{endX: 0, endY: 0}])
|
||||
.then(function() { (Date.now() - start).should.be.above(2500); })
|
||||
.then(function () { (Date.now() - start).should.be.above(2500); })
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should work via mobile only method with percentage', function(done) {
|
||||
it('should work via mobile only method with percentage', function (done) {
|
||||
var opts = {startX: 0.75, startY: 0.75, endX: 0.25, endY: 0.25};
|
||||
h.driver
|
||||
driver
|
||||
.elementByTagName('tableCell').getLocation()
|
||||
.then(function(location1) {
|
||||
return h.driver
|
||||
.then(function (location1) {
|
||||
return driver
|
||||
.execute("mobile: flick", [opts])
|
||||
.elementByTagName('tableCell').getLocation()
|
||||
.then(function(location2) {
|
||||
.then(function (location2) {
|
||||
location2.x.should.equal(location1.x);
|
||||
location2.y.should.not.equal(location1.y);
|
||||
});
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
describe('swipe gesture', function() {
|
||||
describe('swipe gesture @skip-ios7', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
if (process.env.FAST_TESTS) {
|
||||
afterEach(function(done) {
|
||||
h.driver
|
||||
.flick(0, 100, false)
|
||||
if (env.FAST_TESTS) {
|
||||
afterEach(function (done) {
|
||||
driver
|
||||
.flick(0, 70, false)
|
||||
.flick(0, 70, false)
|
||||
.sleep(SLOW_DOWN_MS)
|
||||
.nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should work with wd function in pixels', function(done) {
|
||||
h.driver
|
||||
it('should work with wd function in pixels', function (done) {
|
||||
driver
|
||||
.elementByTagName('tableCell').getLocation()
|
||||
.then(function(location1) {
|
||||
return spinWait(function() {
|
||||
return h.driver
|
||||
.then(function (location1) {
|
||||
return spinWait(function () {
|
||||
return driver
|
||||
.flick(0, -70, true)
|
||||
.elementByTagName('tableCell').getLocation()
|
||||
.then(function(location2) {
|
||||
( (location2.x === location1.x) &&
|
||||
.then(function (location2) {
|
||||
((location2.x === location1.x) &&
|
||||
(location2.y !== location1.y)
|
||||
).should.be.ok;
|
||||
});
|
||||
@@ -95,311 +105,330 @@ describeWd('gesture', function(h) {
|
||||
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should work with wd function in percentage units', function(done) {
|
||||
h.driver
|
||||
it('should work with wd function in percent', function (done) {
|
||||
driver
|
||||
.elementByTagName('tableCell').getLocation()
|
||||
.then(function(location1) {
|
||||
return h.driver
|
||||
.flick(0, -0.15, true)
|
||||
.then(function (location1) {
|
||||
return driver
|
||||
.flick(0, -0.1, true) // flaky
|
||||
.flick(0, -0.1, true)
|
||||
.flick(0, -0.1, true)
|
||||
.elementByTagName('tableCell').getLocation()
|
||||
.then(function(location2) {
|
||||
.then(function (location2) {
|
||||
location2.x.should.equal(location1.x);
|
||||
location2.y.should.not.equal(location1.y);
|
||||
location2.y.should.not.equal(location1.y, '===y');
|
||||
});
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should work with mobile function in pixels', function(done) {
|
||||
it('should work with mobile function in pixels', function (done) {
|
||||
var opts = {startX: 50, startY: 400, endX: 50, endY: 300, duration: 2};
|
||||
h.driver
|
||||
driver
|
||||
.elementByTagName('tableCell').getLocation()
|
||||
.then(function(location1) {
|
||||
return spinWait(function() {
|
||||
return h.driver
|
||||
.then(function (location1) {
|
||||
return spinWait(function () {
|
||||
return driver
|
||||
.execute("mobile: swipe", [opts])
|
||||
.elementByTagName('tableCell').getLocation()
|
||||
.then(function(location2) {
|
||||
.then(function (location2) {
|
||||
location2.x.should.equal(location1.x);
|
||||
location2.y.should.not.equal(location1.y);
|
||||
});
|
||||
});
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should work with mobile function in percent', function(done) {
|
||||
it('should work with mobile function in percent', function (done) {
|
||||
var opts = {startX: 0.5, startY: 0.9, endX: 0.5, endY: 0.7, duration: 2};
|
||||
h.driver
|
||||
driver
|
||||
.elementByTagName('tableCell').getLocation()
|
||||
.then(function(location1) {
|
||||
return spinWait(function() {
|
||||
return h.driver
|
||||
.then(function (location1) {
|
||||
return spinWait(function () {
|
||||
return driver
|
||||
.execute("mobile: swipe", [opts])
|
||||
.elementByTagName('tableCell').getLocation()
|
||||
.then(function(location2) {
|
||||
.then(function (location2) {
|
||||
location2.x.should.equal(location1.x);
|
||||
location2.y.should.not.equal(location1.y);
|
||||
});
|
||||
});
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should not complete instantaneously', function(done) {
|
||||
it('should not complete instantaneously', function (done) {
|
||||
var start = Date.now();
|
||||
var opts = {startX: 0.5, startY: 0.9, endX: 0.5, endY: 0.7, duration: 2};
|
||||
h.driver
|
||||
driver
|
||||
.execute("mobile: swipe", [opts])
|
||||
.then(function() {
|
||||
.then(function () {
|
||||
(Date.now() - start).should.be.above(1999);
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe("flick element", function() {
|
||||
describe("flick element @skip-ios7", function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
if (process.env.FAST_TESTS) {
|
||||
afterEach(function(done) {
|
||||
h.driver
|
||||
if (env.FAST_TESTS) {
|
||||
afterEach(function (done) {
|
||||
driver
|
||||
.elementByTagName("slider")
|
||||
.then(function(el) { if (el) return el.sendKeys(0.5); })
|
||||
.then(function (el) { if (el) return el.sendKeys(0.5); })
|
||||
.then(function (el) { if (el) return el.sendKeys(0.5); })
|
||||
.elementByNameOrNull('Back')
|
||||
.then(function(el) { if (el) return el.click(); })
|
||||
.then(function (el) { if (el) return el.click(); })
|
||||
.sleep(SLOW_DOWN_MS)
|
||||
.nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it("slider value should change", function(done) {
|
||||
it("slider value should change", function (done) {
|
||||
var valueBefore, slider;
|
||||
h.driver
|
||||
.elementsByTagName("tableCell").then(function(els) { return els[1]; })
|
||||
driver
|
||||
.elementsByTagName("tableCell").then(function (els) { return els[1]; })
|
||||
.click()
|
||||
.elementByTagName("slider").then(function(el) { slider = el; })
|
||||
.then(function() { return slider.getAttribute("value"); })
|
||||
.then(function(value) { valueBefore = value; })
|
||||
.then(function() { return slider.flick(-0.5, 0, 1); })
|
||||
.then(function() { return slider.getAttribute("value"); })
|
||||
.then(function(valueAfter) {
|
||||
valueBefore.should.equal("50%");
|
||||
.elementByTagName("slider").then(function (el) { slider = el; })
|
||||
.then(function () { return slider.getAttribute("value"); })
|
||||
.then(function (value) { valueBefore = value; })
|
||||
.then(function () { return slider.flick(-0.5, 0, 1); })
|
||||
.then(function () { return slider.getAttribute("value"); })
|
||||
.then(function (valueAfter) {
|
||||
valueBefore.should.not.equal("0%");
|
||||
valueAfter.should.equal("0%");
|
||||
}).nodeify(done);
|
||||
});
|
||||
it("should work with mobile flick", function(done) {
|
||||
it("should work with mobile flick", function (done) {
|
||||
var valueBefore, slider;
|
||||
h.driver
|
||||
.elementsByTagName("tableCell").then(function(els) { return els[1]; })
|
||||
driver
|
||||
.elementsByTagName("tableCell").then(function (els) { return els[1]; })
|
||||
.click()
|
||||
.elementByTagName("slider").then(function(el) { slider = el; })
|
||||
.then(function() { return slider.getAttribute("value"); })
|
||||
.then(function(value) { valueBefore = value; })
|
||||
.then(function() {
|
||||
.elementByTagName("slider").then(function (el) { slider = el; })
|
||||
.then(function () { return slider.getAttribute("value"); })
|
||||
.then(function (value) { valueBefore = value; })
|
||||
.then(function () {
|
||||
var opts = {element: slider.value, endX: -50, endY: 0};
|
||||
return h.driver.execute("mobile: flick", [opts]);
|
||||
return driver.execute("mobile: flick", [opts]);
|
||||
})
|
||||
.then(function() { return slider.getAttribute("value"); })
|
||||
.then(function(valueAfter) {
|
||||
valueBefore.should.equal("50%");
|
||||
.then(function () { return slider.getAttribute("value"); })
|
||||
.then(function (valueAfter) {
|
||||
valueBefore.should.not.equal("0%");
|
||||
valueAfter.should.equal("0%");
|
||||
}).nodeify(done);
|
||||
});
|
||||
it("should work with mobile flick and percent", function(done) {
|
||||
it("should work with mobile flick and percent", function (done) {
|
||||
var valueBefore, slider;
|
||||
h.driver
|
||||
.elementsByTagName("tableCell").then(function(els) { return els[1]; })
|
||||
driver
|
||||
.elementsByTagName("tableCell").then(function (els) { return els[1]; })
|
||||
.click()
|
||||
.elementByTagName("slider").then(function(el) { slider = el; })
|
||||
.then(function() { return slider.getAttribute("value"); })
|
||||
.then(function(value) { valueBefore = value; })
|
||||
.then(function() {
|
||||
.elementByTagName("slider").then(function (el) { slider = el; })
|
||||
.then(function () { return slider.getAttribute("value"); })
|
||||
.then(function (value) { valueBefore = value; })
|
||||
.then(function () {
|
||||
var opts = {element: slider.value, startX: 0.5, startY: 0.0,
|
||||
endX: 0.0, endY: 0.0};
|
||||
return h.driver.execute("mobile: flick", [opts]);
|
||||
return driver.execute("mobile: flick", [opts]);
|
||||
})
|
||||
.then(function() { return slider.getAttribute("value"); })
|
||||
.then(function(valueAfter) {
|
||||
valueBefore.should.equal("50%");
|
||||
.then(function () { return slider.getAttribute("value"); })
|
||||
.then(function (valueAfter) {
|
||||
valueBefore.should.not.equal("0%");
|
||||
valueAfter.should.equal("0%");
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
describe("swipe element", function() {
|
||||
describe("swipe element @skip-ios7", function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
if (process.env.FAST_TESTS) {
|
||||
afterEach(function(done) {
|
||||
h.driver
|
||||
if (env.FAST_TESTS) {
|
||||
afterEach(function (done) {
|
||||
driver
|
||||
.elementByTagName("slider")
|
||||
.then(function(el) { if (el) return el.sendKeys(0.5); })
|
||||
.then(function (el) { if (el) return el.sendKeys(0.5); })
|
||||
.elementByNameOrNull('Back')
|
||||
.then(function(el) { if (el) return el.click(); })
|
||||
.then(function (el) { if (el) return el.click(); })
|
||||
.sleep(SLOW_DOWN_MS)
|
||||
.nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it("slider value should change", function(done) {
|
||||
it("slider value should change", function (done) {
|
||||
var valueBefore, slider;
|
||||
h.driver
|
||||
.elementsByTagName("tableCell").then(function(els) { return els[1]; })
|
||||
driver
|
||||
.elementsByTagName("tableCell").then(function (els) { return els[1]; })
|
||||
.click()
|
||||
.elementByTagName("slider").then(function(el) { slider = el; })
|
||||
.then(function() { return slider.getAttribute("value"); })
|
||||
.then(function(value) { valueBefore = value; })
|
||||
.then(function() {
|
||||
.elementByTagName("slider").then(function (el) { slider = el; })
|
||||
.then(function () { return slider.getAttribute("value"); })
|
||||
.then(function (value) { valueBefore = value; })
|
||||
.then(function () {
|
||||
var opts = {startX: 0.5, startY: 0.5, endX: 0.25, endY: 0.5,
|
||||
duration: 0.3, element: slider.value};
|
||||
return h.driver.execute("mobile: swipe", [opts]);
|
||||
return driver.execute("mobile: swipe", [opts]);
|
||||
})
|
||||
.then(function() { return slider.getAttribute("value"); })
|
||||
.then(function(valueAfter) {
|
||||
.then(function () { return slider.getAttribute("value"); })
|
||||
.then(function (valueAfter) {
|
||||
valueBefore.should.equal("50%");
|
||||
valueAfter.should.equal("20%");
|
||||
}).nodeify(done);
|
||||
});
|
||||
it("slider value should change by pixels", function(done) {
|
||||
it("slider value should change by pixels", function (done) {
|
||||
var valueBefore, slider;
|
||||
h.driver
|
||||
.elementsByTagName("tableCell").then(function(els) { return els[1]; })
|
||||
driver
|
||||
.elementsByTagName("tableCell").then(function (els) { return els[1]; })
|
||||
.click()
|
||||
.elementByTagName("slider").then(function(el) { slider = el; })
|
||||
.then(function() { return slider.getAttribute("value"); })
|
||||
.then(function(value) { valueBefore = value; })
|
||||
.then(function() {
|
||||
.elementByTagName("slider").then(function (el) { slider = el; })
|
||||
.then(function () { return slider.getAttribute("value"); })
|
||||
.then(function (value) { valueBefore = value; })
|
||||
.then(function () {
|
||||
var opts = {endX: 15, endY: 10, duration: 0.3, element: slider.value};
|
||||
return h.driver.execute("mobile: swipe", [opts]);
|
||||
return driver.execute("mobile: swipe", [opts]);
|
||||
})
|
||||
.then(function() { return slider.getAttribute("value"); })
|
||||
.then(function(valueAfter) {
|
||||
.then(function () { return slider.getAttribute("value"); })
|
||||
.then(function (valueAfter) {
|
||||
valueBefore.should.equal("50%");
|
||||
valueAfter.should.equal("5%");
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
describe('complex tap', function() {
|
||||
if (process.env.FAST_TESTS) {
|
||||
afterEach(function(done) {
|
||||
h.driver
|
||||
describe('complex tap', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
if (env.FAST_TESTS) {
|
||||
afterEach(function (done) {
|
||||
driver
|
||||
.elementByNameOrNull('Back')
|
||||
.then(function(el) { if (el) return el.click(); })
|
||||
.then(function (el) { if (el) return el.click(); })
|
||||
.sleep(SLOW_DOWN_MS)
|
||||
.nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should work with custom options', function(done) {
|
||||
it('should work with custom options', function (done) {
|
||||
var tapOpts = {
|
||||
tapCount: 1 // how many taps
|
||||
, duration: 2.3 // how long
|
||||
, touchCount: 3 // how many fingers
|
||||
, x: 100 // in pixels from left
|
||||
, y: 250 // in pixels from top
|
||||
, duration: 2.3 // how long
|
||||
, touchCount: 3 // how many fingers
|
||||
, x: 100 // in pixels from left
|
||||
, y: 250 // in pixels from top
|
||||
};
|
||||
h.driver
|
||||
driver
|
||||
.execute("mobile: tap", [tapOpts])
|
||||
.elementByTagName("textview").text()
|
||||
.then(function(text) {
|
||||
.then(function (text) {
|
||||
text.should.include(textBlock);
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should work in relative units', function(done) {
|
||||
it('should work in relative units @skip-ios7', function (done) {
|
||||
var tapOpts = {
|
||||
tapCount: 1 // how many taps
|
||||
, duration: 2.3 // how long
|
||||
, touchCount: 3 // how many fingers
|
||||
, x: 0.5 // 50% from left of screen
|
||||
, y: 0.55 // 55% from top of screen
|
||||
, duration: 2.3 // how long
|
||||
, touchCount: 3 // how many fingers
|
||||
, x: 0.5 // 50% from left of screen
|
||||
, y: 0.55 // 55% from top of screen
|
||||
};
|
||||
h.driver
|
||||
driver
|
||||
.execute("mobile: tap", [tapOpts])
|
||||
.elementByTagName("textview").text()
|
||||
.then(function(text) {
|
||||
.then(function (text) {
|
||||
text.should.include(textBlock);
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should work with default options', function(done) {
|
||||
h.driver
|
||||
it('should work with default options @skip-ios7', function (done) {
|
||||
driver
|
||||
.execute("mobile: tap")
|
||||
.elementByTagName("textview").text()
|
||||
.then(function(text) {
|
||||
.then(function (text) {
|
||||
text.should.include(textBlock);
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
describe('complex tap on element', function() {
|
||||
if (process.env.FAST_TESTS) {
|
||||
afterEach(function(done) {
|
||||
h.driver
|
||||
describe('complex tap on element', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
if (env.FAST_TESTS) {
|
||||
afterEach(function (done) {
|
||||
driver
|
||||
.elementByNameOrNull('Back')
|
||||
.then(function(el) { if (el) return el.click(); })
|
||||
.then(function (el) { if (el) return el.click(); })
|
||||
.sleep(SLOW_DOWN_MS)
|
||||
.nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should work in relative units', function(done) {
|
||||
h.driver
|
||||
.elementsByTagName('tableCell').then(function(els) { return els[4]; })
|
||||
.then(function(el) {
|
||||
it('should work in relative units', function (done) {
|
||||
driver
|
||||
.elementsByTagName('tableCell').then(function (els) { return els[4]; })
|
||||
.then(function (el) {
|
||||
var tapOpts = {
|
||||
x: 0.5 // in relative width from left
|
||||
, y: 0.5 // in relative height from top
|
||||
, element: el.value
|
||||
, y: 0.5 // in relative height from top
|
||||
, element: el.value
|
||||
};
|
||||
return h.driver
|
||||
return driver
|
||||
.execute("mobile: tap", [tapOpts]);
|
||||
}).elementByTagName("textview").text()
|
||||
.then(function(text) {
|
||||
.then(function (text) {
|
||||
text.should.include(textBlock);
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('should work in pixels', function(done) {
|
||||
h.driver
|
||||
.elementsByTagName('tableCell').then(function(els) { return els[4]; })
|
||||
.then(function(el) {
|
||||
it('should work in pixels', function (done) {
|
||||
driver
|
||||
.elementsByTagName('tableCell').then(function (els) { return els[4]; })
|
||||
.then(function (el) {
|
||||
var tapOpts = {
|
||||
x: 150 // in pixels from left
|
||||
, y: 30 // in pixels from top
|
||||
, element: el.value
|
||||
, y: 30 // in pixels from top
|
||||
, element: el.value
|
||||
};
|
||||
return h.driver
|
||||
return driver
|
||||
.execute("mobile: tap", [tapOpts]);
|
||||
}).elementByTagName("textview").text()
|
||||
.then(function(text) {
|
||||
.then(function (text) {
|
||||
text.should.include(textBlock);
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('scroll to element', function() {
|
||||
if (process.env.FAST_TESTS) {
|
||||
afterEach(function(done) {
|
||||
h.driver
|
||||
describe('scroll to element @skip-ios7', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
if (env.FAST_TESTS) {
|
||||
afterEach(function (done) {
|
||||
driver
|
||||
.flick(0, 100, false)
|
||||
.flick(0, 100, false)
|
||||
.sleep(SLOW_DOWN_MS)
|
||||
.nodeify(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should bring the element into view', function(done) {
|
||||
it('should bring the element into view', function (done) {
|
||||
var el, scrollOpts, location1;
|
||||
h.driver.elementsByTagName('tableCell').then(function(els) {
|
||||
driver.elementsByTagName('tableCell').then(function (els) {
|
||||
el = els[10];
|
||||
scrollOpts = { element: el.value };
|
||||
})
|
||||
.then(function() { return el.getLocation(); })
|
||||
.then(function(loc) { location1 = loc; })
|
||||
.then(function() {
|
||||
return h.driver.execute("mobile: scrollTo", [scrollOpts]); })
|
||||
.then(function() { return el.getLocation(); })
|
||||
.then(function(location2) {
|
||||
.then(function () { return el.getLocation(); })
|
||||
.then(function (loc) { location1 = loc; })
|
||||
.then(function () {
|
||||
return driver.execute("mobile: scrollTo", [scrollOpts]);
|
||||
}).then(function () { return el.getLocation(); })
|
||||
.then(function (location2) {
|
||||
location2.x.should.equal(location1.x);
|
||||
location2.y.should.not.equal(location1.y);
|
||||
}).nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mobile shake', function() {
|
||||
describe('mobile shake', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should not error', function(done) {
|
||||
h.driver.execute('mobile: shake')
|
||||
it('should not error', function (done) {
|
||||
driver.execute('mobile: shake')
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('UICatalog')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base"),
|
||||
desired = require('./desired');
|
||||
|
||||
describeWd('moveTo and click', function(h) {
|
||||
it('should be able to click on arbitrary x-y elements', function(done) {
|
||||
h.driver
|
||||
.elementByTagName('tableCell').moveTo(10, 10).click()
|
||||
.elementByXPath("button[@name='Rounded']")
|
||||
.should.eventually.exist
|
||||
.nodeify(done);
|
||||
describe('uicatalog - move -', function () {
|
||||
|
||||
describe('moveTo and click', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('should be able to click on arbitrary x-y elements', function (done) {
|
||||
driver
|
||||
.elementByTagName('tableCell').moveTo(10, 10).click()
|
||||
.elementByXPath("button[@name='Rounded']")
|
||||
.should.eventually.exist
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('UICatalog')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base"),
|
||||
desired = require('./desired');
|
||||
|
||||
describeWd('app reset', function(h) {
|
||||
it("should be able to find elements after a soft reset", function(done) {
|
||||
h.driver
|
||||
.elementsByTagName('tableView')
|
||||
.should.eventually.have.length(1)
|
||||
.execute("mobile: reset")
|
||||
.elementsByTagName('tableView')
|
||||
.should.eventually.have.length(1)
|
||||
.nodeify(done);
|
||||
describe('uicatalog - reset -', function () {
|
||||
|
||||
describe('app reset', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it("should be able to find elements after a soft reset", function (done) {
|
||||
driver
|
||||
.elementsByTagName('tableView')
|
||||
.should.eventually.have.length(1)
|
||||
.execute("mobile: reset")
|
||||
.sleep(3000)
|
||||
.elementsByTagName('tableView')
|
||||
.should.eventually.have.length(1)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('UICatalog')
|
||||
, it = require("../../helpers/driverblock.js").it;
|
||||
var setup = require("../common/setup-base"),
|
||||
desired = require('./desired');
|
||||
|
||||
describeWd('window handles', function(h) {
|
||||
it('getting handles should do nothing when no webview open', function(done) {
|
||||
h.driver
|
||||
.windowHandles().should.eventually.have.length(0)
|
||||
.nodeify(done);
|
||||
describe('uicatalog - reset -', function () {
|
||||
|
||||
describe('window handles', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('getting handles should do nothing when no webview open', function (done) {
|
||||
driver
|
||||
.windowHandles().should.eventually.have.length(0)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
7
test/functional/webview/desired.js
Normal file
7
test/functional/webview/desired.js
Normal file
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
var appUtils = require('../../helpers/app-utils');
|
||||
|
||||
module.exports = {
|
||||
app: appUtils.getAppPath('WebViewApp')
|
||||
};
|
||||
@@ -1,17 +1,20 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('WebViewApp')
|
||||
, it = require("../../helpers/driverblock.js").it
|
||||
var setup = require("../common/setup-base")
|
||||
, desired = require('./desired')
|
||||
, _ = require('underscore');
|
||||
|
||||
describeWd('orientation', function(h) {
|
||||
var testOrientation = function(specOrientation) {
|
||||
it('should get and set - ' + specOrientation, function(done) {
|
||||
h.driver
|
||||
describe('webview - orientation -', function () {
|
||||
var driver;
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
var testOrientation = function (specOrientation) {
|
||||
it('should get and set - ' + specOrientation, function (done) {
|
||||
driver
|
||||
.setOrientation(specOrientation)
|
||||
.getOrientation().should.become(specOrientation)
|
||||
.nodeify(done);
|
||||
});
|
||||
};
|
||||
_.each(["LANDSCAPE", "PORTRAIT"], testOrientation);
|
||||
});
|
||||
};
|
||||
_.each(["LANDSCAPE", "PORTRAIT"], testOrientation);
|
||||
});
|
||||
|
||||
@@ -1,52 +1,59 @@
|
||||
"use strict";
|
||||
|
||||
var describeWd = require("../../helpers/driverblock.js").describeForApp('WebViewApp')
|
||||
, it = require("../../helpers/driverblock.js").it
|
||||
var setup = require("../common/setup-base")
|
||||
, desired = require('./desired')
|
||||
, _ = require('underscore');
|
||||
|
||||
describeWd('window handles', function(h) {
|
||||
it('getting current window should do nothing when none set', function(done) {
|
||||
h.driver.windowHandle().should.be.rejectedWith(/status: 23/)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('getting list should work after webview open', function(done) {
|
||||
h.driver.windowHandles().should.eventually.have.length.above(0)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('getting list twice should not crash appium', function(done) {
|
||||
h.driver
|
||||
.windowHandles().should.eventually.have.length.above(0)
|
||||
.windowHandles().should.eventually.have.length.above(0)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('window handles should be strings', function(done) {
|
||||
h.driver.windowHandles().then(function(handles) {
|
||||
handles.length.should.be.above(0);
|
||||
_.each(handles, function(handle) {
|
||||
(typeof handle).should.equal("string");
|
||||
});
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('setting window should work', function(done) {
|
||||
h.driver.windowHandles().then(function(handles) {
|
||||
handles.length.should.be.above(0);
|
||||
return handles[0];
|
||||
}).then(function(handle) {
|
||||
return h.driver.window(handle);
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('clearing window should work', function(done) {
|
||||
h.driver.windowHandles().then(function(handles) {
|
||||
handles.length.should.be.above(0);
|
||||
return handles[0];
|
||||
}).then(function(handle) {
|
||||
return h.driver.window(handle);
|
||||
}).execute("mobile: leaveWebView")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('clearing window should not work if not in webview', function(done) {
|
||||
h.driver
|
||||
.execute("mobile: leaveWebView").should.be.rejectedWith(/status: 8/)
|
||||
describe('webview - webview -', function () {
|
||||
|
||||
describe('window handles', function () {
|
||||
var driver;
|
||||
|
||||
setup(this, desired).then(function (d) { driver = d; });
|
||||
|
||||
it('getting current window should do nothing when none set', function (done) {
|
||||
driver.windowHandle().should.be.rejectedWith(/status: 23/)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('getting list should work after webview open', function (done) {
|
||||
driver.windowHandles().should.eventually.have.length.above(0)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('getting list twice should not crash appium', function (done) {
|
||||
driver
|
||||
.windowHandles().should.eventually.have.length.above(0)
|
||||
.windowHandles().should.eventually.have.length.above(0)
|
||||
.nodeify(done);
|
||||
});
|
||||
it('window handles should be strings', function (done) {
|
||||
driver.windowHandles().then(function (handles) {
|
||||
handles.length.should.be.above(0);
|
||||
_.each(handles, function (handle) {
|
||||
(typeof handle).should.equal("string");
|
||||
});
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('setting window should work', function (done) {
|
||||
driver.windowHandles().then(function (handles) {
|
||||
handles.length.should.be.above(0);
|
||||
return handles[0];
|
||||
}).then(function (handle) {
|
||||
return driver.window(handle);
|
||||
}).nodeify(done);
|
||||
});
|
||||
it('clearing window should work', function (done) {
|
||||
driver.windowHandles().then(function (handles) {
|
||||
handles.length.should.be.above(0);
|
||||
return handles[0];
|
||||
}).then(function (handle) {
|
||||
return driver.window(handle);
|
||||
}).execute("mobile: leaveWebView")
|
||||
.nodeify(done);
|
||||
});
|
||||
it('clearing window should not work if not in webview', function (done) {
|
||||
driver
|
||||
.execute("mobile: leaveWebView").should.be.rejectedWith(/status: 8/)
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/*jshint esnext: true*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var wd = require('yiewd')
|
||||
@@ -9,14 +11,14 @@ var wd = require('yiewd')
|
||||
, defaultHost = '127.0.0.1'
|
||||
, defaultPort = process.env.APPIUM_PORT || 4723
|
||||
, defaultCaps = {
|
||||
browserName: ''
|
||||
, device: 'iPhone Simulator'
|
||||
, platform: 'Mac'
|
||||
, version: '6.0'
|
||||
//, newCommandTimeout: 60
|
||||
};
|
||||
browserName: ''
|
||||
, device: 'iPhone Simulator'
|
||||
, platform: 'Mac'
|
||||
, version: '6.0'
|
||||
//, newCommandTimeout: 60
|
||||
};
|
||||
|
||||
var driverBlock = function(tests, host, port, caps, extraCaps) {
|
||||
var driverBlock = function (tests, host, port, caps, extraCaps) {
|
||||
host = (typeof host === "undefined" || host === null) ? _.clone(defaultHost) : host;
|
||||
port = (typeof port === "undefined" || port === null) ? _.clone(defaultPort) : port;
|
||||
caps = (typeof caps === "undefined" || caps === null) ? _.clone(defaultCaps) : caps;
|
||||
@@ -24,13 +26,13 @@ var driverBlock = function(tests, host, port, caps, extraCaps) {
|
||||
var driverHolder = {driver: null, sessionId: null};
|
||||
var expectConnError = extraCaps && extraCaps.expectConnError;
|
||||
|
||||
beforeEach(function(done) {
|
||||
beforeEach(function (done) {
|
||||
driverHolder.driver = wd.remote(host, port);
|
||||
_.each(['Name', 'TagName', 'XPath', 'Css', 'Id'], function(strat) {
|
||||
_.each(['Name', 'TagName', 'XPath', 'Css', 'Id'], function (strat) {
|
||||
driverHolder.driver['by' + strat] = driverHolder.driver['elementBy' + strat];
|
||||
driverHolder.driver['by' + strat + 's'] = driverHolder.driver['elementsBy' + strat];
|
||||
});
|
||||
run(function*() {
|
||||
run(function* () {
|
||||
try {
|
||||
driverHolder.sessionId = yield driverHolder.driver.init(caps);
|
||||
} catch (err) {
|
||||
@@ -44,12 +46,12 @@ var driverBlock = function(tests, host, port, caps, extraCaps) {
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function(done) {
|
||||
run(function*() {
|
||||
afterEach(function (done) {
|
||||
run(function* () {
|
||||
try {
|
||||
yield driverHolder.driver.quit();
|
||||
} catch (err) {
|
||||
if (err && err.status && err.status.code != 6) {
|
||||
if (err && err.status && err.status.code !== 6) {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
@@ -60,14 +62,14 @@ var driverBlock = function(tests, host, port, caps, extraCaps) {
|
||||
tests(driverHolder);
|
||||
};
|
||||
|
||||
var describeWithDriver = function(desc, tests, host, port, caps, extraCaps, timeout, onlyify) {
|
||||
var describeWithDriver = function (desc, tests, host, port, caps, extraCaps, timeout, onlyify) {
|
||||
var descFn;
|
||||
if (onlyify) {
|
||||
descFn = describe.only;
|
||||
} else {
|
||||
descFn = describe;
|
||||
}
|
||||
descFn(desc, function() {
|
||||
descFn(desc, function () {
|
||||
if (typeof timeout !== "undefined") {
|
||||
this.timeout(timeout);
|
||||
}
|
||||
@@ -75,46 +77,46 @@ var describeWithDriver = function(desc, tests, host, port, caps, extraCaps, time
|
||||
});
|
||||
};
|
||||
|
||||
var describeForSafari = function() {
|
||||
var fn = function(desc, tests, host, port, extraCaps, onlyify) {
|
||||
var describeForSafari = function () {
|
||||
var fn = function (desc, tests, host, port, extraCaps, onlyify) {
|
||||
var caps = {
|
||||
browserName: 'Safari'
|
||||
, app: 'safari'
|
||||
, device: 'iPhone Simulator'
|
||||
, platform: 'Mac'
|
||||
, version: '6.1'
|
||||
, app: 'safari'
|
||||
, device: 'iPhone Simulator'
|
||||
, platform: 'Mac'
|
||||
, version: '6.1'
|
||||
};
|
||||
return describeWithDriver(desc, tests, host, port, caps, extraCaps, undefined, onlyify);
|
||||
};
|
||||
fn.only = function() {
|
||||
fn.only = function () {
|
||||
var a = arguments;
|
||||
return fn(a[0], a[1], a[2], a[3], a[4], true);
|
||||
};
|
||||
return fn;
|
||||
};
|
||||
describeForSafari.only = function() {
|
||||
describeForSafari.only = function () {
|
||||
return describeForSafari(true);
|
||||
};
|
||||
|
||||
var describeForChrome = function() {
|
||||
var fn = function(desc, tests, host, port, extraCaps, onlyify) {
|
||||
var describeForChrome = function () {
|
||||
var fn = function (desc, tests, host, port, extraCaps, onlyify) {
|
||||
var caps = {
|
||||
app: 'chrome'
|
||||
, device: 'Android'
|
||||
, device: 'Android'
|
||||
};
|
||||
return describeWithDriver(desc, tests, host, port, caps, extraCaps, undefined, onlyify);
|
||||
};
|
||||
fn.only = function() {
|
||||
fn.only = function () {
|
||||
var a = arguments;
|
||||
return fn(a[0], a[1], a[2], a[3], a[4], true);
|
||||
};
|
||||
return fn;
|
||||
};
|
||||
describeForChrome.only = function() {
|
||||
describeForChrome.only = function () {
|
||||
return describeForChrome(true);
|
||||
};
|
||||
|
||||
var describeForApp = function(app, device, appPackage, appActivity, appWaitActivity) {
|
||||
var describeForApp = function (app, device, appPackage, appActivity, appWaitActivity) {
|
||||
if (typeof device === "undefined") {
|
||||
device = "ios";
|
||||
}
|
||||
@@ -141,7 +143,7 @@ var describeForApp = function(app, device, appPackage, appActivity, appWaitActiv
|
||||
}
|
||||
}
|
||||
|
||||
return function(desc, tests, host, port, caps, extraCaps) {
|
||||
return function (desc, tests, host, port, caps, extraCaps) {
|
||||
if (typeof extraCaps === "undefined") {
|
||||
extraCaps = {};
|
||||
}
|
||||
@@ -162,8 +164,8 @@ var describeForApp = function(app, device, appPackage, appActivity, appWaitActiv
|
||||
};
|
||||
};
|
||||
|
||||
var describeForSauce = function(appUrl, device) {
|
||||
return function(desc, tests, extraCaps, host, port) {
|
||||
var describeForSauce = function (appUrl, device) {
|
||||
return function (desc, tests, extraCaps, host, port) {
|
||||
device = device || 'iPhone Simulator';
|
||||
host = host || 'ondemand.saucelabs.com';
|
||||
port = port || 80;
|
||||
@@ -174,9 +176,9 @@ var describeForSauce = function(appUrl, device) {
|
||||
'@' + host;
|
||||
var caps = {
|
||||
device: device
|
||||
, browserName: ""
|
||||
, app: appUrl
|
||||
, version: ""
|
||||
, browserName: ""
|
||||
, app: appUrl
|
||||
, version: ""
|
||||
};
|
||||
if (device.toLowerCase().indexOf('android') !== -1) {
|
||||
caps.platform = "LINUX";
|
||||
@@ -189,10 +191,10 @@ var describeForSauce = function(appUrl, device) {
|
||||
};
|
||||
};
|
||||
|
||||
var driverIt = function(desc, gen) {
|
||||
var driverIt = function (desc, gen) {
|
||||
gen = o_O(gen);
|
||||
it(desc, function(done) {
|
||||
run(function*() {
|
||||
it(desc, function (done) {
|
||||
run(function* () {
|
||||
try {
|
||||
yield gen();
|
||||
done();
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
/*jshint esnext: true*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var driverBlock = require('../helpers/driverblock_harmony.js')
|
||||
, describe = driverBlock.describeForApp('UICatalog')
|
||||
, it = driverBlock.it
|
||||
, chai = require('chai')
|
||||
, should = chai.should();
|
||||
, it = driverBlock.it;
|
||||
|
||||
describe('basic', function(h) {
|
||||
describe('basic', function (h) {
|
||||
|
||||
it('should confirm element is not visible', function*() {
|
||||
it('should confirm element is not visible', function* () {
|
||||
yield (yield h.driver.byTagName('tableCell')).click();
|
||||
var el = yield h.driver.byName("UIButtonTypeContactAdd");
|
||||
(yield el.displayed()).should.equal(false);
|
||||
});
|
||||
|
||||
it('should confirm element is visible', function*() {
|
||||
it('should confirm element is visible', function* () {
|
||||
yield (yield h.driver.byTagName('tableCell')).click();
|
||||
var el = yield h.driver.byName("UIButtonTypeRoundedRect");
|
||||
(yield el.displayed()).should.equal(true);
|
||||
});
|
||||
|
||||
it('should confirm element is selected', function*() {
|
||||
it('should confirm element is selected', function* () {
|
||||
yield (yield h.driver.byXPath("text[contains(@text, 'Picker')]")).click();
|
||||
var el = yield h.driver.byXPath("button[contains(@text, 'UIPicker')]");
|
||||
(yield el.selected()).should.equal(true);
|
||||
});
|
||||
|
||||
it('should confirm element is not selected returns false', function*() {
|
||||
it('should confirm element is not selected returns false', function* () {
|
||||
yield (yield h.driver.byXPath("text[contains(@text, 'Picker')]")).click();
|
||||
var el = yield h.driver.byXPath("button[contains(@text, 'Custom')]");
|
||||
(yield el.selected()).should.equal(false);
|
||||
|
||||
12
test/helpers/alert-utils.js
Normal file
12
test/helpers/alert-utils.js
Normal file
@@ -0,0 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
exports.okIfAlert = function (driver) {
|
||||
return driver
|
||||
.alertText()
|
||||
.then(function (text) {
|
||||
if (text) {
|
||||
return driver.acceptAlert();
|
||||
}
|
||||
})
|
||||
.catch(function () {});
|
||||
};
|
||||
17
test/helpers/app-utils.js
Normal file
17
test/helpers/app-utils.js
Normal file
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
|
||||
var env = require('./env'),
|
||||
path = require('path');
|
||||
|
||||
module.exports.getAppPath = function (app) {
|
||||
if (env.IOS) {
|
||||
return path.resolve(__dirname, "../../sample-code/apps/" + app +
|
||||
"/build/Release-iphonesimulator/" + app + ".app");
|
||||
}
|
||||
if (env.ANDROID) {
|
||||
return path.resolve(__dirname, "../../sample-code/apps/" + app +
|
||||
"/bin/" + app + "-debug.apk");
|
||||
}
|
||||
return app;
|
||||
};
|
||||
|
||||
@@ -1,273 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var wd = require('wd')
|
||||
, _ = require("underscore")
|
||||
, path = require("path")
|
||||
, defaultHost = '127.0.0.1'
|
||||
, defaultPort = process.env.APPIUM_PORT || 4723
|
||||
, domain = require('domain')
|
||||
, defaultCaps = {
|
||||
browserName: ''
|
||||
, device: 'iPhone Simulator'
|
||||
, platform: 'Mac'
|
||||
};
|
||||
|
||||
var chai = require('chai')
|
||||
, chaiAsPromised = require('chai-as-promised');
|
||||
chai.use(chaiAsPromised);
|
||||
chai.should();
|
||||
chaiAsPromised.transferPromiseness = wd.transferPromiseness;
|
||||
require("colors");
|
||||
|
||||
var driverBlock = function(tests, host, port, caps, extraCaps) {
|
||||
host = (typeof host === "undefined" || host === null) ? _.clone(defaultHost) : host;
|
||||
var onSauce = host.indexOf("saucelabs") !== -1 && process.env.SAUCE_ACCESS_KEY &&
|
||||
process.env.SAUCE_USERNAME;
|
||||
port = (typeof port === "undefined" || port === null) ? _.clone(defaultPort) : port;
|
||||
caps = (typeof caps === "undefined" || caps === null) ? _.clone(defaultCaps) : caps;
|
||||
caps = _.extend(caps, typeof extraCaps === "undefined" ? {} : extraCaps);
|
||||
caps.launchTimeout = parseInt(process.env.LAUNCH_TIMEOUT || 15000, 10);
|
||||
var driverHolder = {driver: null, sessionId: null};
|
||||
var expectConnError = ((caps && caps.expectConnError) ||
|
||||
(extraCaps && extraCaps.expectConnError));
|
||||
|
||||
var _before = beforeEach;
|
||||
var _after = afterEach;
|
||||
if (process.env.FAST_TESTS) {
|
||||
_before = before;
|
||||
_after = after;
|
||||
}
|
||||
|
||||
_before(function(done) {
|
||||
if (onSauce && this.currentTest) {
|
||||
caps.name = this.currentTest.parent.title + " " + this.currentTest.title;
|
||||
}
|
||||
|
||||
driverHolder.driver = wd.promiseChainRemote(host, port);
|
||||
|
||||
if (process.env.VERBOSE) {
|
||||
driverHolder.driver.on('status', function(info) {
|
||||
console.log(info);
|
||||
});
|
||||
driverHolder.driver.on('command', function(meth, path, data) {
|
||||
console.log(' > ' + meth, path, data || '');
|
||||
});
|
||||
}
|
||||
|
||||
driverHolder.driver
|
||||
.init(caps)
|
||||
.then(
|
||||
// ok
|
||||
function(sessionId) {
|
||||
driverHolder.sessionId = sessionId;
|
||||
return driverHolder.driver.setImplicitWaitTimeout(5000);
|
||||
},
|
||||
// error
|
||||
function(err) {
|
||||
if (expectConnError && err) {
|
||||
driverHolder.connError = err;
|
||||
// ignore error
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
)
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
_after(function(done) {
|
||||
var passed = false;
|
||||
if (this.currentTest) {
|
||||
passed = this.currentTest.state = 'passed';
|
||||
}
|
||||
driverHolder.driver
|
||||
.quit()
|
||||
.catch(function() {
|
||||
if (!expectConnError) {
|
||||
console.warn("didn't quit cleanly.");
|
||||
}
|
||||
})
|
||||
.then( function() {
|
||||
if (onSauce) return driverHolder.driver.sauceJobStatus(passed);
|
||||
})
|
||||
.catch(function() { console.warn("didn't manange to set sauce status."); })
|
||||
.sleep(2000)
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
tests(driverHolder);
|
||||
};
|
||||
|
||||
var describeWithDriver = function(desc, tests, host, port, caps, extraCaps, timeout, onlyify) {
|
||||
var descFn;
|
||||
if (onlyify) {
|
||||
descFn = describe.only;
|
||||
} else {
|
||||
descFn = describe;
|
||||
}
|
||||
descFn(desc, function() {
|
||||
if (typeof timeout !== "undefined") {
|
||||
this.timeout(timeout);
|
||||
}
|
||||
driverBlock(tests, host, port, caps, extraCaps, onlyify);
|
||||
});
|
||||
};
|
||||
|
||||
var describeForSafari = function() {
|
||||
var fn = function(desc, tests, host, port, extraCaps, onlyify) {
|
||||
var caps = {
|
||||
browserName: 'Safari'
|
||||
, app: 'safari'
|
||||
, device: 'iPhone Simulator'
|
||||
};
|
||||
return describeWithDriver(desc, tests, host, port, caps, extraCaps, undefined, onlyify);
|
||||
};
|
||||
fn.only = function() {
|
||||
var a = arguments;
|
||||
return fn(a[0], a[1], a[2], a[3], a[4], true);
|
||||
};
|
||||
return fn;
|
||||
};
|
||||
describeForSafari.only = function() {
|
||||
return describeForSafari(true);
|
||||
};
|
||||
|
||||
var describeForSettings = function(desc, tests, host, port, extraCaps) {
|
||||
var caps = {
|
||||
app: 'settings'
|
||||
, device: 'iPhone Simulator'
|
||||
};
|
||||
return describeWithDriver(desc, tests, host, port, caps, extraCaps);
|
||||
};
|
||||
|
||||
var describeForIWebView = function() {
|
||||
var fn = function(desc, tests, host, port, extraCaps, onlyify) {
|
||||
var caps = {
|
||||
browserName: ''
|
||||
, app: 'iwebview'
|
||||
, device: 'iPhone Simulator'
|
||||
};
|
||||
return describeWithDriver(desc, tests, host, port, caps, extraCaps, undefined, onlyify);
|
||||
};
|
||||
fn.only = function() {
|
||||
var a = arguments;
|
||||
return fn(a[0], a[1], a[2], a[3], a[4], true);
|
||||
};
|
||||
return fn;
|
||||
};
|
||||
|
||||
var describeForChrome = function() {
|
||||
var fn = function(desc, tests, host, port, extraCaps, onlyify) {
|
||||
var caps = {
|
||||
app: 'chrome'
|
||||
, device: 'Android'
|
||||
};
|
||||
return describeWithDriver(desc, tests, host, port, caps, extraCaps, undefined, onlyify);
|
||||
};
|
||||
fn.only = function() {
|
||||
var a = arguments;
|
||||
return fn(a[0], a[1], a[2], a[3], a[4], true);
|
||||
};
|
||||
return fn;
|
||||
};
|
||||
describeForChrome.only = function() {
|
||||
return describeForChrome(true);
|
||||
};
|
||||
|
||||
var describeForApp = function(app, device, appPackage, appActivity, appWaitActivity) {
|
||||
if (typeof device === "undefined") {
|
||||
device = "ios";
|
||||
}
|
||||
var browserName, appPath, realDevice;
|
||||
if (device === "ios") {
|
||||
realDevice = "iPhone Simulator";
|
||||
browserName = "iOS";
|
||||
} else if (device === "android") {
|
||||
browserName = realDevice = "Android";
|
||||
} else if (device === "selendroid") {
|
||||
browserName = realDevice = "Selendroid";
|
||||
} else if (device === "firefox" || device === "firefoxos") {
|
||||
browserName = realDevice = "Firefox";
|
||||
}
|
||||
if (/\//.exec(app) || /\./.exec(app)) {
|
||||
appPath = app;
|
||||
} else {
|
||||
if (device === "ios") {
|
||||
appPath = path.resolve(__dirname, "../../sample-code/apps/" + app + "/build/Release-iphonesimulator/" + app + ".app");
|
||||
} else if (device === "android" || device === "selendroid") {
|
||||
appPath = path.resolve(__dirname, "../../sample-code/apps/" + app + "/bin/" + app + "-debug.apk");
|
||||
} else {
|
||||
appPath = app;
|
||||
}
|
||||
}
|
||||
|
||||
return function(desc, tests, host, port, caps, extraCaps) {
|
||||
if (typeof extraCaps === "undefined") {
|
||||
extraCaps = {};
|
||||
}
|
||||
var newExtraCaps = {
|
||||
app: appPath,
|
||||
browserName: browserName,
|
||||
device: realDevice
|
||||
};
|
||||
if (typeof appPackage !== "undefined") {
|
||||
newExtraCaps['app-package'] = appPackage;
|
||||
newExtraCaps['app-activity'] = appActivity;
|
||||
if (typeof appWaitActivity !== "undefined") {
|
||||
newExtraCaps['app-wait-activity'] = appWaitActivity;
|
||||
}
|
||||
}
|
||||
extraCaps = _.extend(extraCaps, newExtraCaps);
|
||||
return describeWithDriver(desc, tests, host, port, caps, extraCaps);
|
||||
};
|
||||
};
|
||||
|
||||
var describeForSauce = function(appUrl, device) {
|
||||
return function(desc, tests, extraCaps, host, port) {
|
||||
device = device || 'iPhone Simulator';
|
||||
if (typeof process.env.SAUCE_USERNAME === "undefined" || typeof process.env.SAUCE_ACCESS_KEY === "undefined") {
|
||||
throw new Error("Need to set SAUCE_USERNAME and SAUCE_ACCESS_KEY");
|
||||
}
|
||||
host = host || 'http://' + process.env.SAUCE_USERNAME + ':' +
|
||||
process.env.SAUCE_ACCESS_KEY + '@ondemand.saucelabs.com' +
|
||||
':80/wd/hub';
|
||||
port = undefined;
|
||||
var caps = {
|
||||
device: device
|
||||
, browserName: ""
|
||||
, app: appUrl
|
||||
};
|
||||
if (caps.device.toLowerCase().indexOf('android') !== -1) {
|
||||
caps.platform = "LINUX";
|
||||
caps.version = "4.2";
|
||||
} else {
|
||||
caps.version = caps.version || "6.1";
|
||||
caps.platform = caps.platform || "Mac 10.8";
|
||||
}
|
||||
|
||||
return describeWithDriver(desc, tests, host, port, caps, extraCaps, 500000);
|
||||
};
|
||||
};
|
||||
|
||||
module.exports.it = function(behavior, test) {
|
||||
it(behavior, function(done) {
|
||||
var d = domain.create();
|
||||
d.on('error', function(err) {
|
||||
done(err);
|
||||
});
|
||||
d.run(function() {
|
||||
test(done);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
module.exports.block = driverBlock;
|
||||
module.exports.describe = describeWithDriver;
|
||||
module.exports.describeForApp = describeForApp;
|
||||
module.exports.describeForSauce = describeForSauce;
|
||||
module.exports.describeForSafari = describeForSafari;
|
||||
module.exports.describeForSettings = describeForSettings;
|
||||
module.exports.describeForIWebView = describeForIWebView;
|
||||
module.exports.describeForChrome = describeForChrome;
|
||||
module.exports.Q = wd.Q;
|
||||
109
test/helpers/env.js
Normal file
109
test/helpers/env.js
Normal file
@@ -0,0 +1,109 @@
|
||||
"use strict";
|
||||
|
||||
var path = require('path');
|
||||
|
||||
var env = {};
|
||||
|
||||
// local config
|
||||
env.APPIUM_HOST = process.env.APPIUM_HOST || '127.0.0.1';
|
||||
env.APPIUM_PORT = parseInt(process.env.APPIUM_PORT || 4723, 10);
|
||||
env.MOCHA_TIMEOUT = parseInt(process.env.MOCHA_TIMEOUT || 180000, 10);
|
||||
|
||||
// sauce
|
||||
env.SAUCE = process.env.SAUCE;
|
||||
if (env.SAUCE) {
|
||||
env.APPIUM_HOST = process.env.APPIUM_HOST || 'ondemand.saucelabs.com';
|
||||
env.APPIUM_PORT = parseInt(process.env.APPIUM_PORT || 80, 10);
|
||||
if (typeof process.env.SAUCE_USERNAME === "undefined" || typeof process.env.SAUCE_ACCESS_KEY === "undefined") {
|
||||
throw new Error("Need to set SAUCE_USERNAME and SAUCE_ACCESS_KEY");
|
||||
}
|
||||
env.APPIUM_USERNAME = process.env.SAUCE_USERNAME;
|
||||
env.APPIUM_PASSWORD = process.env.SAUCE_ACCESS_KEY;
|
||||
env.MOCHA_TIMEOUT = parseInt(process.env.MOCHA_TIMEOUT || 500000, 10);
|
||||
}
|
||||
|
||||
env.LAUNCH_TIMEOUT = parseInt(process.env.LAUNCH_TIMEOUT || 15000, 10);
|
||||
env.VERBOSE = process.env.VERBOSE;
|
||||
env.ISOLATED_TESTS = process.env.ISOLATED_TESTS;
|
||||
env.FAST_TESTS = !env.ISOLATED_TESTS;
|
||||
|
||||
// real device or emulator
|
||||
env.REAL_DEVICE = process.env.REAL_DEVICE;
|
||||
env.EMU = !env.REAL_DEVICE;
|
||||
|
||||
// device selection
|
||||
env.DEVICE = (process.env.DEVICE || 'ios').toLowerCase();
|
||||
|
||||
function iphoneOrIpadSimulator(device) {
|
||||
return device.match(/ipad/i) ? 'iPad Simulator' : 'iPhone Simulator';
|
||||
}
|
||||
|
||||
switch (env.DEVICE) {
|
||||
case 'ios':
|
||||
case 'ios6':
|
||||
case 'ios6_iphone':
|
||||
case 'ios6_ipad':
|
||||
env.CAPS = {
|
||||
browserName: ''
|
||||
, device: iphoneOrIpadSimulator(env.DEVICE),
|
||||
app: path.resolve(__dirname, "../../sample-code/apps/" + process.env.APP +
|
||||
"/build/Release-iphonesimulator/" + process.env.APP + ".app")
|
||||
};
|
||||
break;
|
||||
case 'ios7':
|
||||
case 'ios7_iphone':
|
||||
case 'ios7_ipad':
|
||||
env.CAPS = {
|
||||
browserName: ''
|
||||
, device: iphoneOrIpadSimulator(env.DEVICE),
|
||||
app: path.resolve(__dirname, "../../sample-code/apps/" + process.env.APP +
|
||||
"/build/Release-iphonesimulator/" + process.env.APP + ".app")
|
||||
};
|
||||
break;
|
||||
case 'android':
|
||||
env.CAPS = {
|
||||
device: 'Android'
|
||||
};
|
||||
break;
|
||||
case 'selendroid':
|
||||
env.CAPS = {
|
||||
browserName: 'Selendroid'
|
||||
, device: 'Selendroid',
|
||||
app: path.resolve(__dirname, "../../sample-code/apps/" + process.env.APP + "/bin/" + process.env.APP + "-debug.apk")
|
||||
};
|
||||
break;
|
||||
case 'firefox':
|
||||
env.CAPS = {
|
||||
browserName: 'Firefox'
|
||||
, device: 'Firefox',
|
||||
app: process.env.APP
|
||||
};
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unknown device!!!');
|
||||
}
|
||||
|
||||
env.IOS = env.DEVICE.match(/ios/i);
|
||||
env.IOS7 = env.DEVICE.match(/ios7/i);
|
||||
env.ANDROID = env.DEVICE.match(/android/i);
|
||||
|
||||
// caps overide for sauce
|
||||
if (env.SAUCE) {
|
||||
if (env.DEVICE === 'IOS') {
|
||||
env.CAPS.version = "6.1";
|
||||
env.CAPS.platform = "Mac 10.8";
|
||||
} else if (env.CAPS.device === 'Android') {
|
||||
env.CAPS.version = "4.2";
|
||||
env.CAPS.platform = "LINUX";
|
||||
}
|
||||
}
|
||||
|
||||
// app path root
|
||||
|
||||
// rest enf points
|
||||
env.TEST_END_POINT = 'http://localhost:' + env.APPIUM_PORT + '/test/';
|
||||
env.GUINEA_TEST_END_POINT = env.TEST_END_POINT + 'guinea-pig';
|
||||
env.CHROME_TEST_END_POINT = 'http://10.0.2.2:' + env.APPIUM_PORT + '/test/';
|
||||
env.CHROME_GUINEA_TEST_END_POINT = env.CHROME_TEST_END_POINT + 'guinea-pig';
|
||||
|
||||
module.exports = env;
|
||||
11
test/helpers/repeat-utils.js
Normal file
11
test/helpers/repeat-utils.js
Normal file
@@ -0,0 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
var tryNTimes = function (n, fn) {
|
||||
if (n <= 0) return;
|
||||
return fn().catch(function () {
|
||||
return tryNTimes(n - 1, fn);
|
||||
});
|
||||
};
|
||||
|
||||
exports.tryNTimes = tryNTimes;
|
||||
exports.try3Times = tryNTimes.bind(null, 3);
|
||||
16
test/helpers/reset-utils.js
Normal file
16
test/helpers/reset-utils.js
Normal file
@@ -0,0 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
var Q = require('Q'),
|
||||
exec = Q.denodeify(require('child_process').exec);
|
||||
|
||||
exports.androidReset = function (appPackage, appActivity) {
|
||||
var cmd = 'adb shell am start -n ' + appPackage + '/' + appActivity;
|
||||
return exec(cmd);
|
||||
};
|
||||
|
||||
exports.androidUninstall = function (appPackage) {
|
||||
var cmd = 'adb uninstall ' + appPackage;
|
||||
return exec(cmd)
|
||||
.catch(function () {})
|
||||
.then(function () { return Q.delay(500); });
|
||||
};
|
||||
84
test/helpers/session-utils.js
Normal file
84
test/helpers/session-utils.js
Normal file
@@ -0,0 +1,84 @@
|
||||
"use strict";
|
||||
var env = require('./env')
|
||||
, wd = require("wd")
|
||||
, Q = require("q")
|
||||
, _ = require("underscore")
|
||||
, androidUninstall = require('./reset-utils').androidUninstall;
|
||||
|
||||
module.exports.initSession = function (desired, opts) {
|
||||
desired = desired || {};
|
||||
opts = opts || {};
|
||||
|
||||
var deferred = Q.defer();
|
||||
|
||||
var browser;
|
||||
|
||||
return {
|
||||
setUp: function () {
|
||||
browser = wd.promiseChainRemote(env.APPIUM_HOST, env.APPIUM_PORT, env.APPIUM_USERNAME, env.APPIUM_PASSWORD);
|
||||
if (env.VERBOSE) {
|
||||
browser.on('status', function (info) {
|
||||
console.log(info);
|
||||
});
|
||||
browser.on('command', function (meth, path, data) {
|
||||
console.log(' > ' + meth, path, data || '');
|
||||
});
|
||||
}
|
||||
deferred.resolve(browser);
|
||||
var caps = _.defaults(desired, env.CAPS);
|
||||
if (env.SAUCE) {
|
||||
caps.name = this.currentTest.parent.title + " " + this.currentTest.title;
|
||||
}
|
||||
|
||||
if (env.VERBOSE) console.log("caps -->", caps);
|
||||
if (env.VERBOSE) console.log("opts -->", opts);
|
||||
|
||||
function init(remainingAttemps) {
|
||||
if (env.VERBOSE) console.log("remainingAttemps -->", remainingAttemps);
|
||||
return browser
|
||||
.init(caps)
|
||||
.catch(function (err) {
|
||||
remainingAttemps --;
|
||||
if (remainingAttemps === 0) {
|
||||
throw err;
|
||||
} else {
|
||||
return browser.sleep(5000).then(function () {
|
||||
return init(remainingAttemps);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
var attempts = opts['no-retry'] ? 1 : 3;
|
||||
return browser.chain()
|
||||
.then(function () {
|
||||
// if android uninstall package first
|
||||
if (desired.device === 'Android' && desired['app-package']) {
|
||||
return androidUninstall(desired['app-package']);
|
||||
}
|
||||
}).then(function () { return init(attempts); })
|
||||
.setImplicitWaitTimeout(5000);
|
||||
},
|
||||
tearDown: function () {
|
||||
var passed = false;
|
||||
if (this.currentTest) {
|
||||
passed = this.currentTest.state = 'passed';
|
||||
}
|
||||
return browser.chain()
|
||||
.then(function () {
|
||||
if (!opts['no-quit']) {
|
||||
return browser
|
||||
.quit()
|
||||
.catch(function () {
|
||||
if (env.VERBOSE) console.warn("didn't quit cleanly.");
|
||||
});
|
||||
}
|
||||
}).then(function () {
|
||||
if (env.SAUCE) return browser.sauceJobStatus(passed);
|
||||
})
|
||||
.catch(function () { console.warn("didn't manange to set sauce status."); })
|
||||
.sleep(2000);
|
||||
},
|
||||
promisedBrowser: deferred.promise
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"use strict";
|
||||
|
||||
var Q = require("./driverblock.js").Q;
|
||||
var Q = require("q");
|
||||
|
||||
exports.spinWait = function(spinFn, waitMs, intMs) {
|
||||
exports.spinWait = function (spinFn, waitMs, intMs) {
|
||||
if (typeof waitMs === "undefined") {
|
||||
waitMs = 10000;
|
||||
}
|
||||
@@ -11,8 +11,8 @@ exports.spinWait = function(spinFn, waitMs, intMs) {
|
||||
}
|
||||
var begunAt = Date.now();
|
||||
var endAt = begunAt + waitMs;
|
||||
var spin = function() {
|
||||
return spinFn().catch( function() {
|
||||
var spin = function () {
|
||||
return spinFn().catch(function () {
|
||||
if (Date.now() < endAt) {
|
||||
return Q.delay(intMs).then(spin);
|
||||
} else {
|
||||
@@ -23,8 +23,8 @@ exports.spinWait = function(spinFn, waitMs, intMs) {
|
||||
return spin();
|
||||
};
|
||||
|
||||
exports.spinTillResEquals = function() {};
|
||||
exports.spinTillResEquals = function () {};
|
||||
|
||||
exports.spinTillNoError = function() {};
|
||||
exports.spinTillNoError = function () {};
|
||||
|
||||
exports.spinTillError = function() {};
|
||||
exports.spinTillError = function () {};
|
||||
|
||||
60
test/helpers/webview-utils.js
Normal file
60
test/helpers/webview-utils.js
Normal file
@@ -0,0 +1,60 @@
|
||||
"use strict";
|
||||
|
||||
var env = require("./env"),
|
||||
uuidGenerator = require('node-uuid');
|
||||
|
||||
var spinTitle = function (expTitle, browser, _timeout) {
|
||||
var timeout = typeof _timeout === 'undefined' ? 90 : _timeout;
|
||||
timeout.should.be.above(0);
|
||||
return browser
|
||||
.title()
|
||||
.then(function (pageTitle) {
|
||||
if (pageTitle.indexOf(expTitle) < 0) {
|
||||
return browser
|
||||
.sleep(500)
|
||||
.then(function () { return spinTitle(expTitle, browser, timeout - 1); });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var loadWebView = function (app, browser, urlToLoad, titleToSpin) {
|
||||
var uuid = uuidGenerator.v1();
|
||||
if (typeof urlToLoad === "undefined") {
|
||||
if (app === "chrome") {
|
||||
urlToLoad = env.CHROME_GUINEA_TEST_END_POINT + '?' + uuid;
|
||||
} else {
|
||||
urlToLoad = env.GUINEA_TEST_END_POINT + '?' + uuid;
|
||||
}
|
||||
}
|
||||
if (typeof titleToSpin === "undefined") {
|
||||
titleToSpin = uuid;
|
||||
}
|
||||
if (app === "safari" || app === "iwebview") {
|
||||
return browser
|
||||
.get(urlToLoad)
|
||||
.then(function () { return spinTitle(titleToSpin, browser); });
|
||||
} else {
|
||||
return browser
|
||||
.windowHandles()
|
||||
.then(function (handles) {
|
||||
handles.length.should.be.above(0);
|
||||
return browser
|
||||
.window(handles[0])
|
||||
.url();
|
||||
})
|
||||
.then(function (url) {
|
||||
if (url !== urlToLoad) {
|
||||
return browser
|
||||
.get(urlToLoad)
|
||||
.then(function () { return spinTitle(titleToSpin, browser); });
|
||||
} else {
|
||||
return spinTitle(titleToSpin, browser);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
spinTitle: spinTitle,
|
||||
loadWebView: loadWebView
|
||||
};
|
||||
2
test/mocha.opts
Executable file
2
test/mocha.opts
Executable file
@@ -0,0 +1,2 @@
|
||||
-t 90000
|
||||
-R spec
|
||||
@@ -9,68 +9,68 @@ var chai = require('chai')
|
||||
, path = require('path')
|
||||
, IOS = require('../../lib/devices/ios/ios.js');
|
||||
|
||||
describe('IOS', function() {
|
||||
describe('IOS', function () {
|
||||
// we'd like to test ios.proxy; mock instruments
|
||||
var inst = new IOS({});
|
||||
inst.instruments = {};
|
||||
inst.instruments.sendCommand = function(cmd, cb) {
|
||||
// let's pretend we've got some latency here.
|
||||
var to = Math.round(Math.random()*10);
|
||||
setTimeout(function() { cb([cmd, to]); }, to);
|
||||
};
|
||||
inst.instruments = {};
|
||||
inst.instruments.sendCommand = function (cmd, cb) {
|
||||
// let's pretend we've got some latency here.
|
||||
var to = Math.round(Math.random() * 10);
|
||||
setTimeout(function () { cb([cmd, to]); }, to);
|
||||
};
|
||||
|
||||
describe('#proxy()', function() {
|
||||
return it('should execute one command at a time keeping the seq right', function(done) {
|
||||
describe('#proxy()', function () {
|
||||
return it('should execute one command at a time keeping the seq right', function (done) {
|
||||
var intercept = []
|
||||
, iterations = 100
|
||||
, check = function(err, result) {
|
||||
, check = function (err, result) {
|
||||
intercept.push(result);
|
||||
if (intercept.length >= iterations) {
|
||||
for (var x=0; x < iterations; x++) {
|
||||
for (var x = 0; x < iterations; x++) {
|
||||
intercept[x][0].should.equal(x);
|
||||
}
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
for (var i=0; i < iterations; i++) {
|
||||
for (var i = 0; i < iterations; i++) {
|
||||
inst.proxy(i, check);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Appium', function() {
|
||||
describe('Appium', function () {
|
||||
var intercept = []
|
||||
, logPath = path.resolve(__dirname, "../../../appium.log")
|
||||
, inst = appium({log: logPath});
|
||||
|
||||
inst.registerConfig({ios: true});
|
||||
|
||||
describe('#start', function() {
|
||||
return it('should fail if a session is in progress', function(done) {
|
||||
var doneYet = function(num) {
|
||||
describe('#start', function () {
|
||||
return it('should fail if a session is in progress', function (done) {
|
||||
var doneYet = function (num) {
|
||||
intercept.push(num);
|
||||
if (intercept.length > 9) {
|
||||
for (var i=0; i < intercept.length; i++) {
|
||||
for (var i = 0; i < intercept.length; i++) {
|
||||
intercept[i].should.not.equal(i);
|
||||
}
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
var loop = function(num) {
|
||||
var loop = function (num) {
|
||||
if (num > 9)
|
||||
return;
|
||||
|
||||
inst.start({app: "/path/to/fake.app", device: "mock_ios"}, function(err) {
|
||||
inst.start({app: "/path/to/fake.app", device: "mock_ios"}, function (err) {
|
||||
var n = num;
|
||||
if (n > 0) {
|
||||
should.exist(err);
|
||||
doneYet(n);
|
||||
} else {
|
||||
setTimeout(function() {
|
||||
inst.stop(function() { doneYet(n); });
|
||||
setTimeout(function () {
|
||||
inst.stop(function () { doneYet(n); });
|
||||
}, 500);
|
||||
}
|
||||
loop(++num);
|
||||
@@ -82,22 +82,22 @@ describe('Appium', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Appium with clobber', function() {
|
||||
describe('Appium with clobber', function () {
|
||||
var logPath = path.resolve(__dirname, "../../../appium.log")
|
||||
, inst = appium({log: logPath, sessionOverride: true });
|
||||
|
||||
inst.registerConfig({mock_ios: true});
|
||||
|
||||
describe('#start', function() {
|
||||
return it('should clobber existing sessions', function(done) {
|
||||
describe('#start', function () {
|
||||
return it('should clobber existing sessions', function (done) {
|
||||
var numSessions = 9
|
||||
, dc = {app: "/path/to/fake.app", device: "mock_ios"};
|
||||
var loop = function(num) {
|
||||
var loop = function (num) {
|
||||
if (num > numSessions) return;
|
||||
inst.start(dc, function() {
|
||||
inst.start(dc, function () {
|
||||
var curSessId = inst.sessionId;
|
||||
var n = num;
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
var newSessId = inst.sessionId;
|
||||
if (n === numSessions) {
|
||||
curSessId.should.equal(newSessId);
|
||||
@@ -105,7 +105,7 @@ describe('Appium with clobber', function() {
|
||||
} else {
|
||||
curSessId.should.not.equal(newSessId);
|
||||
}
|
||||
}, Math.round(Math.random()*100));
|
||||
}, Math.round(Math.random() * 100));
|
||||
loop(++num);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
var rest = require('express')()
|
||||
, appium = require('../../lib/appium');
|
||||
|
||||
describe('Appium', function() {
|
||||
describe('Appium', function () {
|
||||
var inst = appium({});
|
||||
rest.use(rest.router);
|
||||
|
||||
describe('#attachTo', function() {
|
||||
return it('should get valid routes', function(done) {
|
||||
describe('#attachTo', function () {
|
||||
return it('should get valid routes', function (done) {
|
||||
inst.attachTo(rest);
|
||||
done();
|
||||
});
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
var _ = require('underscore')
|
||||
, au = require('../../lib/xpath.js');
|
||||
|
||||
describe("XPath lookups", function() {
|
||||
describe("XPath lookups", function () {
|
||||
var oks = {
|
||||
"//button": {path: [{node: 'button', search: 'desc', index: null}]}
|
||||
"//button": {path: [{node: 'button', search: 'desc', index: null}]}
|
||||
, "//button[last()]": {path: [{node: 'button', search: 'desc', index: -1}]}
|
||||
, "//button[1]": {path: [{node: 'button', search: 'desc', index: 1}]}
|
||||
, "/button": {path: [{node: 'button', search: 'child', index: null}]}
|
||||
@@ -18,38 +18,74 @@ describe("XPath lookups", function() {
|
||||
, "//button/text/webview": {path: [
|
||||
{node: 'button', search: 'desc', index: null}
|
||||
, {node: 'text', search: 'child', index: null}
|
||||
, {node: 'webview', search: 'child', index: null}]}
|
||||
, {node: 'webview', search: 'child', index: null}
|
||||
]}
|
||||
, "//button[1]/text/webview[3]": {path: [
|
||||
{node: 'button', search: 'desc', index: 1}
|
||||
, {node: 'text', search: 'child', index: null}
|
||||
, {node: 'webview', search: 'child', index: 3}]}
|
||||
, {node: 'webview', search: 'child', index: 3}
|
||||
]}
|
||||
, "text/webview//button": {path: [
|
||||
{node: 'text', search: 'desc', index: null}
|
||||
, {node: 'webview', search: 'child', index: null}
|
||||
, {node: 'button', search: 'desc', index: null}]}
|
||||
, {node: 'button', search: 'desc', index: null}
|
||||
]}
|
||||
, "//button[@name='hi there']": {
|
||||
attr: 'name', constraint: 'hi there', substr: false}
|
||||
attr: 'name',
|
||||
constraint: 'hi there',
|
||||
substr: false
|
||||
}
|
||||
, "//button[@other_attr='hi there']": {
|
||||
attr: 'other_attr', constraint: 'hi there', substr: false}
|
||||
attr: 'other_attr',
|
||||
constraint: 'hi there',
|
||||
substr: false
|
||||
}
|
||||
, '//button[@name="hi there"]': {
|
||||
attr: 'name', constraint: 'hi there', substr: false}
|
||||
attr: 'name',
|
||||
constraint: 'hi there',
|
||||
substr: false
|
||||
}
|
||||
, '//list/button[@name="hi there"]': {
|
||||
attr: 'name', constraint: 'hi there', substr: false}
|
||||
attr: 'name',
|
||||
constraint: 'hi there',
|
||||
substr: false
|
||||
}
|
||||
, '//button[@name=hi there]': {
|
||||
attr: 'name', constraint: 'hi there', substr: false}
|
||||
attr: 'name',
|
||||
constraint: 'hi there',
|
||||
substr: false
|
||||
}
|
||||
, '//button[contains(@label, "hi")]': {
|
||||
attr: 'label', constraint: 'hi', substr: true}
|
||||
attr: 'label',
|
||||
constraint: 'hi',
|
||||
substr: true
|
||||
}
|
||||
, '//button[contains(@other_attr, "hi")]': {
|
||||
attr: 'other_attr', constraint: 'hi', substr: true}
|
||||
attr: 'other_attr',
|
||||
constraint: 'hi',
|
||||
substr: true
|
||||
}
|
||||
, "//button[contains(@label, 'hi')]": {
|
||||
attr: 'label', constraint: 'hi', substr: true}
|
||||
attr: 'label',
|
||||
constraint: 'hi',
|
||||
substr: true
|
||||
}
|
||||
, "//button[contains(@label, what's up dog)]": {
|
||||
attr: 'label', constraint: "what's up dog", substr: true}
|
||||
attr: 'label',
|
||||
constraint: "what's up dog",
|
||||
substr: true
|
||||
}
|
||||
, "//*[contains(@text, 'agree')]": {
|
||||
attr: 'text', constraint: 'agree', substr: true}
|
||||
attr: 'text',
|
||||
constraint: 'agree',
|
||||
substr: true
|
||||
}
|
||||
, "//*[@text='agree']": {
|
||||
attr: 'text', constraint: 'agree', substr: false}
|
||||
};
|
||||
attr: 'text',
|
||||
constraint: 'agree',
|
||||
substr: false
|
||||
}
|
||||
};
|
||||
var notOks = [
|
||||
, "//button123"
|
||||
, "//button[-1]"
|
||||
@@ -66,20 +102,20 @@ describe("XPath lookups", function() {
|
||||
, "//button/label[@name='hi']/moar"
|
||||
, "//@attr"
|
||||
];
|
||||
describe("Valid XPaths", function() {
|
||||
_.each(oks, function(test, xpath) {
|
||||
it(xpath + " should work", function() {
|
||||
describe("Valid XPaths", function () {
|
||||
_.each(oks, function (test, xpath) {
|
||||
it(xpath + " should work", function () {
|
||||
var parsed = au.parseXpath(xpath);
|
||||
parsed.should.not.equal(false);
|
||||
_.each(test, function(val, key) {
|
||||
_.each(test, function (val, key) {
|
||||
parsed[key].should.eql(test[key]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("Invalid Xpaths", function() {
|
||||
_.each(notOks, function(xpath) {
|
||||
it(xpath + " should not work", function() {
|
||||
describe("Invalid Xpaths", function () {
|
||||
_.each(notOks, function (xpath) {
|
||||
it(xpath + " should not work", function () {
|
||||
var parsed = au.parseXpath(xpath);
|
||||
parsed.should.equal(false);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user