diff --git a/README.md b/README.md index 19393cf..e6d61c1 100644 --- a/README.md +++ b/README.md @@ -1 +1,9 @@ # node-appium-app-browserstack +App Automate Node Samples +--------------------- + +This repository contains code for Automated Native App tests. Please feel free to clone the repo and use the example code. + +For frameworks integration with BrowserStack, refer to their individual repositories - + +- [WebdriverIO](https://github.com/browserstack/webdriverio-appium-app-browserstack) diff --git a/android/README.md b/android/README.md new file mode 100644 index 0000000..eb81984 --- /dev/null +++ b/android/README.md @@ -0,0 +1,27 @@ + +For installing the node `wd` driver, + +``` +$ npm install wd +``` + +## Running your tests + +- Do remember to switch the BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY with your own browserstack credentials. +- Upload your Native App (.apk file) to BrowserStack servers using upload API and update the app capability: + + ``` + curl -u "username:accesskey" -X POST "https://api.browserstack.com/app-automate/upload" -F "file=@/path/to/app/file/Application-debug.apk" + ``` + +- If you do not have an .apk file and looking to simply try App Automate, you can download our [sample app](https://www.browserstack.com/app-automate/sample-apps/android/WikipediaSample.apk) and upload to the BrowserStack servers using the above API. +- For LocalSample tests, you can use our [local sample app](https://www.browserstack.com/app-automate/sample-apps/android/LocalSample.apk). +- Update the desired capability "app" with the App URL returned from the above API call + +## Notes +* You can view your test results on the [BrowserStack App Automate dashboard](https://www.browserstack.com/app-automate) +* Refer [Get Started](https://www.browserstack.com/app-automate/appium-node) document to configure the capabilities + +For frameworks integration with BrowserStack, refer to their individual repositories - + +- [WebdriverIO](https://github.com/browserstack/webdriverio-appium-app-browserstack) diff --git a/android/localTest.js b/android/localTest.js new file mode 100644 index 0000000..df02d75 --- /dev/null +++ b/android/localTest.js @@ -0,0 +1,45 @@ +var wd = require('wd'); +var assert = require('assert'); +var asserters = wd.asserters; +var Q = wd.Q; + +desiredCaps = { + 'browserstack.user' : 'BROWSERSTACK_USERNAME', + 'browserstack.key' : 'BROWSERSTACK_ACCESS_KEY', + 'build' : 'Node Android', + 'name': 'local_test', + 'device' : 'Google Pixel', + 'app' : 'bs://', + 'browserstack.debug' : true, + 'browserstack.local' : true, + 'realMobile' : true +}; + +driver = wd.promiseRemote("http://hub.browserstack.com/wd/hub"); + +driver + .init(desiredCaps) + .then(function () { + return driver.waitForElementById('com.example.android.basicnetworking:id/test_action', asserters.isDisplayed && asserters.isEnabled, 30000); + }) + .then(function (testElement) { + return testElement.click(); + }) + .then(function () { + return driver.waitForElementsByClassName('android.widget.TextView', asserters.isDisplayed, 30000); + }) + .then(function (textElements) { + return Q().then(function () { + return textElements.map(function (textElement) { + return textElement.text().then(function(value) { + if (value.indexOf('The active connection is') !== -1) { + console.log(value); + assert(value.indexOf('The active connection is wifi') !== -1); + assert(value.indexOf('Up and running') !== -1); + } + }); + }) + }).all() + }) + .fin(function() { return driver.quit(); }) + .done(); diff --git a/android/singleTest.js b/android/singleTest.js new file mode 100644 index 0000000..a68ca71 --- /dev/null +++ b/android/singleTest.js @@ -0,0 +1,38 @@ +var wd = require('wd'); +var assert = require('assert'); +var asserters = wd.asserters; + +desiredCaps = { + 'browserstack.user' : 'BROWSERSTACK_USERNAME', + 'browserstack.key' : 'BROWSERSTACK_ACCESS_KEY', + 'build' : 'Node Android', + 'name': 'single_test', + 'device' : 'Google Pixel', + 'app' : 'bs://', + 'browserstack.debug' : true, + 'realMobile' : true +}; +driver = wd.promiseRemote("http://hub.browserstack.com/wd/hub"); + +driver + .init(desiredCaps) + .then(function () { + return driver.waitForElementById('Search Wikipedia', asserters.isDisplayed && asserters.isEnabled, 30000); + }) + .then(function (searchElement) { + return searchElement.click(); + }) + .then(function () { + return driver.waitForElementById('org.wikipedia.alpha:id/search_src_text', asserters.isDisplayed && asserters.isEnabled, 30000); + }) + .then(function (searchInput) { + return searchInput.sendKeys("BrowserStack"); + }) + .then(function () { + return driver.elementsByClassName('android.widget.TextView'); + }) + .then(function (search_results) { + assert(search_results.length > 0); + }) + .fin(function() { return driver.quit(); }) + .done(); diff --git a/ios/README.md b/ios/README.md new file mode 100644 index 0000000..4e7e15c --- /dev/null +++ b/ios/README.md @@ -0,0 +1,27 @@ + +For installing the node `wd` driver, + +``` +$ npm install wd +``` + +## Running your tests + +- Do remember to switch the BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY with your own browserstack credentials. +- Upload your Native App (.ipa file) to BrowserStack servers using upload API and update the app capability: + + ``` + curl -u "username:accesskey" -X POST "https://api.browserstack.com/app-automate/upload" -F "file=@/path/to/app/file/Application-debug.ipa" + ``` + +- If you do not have an .ipa file and looking to simply try App Automate, you can download our [sample app](https://www.browserstack.com/app-automate/sample-apps/ios/WordPressSample.ipa) and upload to the BrowserStack servers using the above API. +- For LocalSample tests, you can use our [local sample app](https://www.browserstack.com/app-automate/sample-apps/ios/LocalSample.ipa). +- Update the desired capability "app" with the App URL returned from the above API call + +## Notes +* You can view your test results on the [BrowserStack App Automate dashboard](https://www.browserstack.com/app-automate) +* Refer [Get Started](https://www.browserstack.com/app-automate/appium-node) document to configure the capabilities + +For frameworks integration with BrowserStack, refer to their individual repositories - + +- [WebdriverIO](https://github.com/browserstack/webdriverio-appium-app-browserstack) diff --git a/ios/localTest.js b/ios/localTest.js new file mode 100644 index 0000000..6b82d6f --- /dev/null +++ b/ios/localTest.js @@ -0,0 +1,52 @@ +var wd = require('wd'); +var assert = require('assert'); +var asserters = wd.asserters; +var Asserter = wd.Asserter; + +var chai = require("chai"); +var chaiAsPromised = require("chai-as-promised"); +chai.use(chaiAsPromised); +chai.should(); +chaiAsPromised.transferPromiseness = wd.transferPromiseness; + +desiredCaps = { + 'browserstack.user' : 'BROWSERSTACK_USERNAME', + 'browserstack.key' : 'BROWSERSTACK_ACCESS_KEY', + 'build' : 'Node iOS', + 'name': 'local_test', + 'device' : 'iPhone 7 Plus', + 'app' : 'bs://', + 'browserstack.debug' : true, + 'browserstack.local' : true, + 'realMobile' : true +}; + +var customTextNonEmpty = new Asserter( + function(target) { + return target + .text().then(function(text) { + text.should.have.length.above(0); + return text; + }) + .catch(tagChaiAssertionError); + } +); + +driver = wd.promiseRemote("http://hub.browserstack.com/wd/hub"); + +driver + .init(desiredCaps) + .then(function () { + return driver.waitForElementById('TestBrowserStackLocal', asserters.isDisplayed && asserters.isEnabled, 30000); + }) + .then(function (testElement) { + return testElement.click(); + }) + .then(function () { + return driver.waitForElementById('ResultBrowserStackLocal', asserters.isDisplayed, 30000); + }) + .then(function (resultElement) { + return resultElement.text().should.eventually.include('Up and running'); + }) + .fin(function() { return driver.quit(); }) + .done(); diff --git a/ios/singleTest.js b/ios/singleTest.js new file mode 100644 index 0000000..663c8ff --- /dev/null +++ b/ios/singleTest.js @@ -0,0 +1,57 @@ +var wd = require('wd'); +var assert = require('assert'); +var asserters = wd.asserters; +var sleep = require('sleep'); +var Q = wd.Q; + +desiredCaps = { + 'browserstack.user' : 'BROWSERSTACK_USERNAME', + 'browserstack.key' : 'BROWSERSTACK_ACCESS_KEY', + 'build' : 'Node iOS', + 'name': 'single_test', + 'device' : 'iPhone 7 Plus', + 'app' : 'bs://', + 'browserstack.debug' : true, + 'realMobile' : true +}; +driver = wd.promiseRemote("http://hub.browserstack.com/wd/hub"); + +driver + .init(desiredCaps) + .then(function () { + return driver.waitForElementById('Log In', asserters.isDisplayed && asserters.isEnabled, 30000); + }) + .then(function (loginButton) { + return loginButton.click(); + }) + .then(function () { + return driver.waitForElementById('Email address', asserters.isDisplayed && asserters.isEnabled, 30000); + }) + .then(function (emailInput) { + return emailInput.sendKeys("hello@browserstack.com"); + }) + .then(function () { + return driver.waitForElementById('Next', asserters.isDisplayed, 30000); + }) + .then(function (nextButton) { + return nextButton.click().then(function() { + sleep.sleep(5); + }); + }) + .then(function() { + return driver.waitForElementsByXPath("//XCUIElementTypeStaticText", asserters.isDisplayed, 30000); + }) + .then(function (textElements) { + return Q().then(function () { + return textElements.map(function (textElement) { + return textElement.text().then(function(value) { + if (value.indexOf('not registered') !== -1) { + console.log(value); + assert(value.indexOf('This email address is not registered on WordPress.com') !== -1); + } + }); + }) + }).all() + }) + .fin(function() { return driver.quit(); }) + .done();