diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..10ba245 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*/local.log +*/browserstack.err +*/**.pyc diff --git a/README.md b/README.md index 42e89bb..49c4e55 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,108 @@ # python-appium-app-browserstack -App Automate Python Samples ---------------------- -This repository contains code for Automated Native App tests. Please feel free to clone the repo and use the example code. -Refer [Getting Started with App Automate](https://www.browserstack.com/app-automate/appium-python) for more details. +This repository demonstrates how to run Appium tests using Python on BrowserStack App Automate. + +## Setup + +### Requirements + +1. Python 3.6+ or Python 2.7+ + + - If Python is not installed, follow these instructions: + - For Windows, download latest python version from [here](https://www.python.org/downloads/windows/) and run the installer executable + - For Mac and Linux, run `python --version` to see what python version is pre-installed. If you want a different version download from [here](https://www.python.org/downloads/) + +2. Package Manager `pip` + + Note : `pip` comes installed with Python 2.7.9+ and python 3.4+ + + - If `pip` is not installed, follow these instructions: + - Securely download get-pip.py by following this link: [get-pip.py](https://bootstrap.pypa.io/get-pip.py) or use following cURL command to download it: + + ```sh + curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py + ``` + + - After dowloading, run the file : + + - For Python 3 + + ```sh + python3 get-pip.py + ``` + + - For Python 2 + + ```sh + python2 get-pip.py + ``` + +### Install the dependencies + +To install the dependencies for Android tests, run : + +- For Python 3 + + ```sh + pip3 install -r android/requirements.txt + ``` + +- For Python 2 + + ```sh + pip2 install -r android/requirements.txt + ``` + +Or, + +To install the dependencies for iOS tests, run : + +- For Python 3 + + ```sh + pip3 install -r ios/requirements.txt + ``` + +- For Python 2 + + ```sh + pip2 install -r ios/requirements.txt + ``` + + +## Getting Started + +Getting Started with Appium tests in Python on real BrowserStack devices couldn't be easier! + +### **Run first test :** + +- Switch to `run-first-test` directory under [Android examples](android/examples/run-first-test) or [iOS examples](ios/examples/run-first-test) + +- Follow the steps outlined in the documentation [Getting Started with your first test on App Automate](https://www.browserstack.com/docs/app-automate/appium/getting-started/python) + +### **Speed up test execution with parallel testing :** + +- Switch to `run-prarallel-tests` directory under [Android examples](android/examples/run-parallel-tests) or [iOS examples](ios/examples/run-parallel-tests) + +- Follow the steps outlined in the documentation [Getting Started with Parallel testing on App Automate](https://www.browserstack.com/docs/app-automate/appium/getting-started/python/parallelize-tests) + +### **Use Local testing for apps that access resources hosted in development or testing environments :** + +- Switch to `run-local-test` directory under [Android examples](android/examples/run-local-test) or [iOS examples](ios/examples/run-local-test) + +- Follow the steps outlined in the documentation [Getting Started with Local testing on App Automate](https://www.browserstack.com/docs/app-automate/appium/getting-started/python/local-testing) + +**Note**: If you face any issues, refer [Getting Help section](#Getting-Help) + +## Integration with other python frameworks + +For other Python frameworks samples, refer to following repositories : -For frameworks integration with BrowserStack, refer to their individual repositories - -- [Lettuce](https://github.com/browserstack/lettuce-appium-app-browserstack) - [Behave](https://github.com/browserstack/behave-appium-app-browserstack) +- [Lettuce](https://github.com/browserstack/lettuce-appium-app-browserstack) + +Note: For other test frameworks supported by App-Automate refer our [Developer documentation](https://www.browserstack.com/docs/) + +## Getting Help -For python 2 support refer the branch -- [python-2-master](https://github.com/browserstack/python-appium-app-browserstack/tree/python-2-master) +If you are running into any issues or have any queries, please check [Browserstack Support page](https://www.browserstack.com/support/app-automate) or [get in touch with us](https://www.browserstack.com/contact?ref=help). \ No newline at end of file diff --git a/android/BrowserStackAndroid.py b/android/BrowserStackAndroid.py deleted file mode 100644 index f647e9b..0000000 --- a/android/BrowserStackAndroid.py +++ /dev/null @@ -1,32 +0,0 @@ -from appium import webdriver -from appium.webdriver.common.mobileby import MobileBy -from selenium.webdriver.support.ui import WebDriverWait -from selenium.webdriver.support import expected_conditions as EC -import time - -userName = "BROWSERSTACK_USERNAME" -accessKey = "BROWSERSTACK_ACCESS_KEY" - -desired_caps = { - "build": "Python 3 Android", - "device": "Samsung Galaxy S7", - "app": "bs://" -} - -driver = webdriver.Remote("http://" + userName + ":" + accessKey + "@hub-cloud.browserstack.com/wd/hub", desired_caps) - -search_element = WebDriverWait(driver, 30).until( - EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "Search Wikipedia")) -) -search_element.click() - -search_input = WebDriverWait(driver, 30).until( - EC.element_to_be_clickable((MobileBy.ID, "org.wikipedia.alpha:id/search_src_text")) -) -search_input.send_keys("BrowserStack") -time.sleep(5) - -search_results = driver.find_elements_by_class_name("android.widget.TextView") -assert(len(search_results) > 0) - -driver.quit() diff --git a/android/LocalSampleAndroid.py b/android/LocalSampleAndroid.py deleted file mode 100644 index f0d953f..0000000 --- a/android/LocalSampleAndroid.py +++ /dev/null @@ -1,55 +0,0 @@ -from appium import webdriver -from appium.webdriver.common.mobileby import MobileBy -from selenium.webdriver.support.ui import WebDriverWait -from selenium.webdriver.support import expected_conditions as EC -from browserstack.local import Local -import time - -userName = "BROWSERSTACK_USERNAME" -accessKey = "BROWSERSTACK_ACCESS_KEY" - -desired_caps = { - "build": "Python 3 Android Local", - "device": "Samsung Galaxy S7", - "browserstack.local": True, - "app": "bs://" -} - -bs_local = None - -def start_local(): - global bs_local - bs_local = Local() - bs_local_args = { "key": accessKey, "forcelocal": "true" } - bs_local.start(**bs_local_args) - -def stop_local(): - global bs_local - bs_local.stop() - -start_local() -driver = webdriver.Remote("http://" + userName + ":" + accessKey + "@hub-cloud.browserstack.com/wd/hub", desired_caps) -test_button = WebDriverWait(driver, 30).until( - EC.element_to_be_clickable((MobileBy.ID, "com.example.android.basicnetworking:id/test_action")) -) -test_button.click() -WebDriverWait(driver, 30).until( - EC.element_to_be_clickable((MobileBy.CLASS_NAME, "android.widget.TextView")) -) - -test_element = None -search_results = driver.find_elements_by_class_name("android.widget.TextView") -for result in search_results: - if result.text.__contains__("The active connection is"): - test_element = result - -if test_element is None: - raise Exception("Cannot find the needed TextView element from app") - -matched_string = test_element.text -print (matched_string) -assert(matched_string.__contains__("The active connection is wifi")) -assert(matched_string.__contains__("Up and running")) - -driver.quit() -stop_local() diff --git a/android/README.md b/android/README.md deleted file mode 100644 index 0e4aaa6..0000000 --- a/android/README.md +++ /dev/null @@ -1,34 +0,0 @@ -## Dependencies - -For installing the required packages, use the following command - -``` -$ pip3 install -r requirements.txt -``` - -## 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. -- Run ```python3 BrowserStackAndroid.py``` -- For LocalSample tests, you can use our [local sample app](https://www.browserstack.com/app-automate/sample-apps/android/LocalSample.apk). -- Run ```python3 LocalSampleAndroid.py``` -- 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-python) document to configure the capabilities - -For frameworks integration with BrowserStack, refer to their individual repositories - - -- [Lettuce](https://github.com/browserstack/lettuce-appium-app-browserstack) -- [Behave](https://github.com/browserstack/behave-appium-app-browserstack) - -For python 2 support refer the branch -- [python-2-master](https://github.com/browserstack/python-appium-app-browserstack/tree/python-2-master) diff --git a/android/examples/run-first-test/config.json b/android/examples/run-first-test/config.json new file mode 100644 index 0000000..1ed5a60 --- /dev/null +++ b/android/examples/run-first-test/config.json @@ -0,0 +1,15 @@ +{ + "server": "hub-cloud.browserstack.com", + "username":"BROWSERSTACK_USERNAME", + "access_key":"BROWSERSTACK_ACCESS_KEY", + + "capabilities": { + "project": "First Python Android Project", + "build": "Python Android", + "name": "first_test", + "browserstack.debug": true, + "app": "bs://", + "device": "Google Pixel 3", + "os_version": "9.0" + } +} diff --git a/android/examples/run-first-test/first_test.py b/android/examples/run-first-test/first_test.py new file mode 100644 index 0000000..ef2e0dd --- /dev/null +++ b/android/examples/run-first-test/first_test.py @@ -0,0 +1,52 @@ +from appium import webdriver +from appium.webdriver.common.mobileby import MobileBy +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +import time +import os, json + +config_file_path = os.path.join(os.path.dirname(__file__), "config.json") +print("Path to the config file: %s" % (config_file_path)) +with open(config_file_path) as config_file: + CONFIG = json.load(config_file) + +BROWSERSTACK_USERNAME = os.environ['BROWSERSTACK_USERNAME'] if 'BROWSERSTACK_USERNAME' in os.environ else CONFIG['username'] +BROWSERSTACK_ACCESS_KEY = os.environ['BROWSERSTACK_ACCESS_KEY'] if 'BROWSERSTACK_ACCESS_KEY' in os.environ else CONFIG['access_key'] + +def test(): + """ + Test for BrowserStack sample Wikipedia Android app. + Note: If you have uploaded your app to BrowserStack update the test here. + """ + + desired_capabilities = CONFIG['capabilities'] + + driver = webdriver.Remote( + desired_capabilities = desired_capabilities, + command_executor = "http://%s:%s@%s/wd/hub" % (BROWSERSTACK_USERNAME, BROWSERSTACK_ACCESS_KEY, CONFIG['server']) + ) + + search_element = WebDriverWait(driver, 30).until ( + EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "Search Wikipedia")) + ) + + search_element.click() + + search_input = WebDriverWait(driver, 30).until ( + EC.element_to_be_clickable((MobileBy.ID, "org.wikipedia.alpha:id/search_src_text")) + ) + + search_input.send_keys("BrowserStack" + "\n") + + time.sleep(5) + + search_results = driver.find_elements_by_class_name("android.widget.TextView") + + assert(len(search_results) > 0) + + driver.quit() + + +if __name__ == "__main__": + test() + diff --git a/android/examples/run-local-test/config.json b/android/examples/run-local-test/config.json new file mode 100644 index 0000000..f370371 --- /dev/null +++ b/android/examples/run-local-test/config.json @@ -0,0 +1,16 @@ +{ + "server": "hub-cloud.browserstack.com", + "username":"BROWSERSTACK_USERNAME", + "access_key":"BROWSERSTACK_ACCESS_KEY", + + "capabilities": { + "project": "First Python Android Project", + "build": "Python Android Local", + "name": "local_test", + "browserstack.debug": true, + "app": "bs://", + "device": "Google Pixel 3", + "os_version": "9.0", + "browserstack.local": true + } +} diff --git a/android/examples/run-local-test/local_test.py b/android/examples/run-local-test/local_test.py new file mode 100644 index 0000000..7a05e5a --- /dev/null +++ b/android/examples/run-local-test/local_test.py @@ -0,0 +1,70 @@ +from appium import webdriver +from appium.webdriver.common.mobileby import MobileBy +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from browserstack.local import Local +import time +import os, json + +config_file_path = os.path.join(os.path.dirname(__file__), "config.json") +print("Path to the config file: %s" % (config_file_path)) +with open(config_file_path) as config_file: + CONFIG = json.load(config_file) + +BROWSERSTACK_USERNAME = os.environ['BROWSERSTACK_USERNAME'] if 'BROWSERSTACK_USERNAME' in os.environ else CONFIG['username'] +BROWSERSTACK_ACCESS_KEY = os.environ['BROWSERSTACK_ACCESS_KEY'] if 'BROWSERSTACK_ACCESS_KEY' in os.environ else CONFIG['access_key'] + +def start_local(): + global bs_local + bs_local = Local() + bs_local_args = { "key": BROWSERSTACK_ACCESS_KEY, "forcelocal": "true" } + bs_local.start(**bs_local_args) + +def stop_local(): + global bs_local + bs_local.stop() + +def test(): + """ + Test for BrowserStack's sample local Android app. + Note: If you have uploaded your app to BrowserStack update the test here. + """ + + start_local() + + desired_capabilities = CONFIG['capabilities'] + + driver = webdriver.Remote( + desired_capabilities = desired_capabilities, + command_executor = "http://%s:%s@%s/wd/hub" % (BROWSERSTACK_USERNAME, BROWSERSTACK_ACCESS_KEY, CONFIG['server']) + ) + + test_button = WebDriverWait(driver, 30).until( + EC.element_to_be_clickable((MobileBy.ID, "com.example.android.basicnetworking:id/test_action")) + ) + test_button.click() + WebDriverWait(driver, 30).until( + EC.element_to_be_clickable((MobileBy.CLASS_NAME, "android.widget.TextView")) + ) + + test_element = None + search_results = driver.find_elements_by_class_name("android.widget.TextView") + for result in search_results: + if result.text.__contains__("The active connection is"): + test_element = result + + if test_element is None: + raise Exception("Cannot find the needed TextView element from app") + + matched_string = test_element.text + print (matched_string) + assert(matched_string.__contains__("The active connection is wifi")) + assert(matched_string.__contains__("Up and running")) + + driver.quit() + + stop_local() + + +if __name__ == "__main__": + test() diff --git a/android/examples/run-parallel-tests/config.json b/android/examples/run-parallel-tests/config.json new file mode 100644 index 0000000..b26fa16 --- /dev/null +++ b/android/examples/run-parallel-tests/config.json @@ -0,0 +1,22 @@ +{ + "server": "hub-cloud.browserstack.com", + "username":"BROWSERSTACK_USERNAME", + "access_key":"BROWSERSTACK_ACCESS_KEY", + + "capabilities": { + "project": "First Python Android Project", + "build": "Python Android Parallel", + "name": "parallel_test", + "browserstack.debug": true, + "app": "bs://" + }, + + "environments": [{ + "device": "Google Pixel 3", + "os_version": "9.0" + }, + { + "device": "Samsung Galaxy S10e", + "os_version": "9.0" + }] +} diff --git a/android/examples/run-parallel-tests/parallel_tests.py b/android/examples/run-parallel-tests/parallel_tests.py new file mode 100644 index 0000000..327131d --- /dev/null +++ b/android/examples/run-parallel-tests/parallel_tests.py @@ -0,0 +1,60 @@ +from appium import webdriver +from appium.webdriver.common.mobileby import MobileBy +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +import time +import os, json, threading + + +config_file_path = os.path.join(os.path.dirname(__file__), "config.json") +print("Path to the config file: %s" % (config_file_path)) +with open(config_file_path) as config_file: + CONFIG = json.load(config_file) + +BROWSERSTACK_USERNAME = os.environ['BROWSERSTACK_USERNAME'] if 'BROWSERSTACK_USERNAME' in os.environ else CONFIG['username'] +BROWSERSTACK_ACCESS_KEY = os.environ['BROWSERSTACK_ACCESS_KEY'] if 'BROWSERSTACK_ACCESS_KEY' in os.environ else CONFIG['access_key'] + +def test(device_index): + """ + Test for BrowserStack sample Wikipedia Android app. + Note: If you have uploaded your app to BrowserStack update the test here. + """ + + desired_capabilities = CONFIG['capabilities'] + desired_capabilities['device'] = CONFIG['environments'][device_index]['device'] + + driver = webdriver.Remote( + desired_capabilities = dict(desired_capabilities), + command_executor = "http://%s:%s@%s/wd/hub" % (BROWSERSTACK_USERNAME, BROWSERSTACK_ACCESS_KEY, CONFIG['server']) + ) + + search_element = WebDriverWait(driver, 30).until ( + EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "Search Wikipedia")) + ) + + search_element.click() + + search_input = WebDriverWait(driver, 30).until ( + EC.element_to_be_clickable((MobileBy.ID, "org.wikipedia.alpha:id/search_src_text")) + ) + search_input.send_keys("BrowserStack" + "\n") + + time.sleep(5) + + search_results = driver.find_elements_by_class_name("android.widget.TextView") + + assert(len(search_results) > 0) + + driver.quit() + + +if __name__ == "__main__": + jobs = [] + for index in range(2): + thread = threading.Thread(target=test,args=(index,)) + jobs.append(thread) + thread.start() + + for thread in jobs: + thread.join() + diff --git a/android/requirements.txt b/android/requirements.txt index 2aabad0..7becfd4 100644 --- a/android/requirements.txt +++ b/android/requirements.txt @@ -1,3 +1,4 @@ -Appium-Python-Client -browserstack-local -selenium +Appium-Python-Client==0.52;python_version < '3.0' +Appium-Python-Client==1.0.2;python_version >= '3.0' +browserstack-local==1.2.2 +selenium==3.14.0 diff --git a/ios/BrowserStackIOS.py b/ios/BrowserStackIOS.py deleted file mode 100644 index 4b27e43..0000000 --- a/ios/BrowserStackIOS.py +++ /dev/null @@ -1,39 +0,0 @@ -from appium import webdriver -from appium.webdriver.common.mobileby import MobileBy -from selenium.webdriver.support.ui import WebDriverWait -from selenium.webdriver.support import expected_conditions as EC -import time - -userName = "BROWSERSTACK_USERNAME" -accessKey = "BROWSERSTACK_ACCESS_KEY" - -desired_caps = { - "build": "Python 3 iOS", - "device": "iPhone 7", - "app": "bs://" -} - -driver = webdriver.Remote("http://" + userName + ":" + accessKey + "@hub-cloud.browserstack.com/wd/hub", desired_caps) - -text_button = WebDriverWait(driver, 30).until( - EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "Text Button")) -) -text_button.click() - -text_input = WebDriverWait(driver, 30).until( - EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "Text Input")) -) -text_input.send_keys("hello@browserstack.com"+"\n") - -time.sleep(5) - -text_output = WebDriverWait(driver, 30).until( - EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "Text Output")) -) - -if text_output!=None and text_output.text=="hello@browserstack.com": - assert True -else: - assert False - -driver.quit() \ No newline at end of file diff --git a/ios/LocalSampleIOS.py b/ios/LocalSampleIOS.py deleted file mode 100644 index 3d90f1a..0000000 --- a/ios/LocalSampleIOS.py +++ /dev/null @@ -1,55 +0,0 @@ -from appium import webdriver -from appium.webdriver.common.mobileby import MobileBy -from selenium.webdriver.support.ui import WebDriverWait -from selenium.webdriver.support import expected_conditions as EC -from browserstack.local import Local -import os - -userName = "BROWSERSTACK_USERNAME" -accessKey = "BROWSERSTACK_ACCESS_KEY" - -desired_caps = { - "build": "Python 3 iOS Local", - "device": "iPhone 7", - "browserstack.local": True, - "app": "bs://" -} - -bs_local = None - -def start_local(): - global bs_local - bs_local = Local() - bs_local_args = { "key": accessKey, "forcelocal": "true" } - bs_local.start(**bs_local_args) - -def stop_local(): - global bs_local - bs_local.stop() - -def existence_lambda(s): - result = s.find_element_by_accessibility_id("ResultBrowserStackLocal").get_attribute("value") - return result and len(result) > 0 - -start_local() -driver = webdriver.Remote("http://" + userName + ":" + accessKey + "@hub-cloud.browserstack.com/wd/hub", desired_caps) - -test_button = WebDriverWait(driver, 30).until( - EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "TestBrowserStackLocal")) -) -test_button.click() - -WebDriverWait(driver, 30).until(existence_lambda) -result_element = driver.find_element_by_accessibility_id("ResultBrowserStackLocal") -result_string = result_element.text.lower() - -if result_string.__contains__("not working"): - screenshot_file = "%s/screenshot.png" % os.getcwd() - driver.save_screenshot(screenshot_file) - print ("Screenshot stored at %s" % screenshot_file) - print ("Unexpected BrowserStackLocal test result") -else: - assert(result_string.__contains__("up and running")) - -driver.quit() -stop_local() diff --git a/ios/README.md b/ios/README.md deleted file mode 100644 index ecf1540..0000000 --- a/ios/README.md +++ /dev/null @@ -1,34 +0,0 @@ -## Dependencies - -For installing the required packages, use the following command - -``` -$ pip3 install -r requirements.txt -``` - -## 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/BStackSampleApp.ipa) and upload to the BrowserStack servers using the above API. -- Update the desired capability "app" with the App URL returned from the above API call -- Run ```python3 BrowserStackIOS.py``` -- For LocalSample tests, you can use our [local sample app](https://www.browserstack.com/app-automate/sample-apps/ios/LocalSample.ipa). -- Run ```python3 LocalSampleIOS.py``` for local testing - -## 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-python) document to configure the capabilities - -For frameworks integration with BrowserStack, refer to their individual repositories - - -- [Lettuce](https://github.com/browserstack/lettuce-appium-app-browserstack) -- [Behave](https://github.com/browserstack/behave-appium-app-browserstack) - -For python 2 support refer the branch -- [python-2-master](https://github.com/browserstack/python-appium-app-browserstack/tree/python-2-master) diff --git a/ios/examples/run-first-test/config.json b/ios/examples/run-first-test/config.json new file mode 100644 index 0000000..f651a6e --- /dev/null +++ b/ios/examples/run-first-test/config.json @@ -0,0 +1,15 @@ +{ + "server": "hub-cloud.browserstack.com", + "username":"BROWSERSTACK_USERNAME", + "access_key":"BROWSERSTACK_ACCESS_KEY", + + "capabilities": { + "project": "First Python iOS Project", + "build": "Python iOS", + "name": "first_test", + "browserstack.debug": true, + "app": "bs://", + "device": "iPhone 11 Pro", + "os_version": "13" + } +} diff --git a/ios/examples/run-first-test/first_test.py b/ios/examples/run-first-test/first_test.py new file mode 100644 index 0000000..aeba666 --- /dev/null +++ b/ios/examples/run-first-test/first_test.py @@ -0,0 +1,55 @@ +from appium import webdriver +from appium.webdriver.common.mobileby import MobileBy +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +import time +import os, json + +config_file_path = os.path.join(os.path.dirname(__file__), "config.json") +print("Path to the config file: %s" % (config_file_path)) +with open(config_file_path) as config_file: + CONFIG = json.load(config_file) + +BROWSERSTACK_USERNAME = os.environ['BROWSERSTACK_USERNAME'] if 'BROWSERSTACK_USERNAME' in os.environ else CONFIG['username'] +BROWSERSTACK_ACCESS_KEY = os.environ['BROWSERSTACK_ACCESS_KEY'] if 'BROWSERSTACK_ACCESS_KEY' in os.environ else CONFIG['access_key'] + +def test(): + """ + Test for BrowserStack sample iOS app. + Note: If you have uploaded your app to BrowserStack update the test here. + """ + + desired_capabilities = CONFIG['capabilities'] + + driver = webdriver.Remote( + desired_capabilities = desired_capabilities, + command_executor = "http://%s:%s@%s/wd/hub" % (BROWSERSTACK_USERNAME, BROWSERSTACK_ACCESS_KEY, CONFIG['server']) + ) + + text_button = WebDriverWait(driver, 30).until( + EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "Text Button")) + ) + + text_button.click() + + text_input = WebDriverWait(driver, 30).until( + EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "Text Input")) + ) + text_input.send_keys("hello@browserstack.com"+"\n") + + time.sleep(5) + + text_output = WebDriverWait(driver, 30).until( + EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "Text Output")) + ) + + if text_output!=None and text_output.text=="hello@browserstack.com": + assert True + else: + assert False + + driver.quit() + + +if __name__ == "__main__": + test() diff --git a/ios/examples/run-local-test/config.json b/ios/examples/run-local-test/config.json new file mode 100644 index 0000000..cf12095 --- /dev/null +++ b/ios/examples/run-local-test/config.json @@ -0,0 +1,16 @@ +{ + "server": "hub-cloud.browserstack.com", + "username":"BROWSERSTACK_USERNAME", + "access_key":"BROWSERSTACK_ACCESS_KEY", + + "capabilities": { + "project": "First Python iOS Project", + "build": "Python iOS Local", + "name": "local_test", + "browserstack.debug": true, + "app": "bs://", + "device": "iPhone 11 Pro", + "os_version": "13", + "browserstack.local": true + } +} diff --git a/ios/examples/run-local-test/local_test.py b/ios/examples/run-local-test/local_test.py new file mode 100644 index 0000000..1d7cb2a --- /dev/null +++ b/ios/examples/run-local-test/local_test.py @@ -0,0 +1,69 @@ +from appium import webdriver +from appium.webdriver.common.mobileby import MobileBy +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from browserstack.local import Local +import time +import os, json + +config_file_path = os.path.join(os.path.dirname(__file__), "config.json") +print("Path to the config file: %s" % (config_file_path)) +with open(config_file_path) as config_file: + CONFIG = json.load(config_file) + +BROWSERSTACK_USERNAME = os.environ['BROWSERSTACK_USERNAME'] if 'BROWSERSTACK_USERNAME' in os.environ else CONFIG['username'] +BROWSERSTACK_ACCESS_KEY = os.environ['BROWSERSTACK_ACCESS_KEY'] if 'BROWSERSTACK_ACCESS_KEY' in os.environ else CONFIG['access_key'] + +def start_local(): + global bs_local + bs_local = Local() + bs_local_args = { "key": BROWSERSTACK_ACCESS_KEY, "forcelocal": "true" } + bs_local.start(**bs_local_args) + +def stop_local(): + global bs_local + bs_local.stop() + +def existence_lambda(s): + result = s.find_element_by_accessibility_id("ResultBrowserStackLocal").get_attribute("value") + return result and len(result) > 0 + +def test(): + """ + Test for BrowserStack's sample local iOS app. + Note: If you have uploaded your app to BrowserStack update the test here. + """ + + start_local() + + desired_capabilities = CONFIG['capabilities'] + + driver = webdriver.Remote( + desired_capabilities = desired_capabilities, + command_executor = "http://%s:%s@%s/wd/hub" % (BROWSERSTACK_USERNAME, BROWSERSTACK_ACCESS_KEY, CONFIG['server']) + ) + + test_button = WebDriverWait(driver, 30).until( + EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "TestBrowserStackLocal")) + ) + test_button.click() + + WebDriverWait(driver, 30).until(existence_lambda) + result_element = driver.find_element_by_accessibility_id("ResultBrowserStackLocal") + result_string = result_element.text.lower() + + if result_string.__contains__("not working"): + screenshot_file = "%s/screenshot.png" % os.getcwd() + driver.save_screenshot(screenshot_file) + print ("Screenshot stored at %s" % screenshot_file) + print ("Unexpected BrowserStackLocal test result") + else: + assert(result_string.__contains__("up and running")) + + driver.quit() + + stop_local() + + +if __name__ == "__main__": + test() diff --git a/ios/examples/run-parallel-tests/config.json b/ios/examples/run-parallel-tests/config.json new file mode 100644 index 0000000..a8e2fa1 --- /dev/null +++ b/ios/examples/run-parallel-tests/config.json @@ -0,0 +1,21 @@ +{ + "server": "hub-cloud.browserstack.com", + "username":"BROWSERSTACK_USERNAME", + "access_key":"BROWSERSTACK_ACCESS_KEY", + + "capabilities": { + "project": "First Python iOS Project", + "build": "Python iOS Parallel", + "name": "parallel_test", + "browserstack.debug": true, + "app": "bs://" + }, + + "environments": [{ + "device": "iPhone 11 Pro", + "os_version": "13" + }, { + "device": "iPhone 11 Pro Max", + "os_version": "13" + }] +} diff --git a/ios/examples/run-parallel-tests/parallel_test.py b/ios/examples/run-parallel-tests/parallel_test.py new file mode 100644 index 0000000..af4b3f2 --- /dev/null +++ b/ios/examples/run-parallel-tests/parallel_test.py @@ -0,0 +1,65 @@ +from appium import webdriver +from appium.webdriver.common.mobileby import MobileBy +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +import time +import os, json, threading + + +config_file_path = os.path.join(os.path.dirname(__file__), "config.json") +print("Path to the config file: %s" % (config_file_path)) +with open(config_file_path) as config_file: + CONFIG = json.load(config_file) + +BROWSERSTACK_USERNAME = os.environ['BROWSERSTACK_USERNAME'] if 'BROWSERSTACK_USERNAME' in os.environ else CONFIG['username'] +BROWSERSTACK_ACCESS_KEY = os.environ['BROWSERSTACK_ACCESS_KEY'] if 'BROWSERSTACK_ACCESS_KEY' in os.environ else CONFIG['access_key'] + +def test(device_index): + """ + Test for BrowserStack sample iOS app. + Note: If you have uploaded your app to BrowserStack update the test here. + """ + + desired_capabilities = CONFIG['capabilities'] + desired_capabilities['device'] = CONFIG['environments'][device_index]['device'] + + + driver = webdriver.Remote( + desired_capabilities = dict(desired_capabilities), + command_executor = "http://%s:%s@%s/wd/hub" % (BROWSERSTACK_USERNAME, BROWSERSTACK_ACCESS_KEY, CONFIG['server']) + ) + + text_button = WebDriverWait(driver, 30).until( + EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "Text Button")) + ) + + text_button.click() + + text_input = WebDriverWait(driver, 30).until( + EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "Text Input")) + ) + text_input.send_keys("hello@browserstack.com"+"\n") + + time.sleep(5) + + text_output = WebDriverWait(driver, 30).until( + EC.element_to_be_clickable((MobileBy.ACCESSIBILITY_ID, "Text Output")) + ) + + if text_output!=None and text_output.text=="hello@browserstack.com": + assert True + else: + assert False + + driver.quit() + + +if __name__ == "__main__": + jobs = [] + for index in range(2): + thread = threading.Thread(target=test,args=(index,)) + jobs.append(thread) + thread.start() + + for thread in jobs: + thread.join() diff --git a/ios/requirements.txt b/ios/requirements.txt index 2aabad0..7becfd4 100644 --- a/ios/requirements.txt +++ b/ios/requirements.txt @@ -1,3 +1,4 @@ -Appium-Python-Client -browserstack-local -selenium +Appium-Python-Client==0.52;python_version < '3.0' +Appium-Python-Client==1.0.2;python_version >= '3.0' +browserstack-local==1.2.2 +selenium==3.14.0