diff --git a/.travis.yml b/.travis.yml index da56bc7..a43691a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,12 +3,16 @@ branches: - master env: global: - - ANDROID_PACKAGE='camera-debug.apk' - - ANDROID_PACKAGE_FOLDER=$TRAVIS_BUILD_DIR/demo/platforms/android/app/build/outputs/apk/debug - - ANDROID_SAUCE_STORAGE="https://saucelabs.com/rest/v1/storage/$SAUCE_USER/$ANDROID_PACKAGE?overwrite=true" - - IOS_PACKAGE='camera.zip' - - IOS_PACKAGE_FOLDER=$TRAVIS_BUILD_DIR/demo/platforms/ios/build/emulator - - IOS_SAUCE_STORAGE="https://saucelabs.com/rest/v1/storage/$SAUCE_USER/$IOS_PACKAGE?overwrite=true" + - ANDROID_PACKAGE_JS='camera-debug-js.apk' + - ANDROID_PACKAGE_VUE='camera-debug-vue.apk' + - ANDROID_PACKAGE_FOLDER_JS=$TRAVIS_BUILD_DIR/demo/platforms/android/app/build/outputs/apk/debug + - ANDROID_PACKAGE_FOLDER_VUE=$TRAVIS_BUILD_DIR/demo-vue/platforms/android/app/build/outputs/apk/debug + - ANDROID_SAUCE_STORAGE="https://saucelabs.com/rest/v1/storage/$SAUCE_USER" + - IOS_PACKAGE_JS='camera-js.zip' + - IOS_PACKAGE_VUE='camera-vue.zip' + - IOS_PACKAGE_FOLDER_JS=$TRAVIS_BUILD_DIR/demo/platforms/ios/build/emulator + - IOS_PACKAGE_FOLDER_VUE=$TRAVIS_BUILD_DIR/demo-vue/platforms/ios/build/emulator + - IOS_SAUCE_STORAGE="https://saucelabs.com/rest/v1/storage/$SAUCE_USER" matrix: include: @@ -21,58 +25,157 @@ matrix: os: osx env: - WebPackiOS="12.0" + - Type="VanillaJS" osx_image: xcode10.0 language: node_js node_js: "8" jdk: oraclejdk8 - script: cd demo && npm run build.plugin && npm i && tns build ios --env.uglify && cd ../demo-angular && npm i && tns build ios --env.uglify --env.aot + script: + - cd demo && npm run build.plugin + - npm i && tns build ios --bundle --env.uglify + - os: osx + env: + - WebPackiOS="12.0" + - Type="Angular" + osx_image: xcode10.0 + language: node_js + node_js: "8" + jdk: oraclejdk8 + script: + - cd src && npm run build && npm pack + - cd ../demo-angular && tns plugin add ../src/*.tgz + - npm i && tns build ios --bundle --env.uglify --env.aot + - os: osx + env: + - WebPackiOS="12.0" + - Type="VueJS" + osx_image: xcode10.0 + language: node_js + node_js: "8" + jdk: oraclejdk8 + script: + - cd src && npm run build + - cd ../demo-vue && npm i && tns build ios --bundle --env.uglify + - cd $IOS_PACKAGE_FOLDER_VUE && zip -r $IOS_PACKAGE_VUE demovue.app + - "curl -u $SAUCE_USER:$SAUCE_KEY -X POST -H 'Content-Type: application/octet-stream' $IOS_SAUCE_STORAGE/$IOS_PACKAGE_VUE?overwrite=true --data-binary @$IOS_PACKAGE_FOLDER_VUE/$IOS_PACKAGE_VUE" - language: android os: linux env: - - WebPackAndroid="28" + - WebpackAndroid="28" + - Type="VanillaJS" + jdk: oraclejdk8 + before_install: nvm install 8 + script: + - cd src && npm run build + - cd ../demo && npm i && tns build android --bundle --env.uglify --env.snapshot + - "curl -u $SAUCE_USER:$SAUCE_KEY -X POST -H 'Content-Type: application/octet-stream' $ANDROID_SAUCE_STORAGE/$ANDROID_PACKAGE_JS?overwrite=true --data-binary @$ANDROID_PACKAGE_FOLDER_JS/app-debug.apk" + - language: android + os: linux + env: + - WebpackAndroid="28" + - Type="VueJS" + jdk: oraclejdk8 + before_install: nvm install 8 + script: + - cd src && npm run build + - cd ../demo-vue && npm i && tns build android --bundle --env.uglify + - "curl -u $SAUCE_USER:$SAUCE_KEY -X POST -H 'Content-Type: application/octet-stream' $ANDROID_SAUCE_STORAGE/$ANDROID_PACKAGE_VUE?overwrite=true --data-binary @$ANDROID_PACKAGE_FOLDER_VUE/app-debug.apk" + - language: android + os: linux + env: + - WebpackAndroid="28" + - Type="Angular" + jdk: oraclejdk8 + before_install: nvm install 8 + script: + - cd src && npm run build + - cd ../publish && sh pack.sh + - cd ../demo-angular && tns plugin add ../publish/package/*.tgz + - npm i && tns build android --bundle --env.uglify --env.snapshot --env.aot + - language: android + env: + - BuildAndroid="28" + - Type="VanillaJS" + os: linux jdk: oraclejdk8 before_install: nvm install 8.11.4 - script: cd demo && npm run build.plugin && npm i && tns build android --env.uglify --env.snapshot && cd ../demo-angular && npm i && tns build android --env.uglify --env.snapshot --env.aot - - env: + script: + - cd demo && npm run ci.android.build + - language: android + env: - BuildAndroid="28" - language: android + - Type="Angular" os: linux jdk: oraclejdk8 before_install: nvm install 8.11.4 script: - - cd src && npm i && npm run tsc && cd ../demo && tns build android && cd ../demo-angular && tns build android - - "curl -u $SAUCE_USER:$SAUCE_KEY -X POST -H 'Content-Type: application/octet-stream' $ANDROID_SAUCE_STORAGE --data-binary @$ANDROID_PACKAGE_FOLDER/app-debug.apk" + - cd demo-angular && npm run ci.android.build - os: osx - env: + env: - BuildiOS="12.0" - Xcode="10.0" + - Type="VanillaJS" osx_image: xcode10.0 - language: node_js + language: node_js node_js: "8" jdk: oraclejdk8 - script: - - cd src && npm i && npm run tsc && cd ../demo && tns build ios && cd ../demo-angular && tns build ios - - cd $IOS_PACKAGE_FOLDER && zip -r $IOS_PACKAGE demo.app - - "curl -u $SAUCE_USER:$SAUCE_KEY -X POST -H 'Content-Type: application/octet-stream' $IOS_SAUCE_STORAGE --data-binary @$IOS_PACKAGE_FOLDER/$IOS_PACKAGE" + script: + - cd demo && npm run ci.ios.build + - cd $IOS_PACKAGE_FOLDER_JS && zip -r $IOS_PACKAGE_JS demo.app + - "curl -u $SAUCE_USER:$SAUCE_KEY -X POST -H 'Content-Type: application/octet-stream' $IOS_SAUCE_STORAGE/$IOS_PACKAGE_JS?overwrite=true --data-binary @$IOS_PACKAGE_FOLDER_JS/$IOS_PACKAGE_JS" + - os: osx + env: + - BuildiOS="12.0" + - Xcode="10.0" + - Type="Angular" + osx_image: xcode10.0 + language: node_js + node_js: "8" + jdk: oraclejdk8 + script: + - cd demo-angular && npm run ci.ios.build - stage: "UI Tests" - env: - - Android="23" + env: + - Android="24" + - Type="VanillaJS" language: node_js os: linux node_js: "8" script: - npm i -g appium - cd demo && npm i - - travis_retry npm run e2e -- --runType android23 --sauceLab --reuseDevice --appPath $ANDROID_PACKAGE + - travis_wait travis_retry npm run e2e -- --runType android23 --sauceLab --appPath $ANDROID_PACKAGE_JS - os: linux - env: - - iOS="10" - language: node_js + env: + - Android="24" + - Type="VueJS" + language: node_js + os: linux + node_js: "8" + script: + - npm i -g appium + - cd demo-vue && npm i + - travis_wait travis_retry npm run e2e -- --runType android23 --sauceLab --appPath $ANDROID_PACKAGE_VUE + - os: linux + env: + - iOS="12.0" + - Type="VanillaJS" + language: node_js node_js: "8" script: - npm i -g appium - cd demo && npm i - - travis_wait travis_retry npm run e2e -- --runType sim.iPhone8.iOS11.2 --sauceLab --reuseDevice --appPath $IOS_PACKAGE + - travis_wait travis_retry npm run e2e -- --runType sim.iPhoneX.iOS12 --sauceLab --appPath $IOS_PACKAGE_JS + - os: linux + env: + - iOS="12.0" + - Type="VueJS" + language: node_js + node_js: "8" + script: + - npm i -g appium + - cd demo-vue && npm i + - travis_wait travis_retry npm run e2e -- --runType sim.iPhoneX.iOS12 --sauceLab --appPath $IOS_PACKAGE_VUE android: components: diff --git a/demo-angular/package.json b/demo-angular/package.json index 4d9df81..c8dbae2 100644 --- a/demo-angular/package.json +++ b/demo-angular/package.json @@ -14,7 +14,9 @@ }, "scripts": { "build.plugin": "cd ../src && npm run build", - "ci.tslint": "npm i && tslint --config '../tslint.json' 'app/**/*.ts' --exclude '**/node_modules/**'" + "ci.tslint": "npm i && tslint --config '../tslint.json' 'app/**/*.ts' --exclude '**/node_modules/**'", + "ci.android.build": "cd ../src && npm run build && cd ../demo-angular && tns build android", + "ci.ios.build": "cd ../src && npm run build && cd ../demo-angular && tns build ios" }, "dependencies": { "@angular/animations": "~7.1.0", diff --git a/demo-vue/e2e/config/appium.capabilities.json b/demo-vue/e2e/config/appium.capabilities.json new file mode 100644 index 0000000..47b639e --- /dev/null +++ b/demo-vue/e2e/config/appium.capabilities.json @@ -0,0 +1,144 @@ +{ + "android19": { + "platformName": "Android", + "platformVersion": "4.4", + "deviceName": "Emulator-Api19-Default", + "avd": "Emulator-Api19-Default", + "lt": 60000, + "appActivity": "com.tns.NativeScriptActivity", + "newCommandTimeout": 720, + "noReset": true, + "fullReset": false, + "app": "" + }, + "android21": { + "platformName": "Android", + "platformVersion": "5.0", + "deviceName": "Emulator-Api21-Default", + "avd": "Emulator-Api21-Default", + "lt": 60000, + "appActivity": "com.tns.NativeScriptActivity", + "newCommandTimeout": 720, + "noReset": true, + "fullReset": false, + "app": "" + }, + "android23.local": { + "platformName": "Android", + "platformVersion": "6.0", + "deviceName": "Emulator_Api23_Default", + "avd": "Emulator_Api23_Default", + "noReset": true + }, + "android23": { + "platformName": "Android", + "platformVersion": "6.0", + "deviceName": "Android Emulator", + "appium-version": "1.7.1", + "noReset": true + }, + "android24": { + "platformName": "Android", + "platformVersion": "7.0", + "deviceName": "Android GoogleAPI Emulator", + "lt": 60000, + "appActivity": "com.tns.NativeScriptActivity", + "newCommandTimeout": 720, + "noReset": true, + "fullReset": false, + "app": "" + }, + "android24.sauce": { + "platformName": "Android", + "platformVersion": "7.0", + "deviceName": "Android GoogleAPI Emulator", + "lt": 60000, + "newCommandTimeout": 720, + "appiumVersion": "1.9.1", + "noReset": true, + "fullReset": false, + "app": "" + }, + "android25": { + "platformName": "Android", + "platformVersion": "7.1", + "deviceName": "Emulator-Api25-Google", + "avd": "Emulator-Api25-Google", + "lt": 60000, + "appActivity": "com.tns.NativeScriptActivity", + "newCommandTimeout": 720, + "noReset": true, + "fullReset": false, + "app": "" + }, + "android26": { + "platformName": "Android", + "platformVersion": "8.0", + "deviceName": "Emulator-Api26-Google", + "avd": "Emulator-Api26-Google", + "noReset": true, + "fullReset": false, + "app": "" + }, + "sim.iPhone7.iOS100": { + "platformName": "iOS", + "platformVersion": "10.0", + "deviceName": "iPhone 7 100", + "noReset": true, + "fullReset": false, + "app": "" + }, + "sim103iPhone6": { + "browserName": "", + "appiumVersion": "1.7.1", + "platformName": "iOS", + "platformVersion": "10.3", + "deviceName": "iPhone 6", + "app": "" + }, + "sim.iPhone8.iOS110": { + "platformName": "iOS", + "platformVersion": "11.0", + "deviceName": "iPhone 8 110", + "noReset": true, + "fullReset": false, + "app": "" + }, + "sim.iPhoneX.iOS110": { + "platformName": "iOS", + "platformVersion": "11.0", + "deviceName": "iPhone X", + "noReset": true, + "fullReset": false, + "app": "" + }, + "sim.iPhoneX.iOS12": { + "platformName": "iOS", + "platformVersion": "12.0", + "deviceName": "iPhone X", + "noReset": true, + "fullReset": false, + "app": "", + "density":3, + "offsetPixels":87 + }, + "sim.iPhoneX.iOS12.1": { + "platformName": "iOS", + "platformVersion": "12.1", + "deviceName": "iPhone X", + "noReset": true, + "fullReset": false, + "app": "", + "density":3, + "offsetPixels":87 + }, + "sim.iPhone8.iOS11.2": { + "platformName": "iOS", + "platformVersion": "11.2", + "deviceName": "iPhone 8", + "noReset": true, + "fullReset": false, + "appiumVersion": "1.7.1", + "app": "" + } +} \ No newline at end of file diff --git a/demo-vue/e2e/config/mocha.opts b/demo-vue/e2e/config/mocha.opts new file mode 100644 index 0000000..ad112ca --- /dev/null +++ b/demo-vue/e2e/config/mocha.opts @@ -0,0 +1,4 @@ +--timeout 800000 +--recursive e2e +--reporter mocha-multi +--reporter-options spec=-,mocha-junit-reporter=test-results.xml \ No newline at end of file diff --git a/demo-vue/e2e/reports/app/Emulator Api24 Google/should take a picture.png b/demo-vue/e2e/reports/app/Emulator Api24 Google/should take a picture.png new file mode 100644 index 0000000..2ef8424 Binary files /dev/null and b/demo-vue/e2e/reports/app/Emulator Api24 Google/should take a picture.png differ diff --git a/demo-vue/e2e/reports/demovue/Android_GoogleAPI_Emulator/should take a picture.png b/demo-vue/e2e/reports/demovue/Android_GoogleAPI_Emulator/should take a picture.png new file mode 100644 index 0000000..106dac7 Binary files /dev/null and b/demo-vue/e2e/reports/demovue/Android_GoogleAPI_Emulator/should take a picture.png differ diff --git a/demo-vue/e2e/reports/demovue/iPhone X/should take a picture.png b/demo-vue/e2e/reports/demovue/iPhone X/should take a picture.png new file mode 100644 index 0000000..f8168cb Binary files /dev/null and b/demo-vue/e2e/reports/demovue/iPhone X/should take a picture.png differ diff --git a/demo-vue/e2e/setup.ts b/demo-vue/e2e/setup.ts new file mode 100644 index 0000000..8b26e66 --- /dev/null +++ b/demo-vue/e2e/setup.ts @@ -0,0 +1,9 @@ +import { startServer, stopServer } from "nativescript-dev-appium"; + +before("start server", async () => { + await startServer(); +}); + +after("stop server", async () => { + await stopServer(); +}); diff --git a/demo-vue/e2e/tests.e2e.ts b/demo-vue/e2e/tests.e2e.ts new file mode 100644 index 0000000..b5187a2 --- /dev/null +++ b/demo-vue/e2e/tests.e2e.ts @@ -0,0 +1,74 @@ +import { AppiumDriver, createDriver, SearchOptions, Direction, UIElement, Point, Locator } from "nativescript-dev-appium"; +import { isSauceLab, runType } from "nativescript-dev-appium/lib/parser"; +import { expect } from "chai"; +import { exec } from "child_process"; + +const isSauceRun = isSauceLab; +const isAndroid: boolean = runType.includes("android"); + +describe("Camera", () => { + let driver: AppiumDriver; + + before(async () => { + driver = await createDriver(); + driver.defaultWaitTime = 15000; + }); + + after(async () => { + if (isSauceRun) { + driver.sessionId().then(function (sessionId) { + console.log("Report: https://saucelabs.com/beta/tests/" + sessionId); + }); + } + await driver.quit(); + console.log("Driver quits!"); + }); + + afterEach(async function () { + if (this.currentTest.state === "failed") { + await driver.logScreenshot(this.currentTest.title); + } + }); + + it("should take a picture", async function () { + const takePictureButton = await driver.findElementByText("Take Picture"); + await takePictureButton.click(); + await driver.wait(1000); + if (isAndroid) { + let allow = await driver.findElementByTextIfExists("Allow", SearchOptions.exact); + if (allow !== undefined) { + await allow.click(); + allow = await driver.findElementByTextIfExists("Allow", SearchOptions.exact); + await allow.click(); + } + const deny = await driver.findElementByTextIfExists("Deny", SearchOptions.exact); + if (deny !== undefined) { + await deny.click(); + } + let images = await driver.findElementsByClassName(driver.locators.image); // Take a picture + await images[5].click(); + images = await driver.findElementsByClassName(driver.locators.image); // Accept it + await images[4].click(); + } else { + let ok = await driver.findElementByTextIfExists("OK", SearchOptions.exact); + if(ok !== undefined){ + await ok.click(); + let okBtn = await driver.findElementByTextIfExists("OK", SearchOptions.exact); + await okBtn.click(); + } + let photos = await driver.findElementByText("Photos", SearchOptions.exact); + expect(photos).to.exist; + await driver.wait(2000); + await driver.clickPoint(50, 110); // Select directory + await driver.wait(2000); + await driver.clickPoint(50, 240); // Select image + } + const saveToGalleryLabel = await driver.findElementByText("saveToGallery"); + expect(saveToGalleryLabel).to.exist; + const imageDisplayedInfo = await driver.findElementByText("Displayed Size: ", SearchOptions.contains); + expect(imageDisplayedInfo).to.exist; + const imageInfo = await driver.findElementByText("Image Size: ", SearchOptions.contains); + expect(imageInfo).to.exist; + + }); +}); \ No newline at end of file diff --git a/demo-vue/e2e/tsconfig.json b/demo-vue/e2e/tsconfig.json new file mode 100644 index 0000000..c297b23 --- /dev/null +++ b/demo-vue/e2e/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "importHelpers": false, + "types": [ + "node", + "mocha", + "chai" + ], + "lib": [ + "es2015", + "dom" + ] + } +} \ No newline at end of file diff --git a/demo-vue/package.json b/demo-vue/package.json index b69ff93..493aa95 100644 --- a/demo-vue/package.json +++ b/demo-vue/package.json @@ -1,30 +1,39 @@ { - "nativescript": { - "id": "org.nativescript.demovue", - "tns-android": { - "version": "5.1.0" - }, - "tns-ios": { - "version": "5.1.0" - } + "nativescript": { + "id": "org.nativescript.demovue", + "tns-android": { + "version": "5.1.0" }, - "scripts": { - "build.plugin": "cd ../src && npm run build" - }, - "dependencies": { - "nativescript-camera": "../src", - "nativescript-theme-core": "~1.0.4", - "nativescript-vue": "~2.0.0", - "tns-core-modules": "~5.0.2" - }, - "devDependencies": { - "@babel/core": "~7.1.0", - "@babel/preset-env": "~7.1.0", - "babel-loader": "~8.0.0", - "nativescript-dev-webpack": "~0.18.0", - "nativescript-dev-typescript": "~0.7.0", - "nativescript-vue-template-compiler": "~2.0.0", - "node-sass": "~4.9.0", - "vue-loader": "~15.4.0" + "tns-ios": { + "version": "5.1.0" } -} \ No newline at end of file + }, + "scripts": { + "build.plugin": "cd ../src && npm run build", + "e2e": "tsc -p e2e && mocha --opts ./e2e/config/mocha.opts " + }, + "dependencies": { + "nativescript-camera": "../src", + "nativescript-theme-core": "~1.0.4", + "nativescript-vue": "~2.0.0", + "tns-core-modules": "~5.0.2" + }, + "devDependencies": { + "@babel/core": "~7.1.0", + "@babel/preset-env": "~7.1.0", + "@types/chai": "~4.1.7", + "@types/mocha": "~5.2.5", + "@types/node": "~10.12.18", + "babel-loader": "~8.0.0", + "mocha": "~5.2.0", + "mocha-junit-reporter": "~1.18.0", + "mocha-multi": "~1.0.1", + "nativescript-dev-appium": "4.0.9", + "nativescript-dev-typescript": "~0.7.0", + "nativescript-dev-webpack": "~0.18.0", + "nativescript-vue-template-compiler": "~2.0.0", + "node-sass": "~4.9.0", + "tslint": "~5.12.1", + "vue-loader": "~15.4.0" + } +} diff --git a/demo-vue/test-results.xml b/demo-vue/test-results.xml new file mode 100644 index 0000000..53fb1e8 --- /dev/null +++ b/demo-vue/test-results.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/demo/e2e/config/appium.capabilities.json b/demo/e2e/config/appium.capabilities.json index b2d3a21..55a7d0a 100644 --- a/demo/e2e/config/appium.capabilities.json +++ b/demo/e2e/config/appium.capabilities.json @@ -40,10 +40,10 @@ "android24": { "platformName": "Android", "platformVersion": "7.0", - "deviceName": "Emulator Api24 Google", + "deviceName": "Android GoogleAPI Emulator", "lt": 60000, - "appActivity": "com.tns.NativeScriptActivity", "newCommandTimeout": 720, + "appiumVersion": "1.7.1", "noReset": true, "fullReset": false, "app": "" @@ -112,13 +112,24 @@ "fullReset": false, "app": "" }, - "sim.iPhone8.iOS11.2": { + "sim.iPhoneX.iOS12": { "platformName": "iOS", - "platformVersion": "11.2", - "deviceName": "iPhone 8", + "platformVersion": "12.0", + "deviceName": "iPhone X", "noReset": true, "fullReset": false, - "appiumVersion": "1.7.1", - "app": "" + "app": "", + "density":3, + "offsetPixels":87 + }, + "sim.iPhoneX.iOS12.1": { + "platformName": "iOS", + "platformVersion": "12.1", + "deviceName": "iPhone X", + "noReset": true, + "fullReset": false, + "app": "", + "density":3, + "offsetPixels":87 } } \ No newline at end of file diff --git a/demo/e2e/tests.e2e.ts b/demo/e2e/tests.e2e.ts index ab8e512..6ecbebe 100644 --- a/demo/e2e/tests.e2e.ts +++ b/demo/e2e/tests.e2e.ts @@ -49,15 +49,17 @@ describe("Camera", () => { await images[4].click(); } else { let ok = await driver.findElementByTextIfExists("OK", SearchOptions.exact); - if (ok !== undefined) { - await ok.click(); - ok = await driver.findElementByTextIfExists("OK", SearchOptions.exact); + if(ok !== undefined){ await ok.click(); + let okBtn = await driver.findElementByTextIfExists("OK", SearchOptions.exact); + await okBtn.click(); } + let photos = await driver.findElementByText("Photos", SearchOptions.exact); + expect(photos).to.exist; await driver.wait(2000); - await driver.clickPoint(50, 100); // Select directory + await driver.clickPoint(50, 110); // Select directory await driver.wait(2000); - await driver.clickPoint(50, 150); // Select image + await driver.clickPoint(50, 240); // Select image } const saveToGalleryLabel = await driver.findElementByText("saveToGallery"); expect(saveToGalleryLabel).to.exist; diff --git a/demo/package.json b/demo/package.json index 13a729a..abd7102 100644 --- a/demo/package.json +++ b/demo/package.json @@ -17,15 +17,23 @@ "ci.tslint": "npm i && tslint --config '../tslint.json' 'app/**/*.ts' --exclude '**/node_modules/**'", "generate-android-snapshot": "generate-android-snapshot --targetArchs arm,arm64,ia32 --install", "e2e": "tsc -p e2e && mocha --opts ./e2e/config/mocha.opts", - "compile-tests": "tsc -p e2e --watch" + "compile-tests": "tsc -p e2e --watch", + "ci.android.build": "cd ../src && npm run build && cd ../demo && tns build android", + "ci.ios.build": "cd ../src && npm run build && cd ../demo && tns build ios" }, "dependencies": { "nativescript-camera": "../src", "tns-core-modules": "^5.1.0" }, "devDependencies": { + "@types/chai": "~4.1.7", + "@types/mocha": "~5.2.5", + "@types/node": "~10.12.18", + "mocha": "~5.2.0", + "mocha-junit-reporter": "~1.18.0", + "mocha-multi": "~1.0.1", "nativescript-css-loader": "~0.26.1", - "nativescript-dev-appium": "3.2.0", + "nativescript-dev-appium": "4.0.9", "nativescript-dev-typescript": "~0.7.0", "nativescript-dev-webpack": "~0.18.0", "tslint": "~5.11.0"