WIP: integrating saucelabs tests

This commit is contained in:
Sefa Ilkimen 2017-10-11 16:33:07 +02:00
parent 807af7adfa
commit 9dc0bd56e0
21 changed files with 449 additions and 17 deletions

View File

@ -2,3 +2,4 @@ tags
.zedstate
/scripts
/temp
/test

View File

@ -1,6 +1,43 @@
language: node_js
node_js:
- lts/*
sudo: false
language: objective-c
os: osx
osx_image: xcode9.1
cache: false
addons:
sauce_connect:
username: silkimen
jwt: TwUj8A5qAR53BRhVwcdLCM64kI+f8beOLbZ2VmLJ557ptGAxvkHrhQ19uLEQakL64SWoeznObJjTG/Sp8zbO6O9xkfTw5mbNPk7FBTMd77x62l/PHZSWuwiFEVPfLnG2jSGWBqrLxr/g8cIiruzHSXS9J4C86SYIKIGnz9atJxB7XswwzAkvmyzgzC6iRCFhoAgmnhtY+Xr+QHcbpESoiUPv/MQ8CFNpk65CX+fuvVunWX70e3Qlelcs7nkbF/soFwD1WExCbTaPlaNvKqBIc1YuO4qdNy4Uff4mZZLsARH0X618EwFAVN4VM7AIqeUp3NoQYDw9vpkR7lmoOUJzI0aovasXa8frDNvm8GSP17jtCTQzfYEMK+B9rIA9oBRd46dyGujZtbKoTpDdTMIe0ayqb38NRuNwDzEV7WVMCcUgux0Q8NIAkWYYb21QN9z7XOOznP7BatK7mlJ0V6J7taBW2EBOwQzHWRG7n9GknGXsPzwxDW6aBCiOem/AcxZkajDPcRu/3diq5ZSZcC7cTVBxCZZCqpPCsZH0l47jW8MNh+CYw+i5TGsp7g0YHVmbWzE8dv73tMD9zQP0pUjOSkY55xbS7kTCXvFqP0OdMccpzdZY5h7JER95tIPz3gZwVFCoBg0GvwTqTxhGKR+jNosUD2n6WhCVFAU+AspgCKo=
before_install:
- export LANG=en_US.UTF-8
- brew update
install:
- npm install
- brew install gradle
- wget http://dl.google.com/android/android-sdk_r24.4-macosx.zip
- tar -xvf android-sdk_r24.4-macosx.zip
- echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter platform-tools
- echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter build-tools-25.0.0
- echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter android-25
- echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter extra-android-support
- echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter extra-android-m2repository
- echo y | ./android-sdk-macosx/tools/android update sdk --no-ui --all --filter extra-google-m2repository
- export ANDROID_HOME=./android-sdk-macosx
- export PATH=${PATH}:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools/23.0.2
script:
- scripts/build-test-app.sh
- scripts/upload-artifact.sh
- scripts/test.sh --ios --emulator
after_success:
deploy:
notifications:
slack:
secure: lXE+2AgsxZU5G5dI91LkMAIgo8MAWfdM7DB5UOtn5LpuNln+2FmJo1gOI7tkdmLOqpXTGYnpI2VyQN3H4nOF21YhuouzD1Sh8n2wtQg1iTm353kuQpqiVhSBX8ZJ7Be1e1G8OsnxoYOxbs4Zo9qI40EruwkvqLCBHWM5MRGyd4M7EFWwb9Z29VZN0y1Nt5g/c3bT76kdKmF+JCLur2OeEKxAity7sIKgZekSqeIMwEVLSxXnda6Dbjc/cg0MJ0iDArkD7iu6fz/Fcrrxgm/pUxjcgvqze7Gy5i31mjEfspnrglWV1cshMd48BTDKCJ2AMmxH8O3GPSWE2txjIvGRWUve7iViNylvmQCVz3Eyf99+4EuuVGa+5PSodQ/CqODx/65EwtcN3PE1tNz2puKOK8nrOJcFkcbG8KTHKUlQtHCkjitbykUnj/hvhLK5/oWlQYVOLWWrHwdGUh8FI8aFPVGjRjWbHbhdayjEIqxwr1ns+6mYrP1EFNXbaeZxnLNC59XpJl1ifuezqYAk7YEiU5j4rtC7YKgyQ3ueb7anOHTJoTMyDn8mpZXgwuyhoBaeEYytQVgRyMtL6Y5cP98Jn2kv0+vdne3rkk9/JEBTo32HOjvoij6rsqEvXC0LhUDJSNadOVdHht0jjoN6zBH37HIE5/3zysLlPcAcHAS83ow=

View File

@ -3,7 +3,7 @@
"version": "1.6.1",
"description": "Cordova / Phonegap plugin for communicating with HTTP servers using SSL pinning",
"scripts": {
"test": "./scripts/test-installation.sh"
"test": "./scripts/build-test-app.sh && ./scripts/test.sh --ios --emulator"
},
"cordova": {
"id": "cordova-plugin-advanced-http",
@ -49,9 +49,14 @@
},
"homepage": "https://github.com/silkimen/cordova-plugin-advanced-http#readme",
"devDependencies": {
"chai": "4.1.2",
"chai-as-promised": "7.1.1",
"colors": "1.1.2",
"cordova": "7.0.1",
"mocha": "4.0.0",
"mz": "2.7.0",
"umd-tough-cookie": "2.3.2",
"wd": "1.4.1",
"xml2js": "0.4.19"
}
}

View File

@ -5,5 +5,6 @@ VERSION=$(node -e "console.log(require('./package.json').version)")
./scripts/update-tough-cookie.sh
node ./scripts/update-plugin-xml.js $VERSION
npm publish
git commit -a -m "release v$VERSION"
git tag "v$VERSION"
npm publish

16
scripts/build-test-app.sh Executable file
View File

@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -e
PLATFORM=$([[ "${@#--android}" = "$@" ]] && echo "ios" || echo "android")
TARGET=$([[ "${@#--device}" = "$@" ]] && echo "emulator" || echo "device")
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/..
CDV=$ROOT/node_modules/.bin/cordova
rm -rf $ROOT/temp
mkdir $ROOT/temp
cp -r $ROOT/test/app-template/ $ROOT/temp/
cp $ROOT/test/test-definitions.js $ROOT/temp/www/js/
cd $ROOT/temp
$CDV prepare
$CDV plugins add $ROOT
$CDV build $PLATFORM --$TARGET

View File

@ -1,12 +0,0 @@
#!/usr/bin/env bash
set -e
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/..
CDV=$ROOT/node_modules/.bin/cordova
rm -rf $ROOT/temp
$CDV create $ROOT/temp
cd $ROOT/temp
$CDV platforms add android
$CDV platforms add ios
$CDV plugins add $ROOT

8
scripts/test.sh Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -e
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/..
pushd $ROOT
./node_modules/.bin/mocha ./test/mocha-specs/test.js "$@"
popd

16
scripts/upload-artifact.sh Executable file
View File

@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -e
ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"/..
TEMP=$ROOT/temp
rm -rf $TEMP/HttpDemo.app.zip
pushd $TEMP/platforms/ios/build/emulator
zip -r $TEMP/HttpDemo.app.zip ./HttpDemo.app
popd
curl -u $SAUCE_USERNAME:$SAUCE_ACCESS_KEY \
-X POST \
-H "Content-Type: application/octet-stream" \
https://saucelabs.com/rest/v1/storage/$SAUCE_USERNAME/HttpDemo.app.zip?overwrite=true \
--data-binary @$TEMP/HttpDemo.app.zip

View File

@ -0,0 +1,27 @@
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.ilkimen.http.demo" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>HttpDemo</name>
<description>
A sample Apache Cordova application that demonstrates advanced HTTP plugin.
</description>
<author email="dev@cordova.apache.org" href="http://cordova.io">
Sefa Ilkimen
</author>
<content src="index.html" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
</platform>
<engine name="android" spec="6.2.3" />
<engine name="ios" spec="4.4.0" />
</widget>

View File

@ -0,0 +1,25 @@
{
"name": "com.ilkimen.http.demo",
"displayName": "HttpDemo",
"version": "1.0.0",
"description": "A sample Apache Cordova application that demonstrates advanced HTTP plugin.",
"main": "index.js",
"scripts": {
"build": "scripts/build.sh",
"test": "npm run build && scripts/test.sh"
},
"author": "Sefa Ilkimen",
"license": "Apache-2.0",
"dependencies": {
"cordova": "7.0.1",
"cordova-android": "6.2.3",
"cordova-ios": "4.4.0"
},
"cordova": {
"platforms": [
"android",
"ios"
]
},
"devDependencies": {}
}

View File

@ -0,0 +1,24 @@
* {
-webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
}
body {
-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
-webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
-webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
height:100%;
margin:0px;
padding:20px 0;
width:100%;
font-family: sans-serif;
}
button, input, textarea {
display: block;
width: 100%;
}
h1 {
font-size: 12pt;
text-align: center;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<link rel="stylesheet" type="text/css" href="css/index.css">
</head>
<body>
<h1 id="descriptionLbl">Advanced HTTP test suite</h1>
<textarea rows="20" cols="50" id="resultTextarea">Click next to run first test.</textarea>
<button id="nextBtn">Run next test</button>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/test-definitions.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</body>
</html>

View File

@ -0,0 +1,51 @@
const app = {
testIndex: -1,
initialize: function() {
document.getElementById('nextBtn').addEventListener('click', app.onNextBtnClick);
},
print: function(prefix, content) {
const text = '\n' + prefix + ': ' + JSON.stringify(content);
document.getElementById('resultTextarea').value += text;
},
reject: function(content) {
app.print('result - rejected', content);
},
resolve: function(content) {
app.print('result - resolved', content);
},
runTest: function(index) {
const testDefinition = tests[index];
const titleText = app.testIndex + ': ' + testDefinition.description;
const resultText = 'expectation - ' + testDefinition.expected;
document.getElementById('resultTextarea').value = resultText;
document.getElementById('descriptionLbl').innerText = titleText;
testDefinition.func(index);
},
onFinishedAllTests: function() {
const titleText = 'No more tests';
const resultText = 'You have run all available tests.';
document.getElementById('resultTextarea').value = resultText;
document.getElementById('descriptionLbl').innerText = titleText;
},
onNextBtnClick: function() {
app.testIndex += 1;
if (app.testIndex < tests.length) {
app.runTest(app.testIndex);
} else {
app.onFinishedAllTests();
}
}
};
app.initialize();

View File

@ -0,0 +1,10 @@
const path = require('path');
if (process.env.SAUCE_USERNAME) {
exports.iosTestApp = 'sauce-storage:HttpDemo.app.zip';
exports.androidTestApp = 'sauce-storage:HttpDemo.apk';
} else {
// these paths are relative to working directory
exports.iosTestApp = path.resolve('temp/platforms/ios/build/emulator/HttpDemo.app');
exports.androidTestApp = path.resolve('temp/platforms/android/build/outputs/apk/android-debug.apk');
}

View File

@ -0,0 +1,65 @@
const local = {
iosDevice: {
browserName: '',
'appium-version': '1.7.1',
platformName: 'iOS',
platformVersion: '10.3',
deviceName: 'iPhone 6',
autoWebview: true,
app: undefined // will be set later
},
iosEmulator: {
browserName: '',
'appium-version': '1.7.1',
platformName: 'iOS',
platformVersion: '11.0',
deviceName: 'iPhone Simulator',
autoWebview: true,
app: undefined // will be set later
},
androidEmulator: {
browserName: '',
'appium-version': '1.7.1',
platformName: 'Android',
platformVersion: '5.1',
deviceName: 'Android Emulator',
autoWebview: true,
app: undefined // will be set later
}
};
const sauce = {
iosDevice: {
browserName: '',
'appium-version': '1.7.1',
platformName: 'iOS',
platformVersion: '10.3',
deviceName: 'iPhone 6',
autoWebview: true,
app: undefined // will be set later
},
iosEmulator: {
browserName: '',
'appium-version': '1.7.1',
platformName: 'iOS',
platformVersion: '10.3',
deviceName: 'iPhone Simulator',
autoWebview: true,
app: undefined // will be set later
},
androidEmulator: {
browserName: '',
'appium-version': '1.7.1',
platformName: 'Android',
platformVersion: '5.1',
deviceName: 'Android Emulator',
autoWebview: true,
app: undefined // will be set later
}
};
if (process.env.SAUCE_USERNAME) {
module.exports = sauce;
} else {
module.exports = local;
}

View File

@ -0,0 +1,13 @@
exports.configure = driver => {
driver.on('status', info => {
console.log(info.cyan);
});
driver.on('command', (meth, path, data) => {
console.log(' > ' + meth.yellow, path.grey, data || '');
});
driver.on('http', (meth, path, data) => {
console.log(' > ' + meth.magenta, path, (data || '').grey);
});
};

View File

@ -0,0 +1,16 @@
const local = {
host: 'localhost',
port: 4723
};
const sauce = {
host: 'ondemand.saucelabs.com',
port: 80,
auth: process.env.SAUCE_USERNAME + ":" + process.env.SAUCE_ACCESS_KEY
};
if (process.env.SAUCE_USERNAME) {
module.exports = sauce;
} else {
module.exports = local;
}

View File

@ -0,0 +1,12 @@
const wd = require("wd");
require('colors');
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
const should = chai.should();
chaiAsPromised.transferPromiseness = wd.transferPromiseness;
exports.should = should;

71
test/mocha-specs/test.js Normal file
View File

@ -0,0 +1,71 @@
require('./helpers/setup');
const wd = require('wd');
const apps = require('./helpers/apps');
const caps = Object.assign({}, require('./helpers/caps'));
const serverConfig = require('./helpers/server');
const testDefinitions = require('../test-definitions');
describe('Advanced HTTP', function() {
let driver;
let allPassed = true;
this.timeout(300000);
const getCaps = appName => {
const isDevice = process.argv.includes('--device');
const isAndroid = process.argv.includes('--android');
const desiredCaps = caps[(isAndroid ? 'android' : 'ios') + (isDevice ? 'Device' : 'Emulator')];
const desiredApp = apps[(isAndroid ? 'android' : 'ios') + appName];
desiredCaps.app = desiredApp;
return desiredCaps;
};
const validateTestIndex = number => driver
.elementById('descriptionLbl')
.text()
.then(text => parseInt(text.match(/(\d):/)[1], 10))
.should.eventually.become(number);
const validateTestTitle = testTitle => driver
.elementById('descriptionLbl')
.text()
.then(text => text.match(/\d:\ (.*)/)[1])
.should.eventually.become(testTitle);
const validateResult = text => driver
.elementById('resultTextarea')
.getAttribute('value')
.should.eventually.include(text);
const clickNext = () => driver
.elementById('nextBtn')
.click()
.sleep(1000);
before(() => {
driver = wd.promiseChainRemote(serverConfig);
require('./helpers/logging').configure(driver);
return driver.init(getCaps('TestApp'));
});
after(() => driver
.quit()
.finally(function () {
if (process.env.SAUCE_USERNAME) {
return driver.sauceJobStatus(allPassed);
}
}));
testDefinitions.forEach((definition, index) => {
it(definition.description, function() {
return clickNext()
.then(() => validateTestIndex(index))
.then(() => validateTestTitle(this.test.title))
.then(() => validateResult(definition.expected))
});
});
});

27
test/test-definitions.js Normal file
View File

@ -0,0 +1,27 @@
const tests = [
{
description: 'should reject self signed cert (GET)',
expected: 'rejected: {"status":-1,"error":"cancelled"}',
func: function() { cordova.plugin.http.get('https://self-signed.badssl.com/', {}, {}, app.resolve, app.reject); }
},{
description: 'should reject self signed cert (PUT)',
expected: 'rejected: {"status":-1,"error":"cancelled"}',
func: function() { cordova.plugin.http.put('https://self-signed.badssl.com/', { test: 'testString' }, {}, app.resolve, app.reject); }
},{
description: 'should reject self signed cert (POST)',
expected: 'rejected: {"status":-1,"error":"cancelled"}',
func: function() { cordova.plugin.http.post('https://self-signed.badssl.com/', { test: 'testString' }, {}, app.resolve, app.reject); }
},{
description: 'should reject self signed cert (PATCH)',
expected: 'rejected: {"status":-1,"error":"cancelled"}',
func: function() { cordova.plugin.http.patch('https://self-signed.badssl.com/', { test: 'testString' }, {}, app.resolve, app.reject); }
},{
description: 'should reject self signed cert (DELETE)',
expected: 'rejected: {"status":-1,"error":"cancelled"}',
func: function() { cordova.plugin.http.delete('https://self-signed.badssl.com/', {}, {}, app.resolve, app.reject); }
}
];
if (module && module.exports) {
module.exports = tests;
}