├── .github └── workflows │ ├── Semgrep.yml │ └── sanity-workflow.yml ├── CODEOWNERS ├── README.md ├── android ├── LocalSample.apk ├── WikipediaSample.apk ├── browserstack.yml ├── browserstack_sample.py └── browserstack_sample_local.py ├── ios ├── BStackSampleApp.ipa ├── LocalSample.ipa ├── browserstack.yml ├── browserstack_sample.py └── browserstack_sample_local.py └── requirements.txt /.github/workflows/Semgrep.yml: -------------------------------------------------------------------------------- 1 | # Name of this GitHub Actions workflow. 2 | name: Semgrep 3 | 4 | on: 5 | # Scan changed files in PRs (diff-aware scanning): 6 | # The branches below must be a subset of the branches above 7 | pull_request: 8 | branches: ["master", "main"] 9 | push: 10 | branches: ["master", "main"] 11 | schedule: 12 | - cron: '0 6 * * *' 13 | 14 | 15 | permissions: 16 | contents: read 17 | 18 | jobs: 19 | semgrep: 20 | # User definable name of this GitHub Actions job. 21 | permissions: 22 | contents: read # for actions/checkout to fetch code 23 | security-events: write # for github/codeql-action/upload-sarif to upload SARIF results 24 | name: semgrep/ci 25 | # If you are self-hosting, change the following `runs-on` value: 26 | runs-on: ubuntu-latest 27 | 28 | container: 29 | # A Docker image with Semgrep installed. Do not change this. 30 | image: returntocorp/semgrep 31 | 32 | # Skip any PR created by dependabot to avoid permission issues: 33 | if: (github.actor != 'dependabot[bot]') 34 | 35 | steps: 36 | # Fetch project source with GitHub Actions Checkout. 37 | - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 38 | # Run the "semgrep ci" command on the command line of the docker image. 39 | - run: semgrep ci --sarif --output=semgrep.sarif 40 | env: 41 | # Add the rules that Semgrep uses by setting the SEMGREP_RULES environment variable. 42 | SEMGREP_RULES: p/default # more at semgrep.dev/explore 43 | 44 | - name: Upload SARIF file for GitHub Advanced Security Dashboard 45 | uses: github/codeql-action/upload-sarif@6c089f53dd51dc3fc7e599c3cb5356453a52ca9e # v2.20.0 46 | with: 47 | sarif_file: semgrep.sarif 48 | if: always() -------------------------------------------------------------------------------- /.github/workflows/sanity-workflow.yml: -------------------------------------------------------------------------------- 1 | # This job is to test different maven profiles in sdk branch against full commit-id provided 2 | # This workflow targets Appium execution 3 | 4 | name: Python SDK Test workflow on workflow_dispatch 5 | 6 | on: 7 | workflow_dispatch: 8 | inputs: 9 | commit_sha: 10 | description: 'The full commit id to build' 11 | required: true 12 | 13 | jobs: 14 | comment-run: 15 | runs-on: ${{ matrix.os }} 16 | strategy: 17 | fail-fast: false 18 | max-parallel: 3 19 | matrix: 20 | python: ['3.7', '3.10', '3.11'] 21 | os: [ macos-latest, windows-latest, ubuntu-latest ] 22 | name: Python Appium Repo ${{ matrix.python }} - ${{ matrix.os }} Sample 23 | env: 24 | BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} 25 | BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} 26 | 27 | steps: 28 | - uses: actions/checkout@v3 29 | with: 30 | ref: ${{ github.event.inputs.commit_sha }} 31 | - uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 32 | id: status-check-in-progress 33 | env: 34 | job_name: Python Appium Repo ${{ matrix.python }} - ${{ matrix.os }} Sample 35 | commit_sha: ${{ github.event.inputs.commit_sha }} 36 | with: 37 | github-token: ${{ github.token }} 38 | script: | 39 | const result = await github.rest.checks.create({ 40 | owner: context.repo.owner, 41 | repo: context.repo.repo, 42 | name: process.env.job_name, 43 | head_sha: process.env.commit_sha, 44 | status: 'in_progress' 45 | }).catch((err) => ({status: err.status, response: err.response})); 46 | console.log(`The status-check response : ${result.status} Response : ${JSON.stringify(result.response)}`) 47 | if (result.status !== 201) { 48 | console.log('Failed to create check run') 49 | } 50 | - name: Setup python 51 | uses: actions/setup-python@v4 52 | with: 53 | python-version: ${{ matrix.python }} 54 | 55 | - name: Install dependencies 56 | run: python -m pip install -r requirements.txt 57 | 58 | - name: run tests in parallel on android 59 | run: | 60 | cd android 61 | browserstack-sdk python browserstack_sample.py 62 | 63 | - name: run local tests in parallel on android 64 | run: | 65 | cd android 66 | browserstack-sdk python browserstack_sample_local.py --browserstack.app "./LocalSample.apk" 67 | 68 | - name: run tests in parallel on ios 69 | run: | 70 | cd ios 71 | browserstack-sdk python browserstack_sample.py 72 | 73 | - name: run local tests in parallel on ios 74 | run: | 75 | cd ios 76 | browserstack-sdk python browserstack_sample_local.py --browserstack.app "./LocalSample.ipa" 77 | 78 | - if: always() 79 | uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 80 | id: status-check-completed 81 | env: 82 | conclusion: ${{ job.status }} 83 | job_name: Python Appium Repo ${{ matrix.python }} - ${{ matrix.os }} Sample 84 | commit_sha: ${{ github.event.inputs.commit_sha }} 85 | with: 86 | github-token: ${{ github.token }} 87 | script: | 88 | const result = await github.rest.checks.create({ 89 | owner: context.repo.owner, 90 | repo: context.repo.repo, 91 | name: process.env.job_name, 92 | head_sha: process.env.commit_sha, 93 | status: 'completed', 94 | conclusion: process.env.conclusion 95 | }).catch((err) => ({status: err.status, response: err.response})); 96 | console.log(`The status-check response : ${result.status} Response : ${JSON.stringify(result.response)}`) 97 | if (result.status !== 201) { 98 | console.log('Failed to create check run') 99 | } 100 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @browserstack/app-automate-public-repos 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python-appium-app-browserstack 2 | 3 | This repository demonstrates how to run Appium Python tests on BrowserStack App Automate. 4 | 5 | ## Based on 6 | 7 | These code samples are currently based on: 8 | 9 | - **Appium-Python-Client:** `2.6.1` 10 | - **Protocol:** `W3C` 11 | 12 | ## Setup 13 | 14 | ### Requirements 15 | 16 | 1. Python 3.7+ 17 | 18 | > **_NOTE:_** Since v1.0.0, only Python 3.7+ is supported. 19 | 20 | - For Windows, download latest python version from [here](https://www.python.org/downloads/windows/) and run the installer executable 21 | - 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/) 22 | 23 | 2. Package Manager pip 24 | 25 | Note : `pip` comes installed with python 3.4+ 26 | 27 | - If `pip` is not installed, follow these instructions: 28 | 29 | - 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: 30 | 31 | ```sh 32 | curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py 33 | ``` 34 | 35 | - After dowloading, run the file : 36 | 37 | - For Python 3 38 | 39 | ```sh 40 | python3 get-pip.py 41 | ``` 42 | 43 | ### Install the dependencies 44 | 45 | To install the dependencies, run the following command in project's base directory: 46 | 47 | - For Python 3 48 | 49 | ```sh 50 | pip3 install -r requirements.txt 51 | ``` 52 | 53 | ## Getting Started 54 | 55 | Getting Started with Appium tests in Python on BrowserStack couldn't be easier! 56 | 57 | ### **Run your first test :** 58 | 59 | Open `Android` or `iOS` folder : 60 | 61 | - If you have uploaded your app then add the app id to the `browserstack.yml` config file, or you can directly specify the path to your app in the `browserstack.yml` file. 62 | 63 | - Run `browserstack-sdk python browserstack_sample.py` 64 | 65 | - You can access the test execution results, and debugging information such as video recording, network logs on [App Automate dashboard](https://app-automate.browserstack.com/dashboard) 66 | 67 | --- 68 | 69 | ### **Use Local testing for apps that access resources hosted in development or testing environments :** 70 | 71 | Open `Android` or `iOS` folder : 72 | 73 | - Ensure that `browserstackLocal` capability is set to `true` in the `browserstack.yml` file 74 | 75 | - If you have uploaded your app then add the app id to the `browserstack.yml` config file, or you can directly specify the path to your app in the `browserstack.yml` file. 76 | 77 | - Run `browserstack-sdk python browserstack_sample_local.py` 78 | 79 | - You can access the test execution results, and debugging information such as video recording, network logs on [App Automate dashboard](https://app-automate.browserstack.com/dashboard) 80 | 81 | ## Integration with other python frameworks 82 | 83 | For other Python frameworks samples, refer to following repositories : 84 | 85 | - [Behave](https://github.com/browserstack/behave-appium-app-browserstack) 86 | - [Lettuce](https://github.com/browserstack/lettuce-appium-app-browserstack) 87 | 88 | Note: For other test frameworks supported by App-Automate refer our [Developer documentation](https://www.browserstack.com/docs/) 89 | 90 | ## Getting Help 91 | 92 | 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). 93 | -------------------------------------------------------------------------------- /android/LocalSample.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserstack/python-appium-app-browserstack/914a432dce645ba2556eb8d288c777adff587992/android/LocalSample.apk -------------------------------------------------------------------------------- /android/WikipediaSample.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserstack/python-appium-app-browserstack/914a432dce645ba2556eb8d288c777adff587992/android/WikipediaSample.apk -------------------------------------------------------------------------------- /android/browserstack.yml: -------------------------------------------------------------------------------- 1 | # ============================= 2 | # Set BrowserStack Credentials 3 | # ============================= 4 | # Add your BrowserStack userName and acccessKey here or set BROWSERSTACK_USERNAME and 5 | # BROWSERSTACK_ACCESS_KEY as env variables 6 | userName: BROWSERSTACK_USERNAME 7 | accessKey: BROWSERSTACK_ACCESS_KEY 8 | 9 | # ====================== 10 | # BrowserStack Reporting 11 | # ====================== 12 | # The following capabilities are used to set up reporting on BrowserStack: 13 | # Set 'projectName' to the name of your project. Example, Marketing Website 14 | projectName: BrowserStack Samples 15 | # Set `buildName` as the name of the job / testsuite being run 16 | buildName: browserstack build 17 | # `buildIdentifier` is a unique id to differentiate every execution that gets appended to 18 | # buildName. Choose your buildIdentifier format from the available expressions: 19 | # ${BUILD_NUMBER} (Default): Generates an incremental counter with every execution 20 | # ${DATE_TIME}: Generates a Timestamp with every execution. Eg. 05-Nov-19:30 21 | # Read more about buildIdentifiers here -> https://www.browserstack.com/docs/automate/selenium/organize-tests 22 | buildIdentifier: '#${BUILD_NUMBER}' # Supports strings along with either/both ${expression} 23 | 24 | source: 'python:appium-sample-sdk:v1.0' 25 | 26 | # Set `app` to define the app that is to be used for testing. 27 | # It can either take the id of any uploaded app or the path of the app directly. 28 | app: ./WikipediaSample.apk 29 | # app: ./LocalSample.apk #For running local tests 30 | 31 | # ======================================= 32 | # Platforms (Browsers / Devices to test) 33 | # ======================================= 34 | # Platforms object contains all the browser / device combinations you want to test on. 35 | # Entire list available here -> (https://www.browserstack.com/list-of-browsers-and-platforms/automate) 36 | 37 | platforms: 38 | - deviceName: Samsung Galaxy S22 Ultra 39 | osVersion: 12.0 40 | platformName: android 41 | - deviceName: Samsung Galaxy S21 42 | osVersion: 11.0 43 | platformName: android 44 | - deviceName: Google Pixel 6 Pro 45 | osVersion: 12.0 46 | platformName: android 47 | 48 | # ======================= 49 | # Parallels per Platform 50 | # ======================= 51 | # The number of parallel threads to be used for each platform set. 52 | # BrowserStack's SDK runner will select the best strategy based on the configured value 53 | # 54 | # Example 1 - If you have configured 3 platforms and set `parallelsPerPlatform` as 2, a total of 6 (2 * 3) parallel threads will be used on BrowserStack 55 | # 56 | # Example 2 - If you have configured 1 platform and set `parallelsPerPlatform` as 5, a total of 5 (1 * 5) parallel threads will be used on BrowserStack 57 | parallelsPerPlatform: 1 58 | 59 | # ========================================== 60 | # BrowserStack Local 61 | # (For localhost, staging/private websites) 62 | # ========================================== 63 | # Set browserStackLocal to true if your website under test is not accessible publicly over the internet 64 | # Learn more about how BrowserStack Local works here -> https://www.browserstack.com/docs/automate/selenium/local-testing-introduction 65 | browserstackLocal: true # (Default false) 66 | #browserStackLocalOptions: 67 | #Options to be passed to BrowserStack local in-case of advanced configurations 68 | # localIdentifier: # (Default: null) Needed if you need to run multiple instances of local. 69 | # forceLocal: true # (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel. 70 | # Entire list of arguments available here -> https://www.browserstack.com/docs/automate/selenium/manage-incoming-connections 71 | 72 | # =================== 73 | # Debugging features 74 | # =================== 75 | debug: false # # Set to true if you need screenshots for every selenium command ran 76 | networkLogs: false # Set to true to enable HAR logs capturing 77 | consoleLogs: errors # Remote browser's console debug levels to be printed (Default: errors) 78 | # Available options are `disable`, `errors`, `warnings`, `info`, `verbose` (Default: errors) 79 | -------------------------------------------------------------------------------- /android/browserstack_sample.py: -------------------------------------------------------------------------------- 1 | from appium import webdriver 2 | from appium.options.android import UiAutomator2Options 3 | from appium.webdriver.common.appiumby import AppiumBy 4 | from selenium.webdriver.support.ui import WebDriverWait 5 | from selenium.webdriver.support import expected_conditions as EC 6 | import time 7 | 8 | # Options are only available since client version 2.3.0 9 | # If you use an older client then switch to desired_capabilities 10 | # instead: https://github.com/appium/python-client/pull/720 11 | options = UiAutomator2Options().load_capabilities({ 12 | # Specify device and os_version for testing 13 | "platformName" : "android", 14 | "platformVersion" : "9.0", 15 | "deviceName" : "Google Pixel 3" 16 | 17 | # Add your caps here 18 | }) 19 | 20 | driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", options=options) 21 | 22 | # Test case for the BrowserStack sample Android app. 23 | # If you have uploaded your app, update the test case here. 24 | search_element = WebDriverWait(driver, 30).until( 25 | EC.element_to_be_clickable((AppiumBy.ACCESSIBILITY_ID, "Search Wikipedia")) 26 | ) 27 | search_element.click() 28 | search_input = WebDriverWait(driver, 30).until( 29 | EC.element_to_be_clickable( 30 | (AppiumBy.ID, "org.wikipedia.alpha:id/search_src_text")) 31 | ) 32 | search_input.send_keys("BrowserStack") 33 | time.sleep(5) 34 | search_results = driver.find_elements(AppiumBy.CLASS_NAME, "android.widget.TextView") 35 | assert (len(search_results) > 0) 36 | 37 | # Invoke driver.quit() after the test is done to indicate that the test is completed. 38 | driver.quit() 39 | -------------------------------------------------------------------------------- /android/browserstack_sample_local.py: -------------------------------------------------------------------------------- 1 | from appium import webdriver 2 | from appium.options.android import UiAutomator2Options 3 | from appium.webdriver.common.appiumby import AppiumBy 4 | from selenium.webdriver.support.ui import WebDriverWait 5 | from selenium.webdriver.support import expected_conditions as EC 6 | import time 7 | 8 | # Options are only available since client version 2.3.0 9 | # If you use an older client then switch to desired_capabilities 10 | # instead: https://github.com/appium/python-client/pull/720 11 | options = UiAutomator2Options().load_capabilities({ 12 | # Specify device and os_version for testing 13 | "deviceName": "Google Pixel 3", 14 | "platformName": "android", 15 | "platformVersion": "9.0", 16 | 17 | # Add your caps here 18 | }) 19 | 20 | driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", options=options) 21 | 22 | # Test case for the BrowserStack sample Android app. 23 | # If you have uploaded your app, update the test case here. 24 | test_button = WebDriverWait(driver, 30).until( 25 | EC.element_to_be_clickable((AppiumBy.ID, "com.example.android.basicnetworking:id/test_action")) 26 | ) 27 | test_button.click() 28 | WebDriverWait(driver, 30).until( 29 | EC.element_to_be_clickable((AppiumBy.CLASS_NAME, "android.widget.TextView")) 30 | ) 31 | test_element = None 32 | search_results = driver.find_elements(AppiumBy.CLASS_NAME,"android.widget.TextView") 33 | for result in search_results: 34 | if result.text.__contains__("The active connection is"): 35 | test_element = result 36 | if test_element is None: 37 | raise Exception("Cannot find the needed TextView element from app") 38 | matched_string = test_element.text 39 | print (matched_string) 40 | assert(matched_string.__contains__("The active connection is wifi")) 41 | assert(matched_string.__contains__("Up and running")) 42 | 43 | # Invoke driver.quit() after the test is done to indicate that the test is completed. 44 | driver.quit() 45 | -------------------------------------------------------------------------------- /ios/BStackSampleApp.ipa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserstack/python-appium-app-browserstack/914a432dce645ba2556eb8d288c777adff587992/ios/BStackSampleApp.ipa -------------------------------------------------------------------------------- /ios/LocalSample.ipa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/browserstack/python-appium-app-browserstack/914a432dce645ba2556eb8d288c777adff587992/ios/LocalSample.ipa -------------------------------------------------------------------------------- /ios/browserstack.yml: -------------------------------------------------------------------------------- 1 | # ============================= 2 | # Set BrowserStack Credentials 3 | # ============================= 4 | # Add your BrowserStack userName and acccessKey here or set BROWSERSTACK_USERNAME and 5 | # BROWSERSTACK_ACCESS_KEY as env variables 6 | userName: BROWSERSTACK_USERNAME 7 | accessKey: BROWSERSTACK_ACCESS_KEY 8 | 9 | # ====================== 10 | # BrowserStack Reporting 11 | # ====================== 12 | # The following capabilities are used to set up reporting on BrowserStack: 13 | # Set 'projectName' to the name of your project. Example, Marketing Website 14 | projectName: BrowserStack Samples 15 | # Set `buildName` as the name of the job / testsuite being run 16 | buildName: browserstack build 17 | # `buildIdentifier` is a unique id to differentiate every execution that gets appended to 18 | # buildName. Choose your buildIdentifier format from the available expressions: 19 | # ${BUILD_NUMBER} (Default): Generates an incremental counter with every execution 20 | # ${DATE_TIME}: Generates a Timestamp with every execution. Eg. 05-Nov-19:30 21 | # Read more about buildIdentifiers here -> https://www.browserstack.com/docs/automate/selenium/organize-tests 22 | buildIdentifier: '#${BUILD_NUMBER}' # Supports strings along with either/both ${expression} 23 | 24 | source: 'python:appium-sample-sdk:v1.0' 25 | 26 | # Set `app` to define the app that is to be used for testing. 27 | # It can either take the id of any uploaded app or the path of the app directly. 28 | app: ./BStackSampleApp.ipa 29 | # app: ./LocalSample.ipa #For running local tests 30 | 31 | # ======================================= 32 | # Platforms (Browsers / Devices to test) 33 | # ======================================= 34 | # Platforms object contains all the browser / device combinations you want to test on. 35 | # Entire list available here -> (https://www.browserstack.com/list-of-browsers-and-platforms/automate) 36 | 37 | platforms: 38 | - deviceName: iPhone 14 Pro 39 | osVersion: 16 40 | platformName: ios 41 | - deviceName: iPhone 13 Pro 42 | osVersion: 15 43 | platformName: ios 44 | - deviceName: iPhone 12 45 | osVersion: 17 46 | platformName: ios 47 | 48 | # ======================= 49 | # Parallels per Platform 50 | # ======================= 51 | # The number of parallel threads to be used for each platform set. 52 | # BrowserStack's SDK runner will select the best strategy based on the configured value 53 | # 54 | # Example 1 - If you have configured 3 platforms and set `parallelsPerPlatform` as 2, a total of 6 (2 * 3) parallel threads will be used on BrowserStack 55 | # 56 | # Example 2 - If you have configured 1 platform and set `parallelsPerPlatform` as 5, a total of 5 (1 * 5) parallel threads will be used on BrowserStack 57 | parallelsPerPlatform: 1 58 | 59 | # ========================================== 60 | # BrowserStack Local 61 | # (For localhost, staging/private websites) 62 | # ========================================== 63 | # Set browserStackLocal to true if your website under test is not accessible publicly over the internet 64 | # Learn more about how BrowserStack Local works here -> https://www.browserstack.com/docs/automate/selenium/local-testing-introduction 65 | browserstackLocal: true # (Default false) 66 | #browserStackLocalOptions: 67 | #Options to be passed to BrowserStack local in-case of advanced configurations 68 | # localIdentifier: # (Default: null) Needed if you need to run multiple instances of local. 69 | # forceLocal: true # (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel. 70 | # Entire list of arguments available here -> https://www.browserstack.com/docs/automate/selenium/manage-incoming-connections 71 | 72 | # =================== 73 | # Debugging features 74 | # =================== 75 | debug: false # # Set to true if you need screenshots for every selenium command ran 76 | networkLogs: false # Set to true to enable HAR logs capturing 77 | consoleLogs: errors # Remote browser's console debug levels to be printed (Default: errors) 78 | # Available options are `disable`, `errors`, `warnings`, `info`, `verbose` (Default: errors) 79 | -------------------------------------------------------------------------------- /ios/browserstack_sample.py: -------------------------------------------------------------------------------- 1 | from appium import webdriver 2 | from appium.options.ios import XCUITestOptions 3 | from appium.webdriver.common.appiumby import AppiumBy 4 | from selenium.webdriver.support.ui import WebDriverWait 5 | from selenium.webdriver.support import expected_conditions as EC 6 | import time 7 | 8 | # Options are only available since client version 2.3.0 9 | # If you use an older client then switch to desired_capabilities 10 | # instead: https://github.com/appium/python-client/pull/720 11 | options = XCUITestOptions().load_capabilities({ 12 | # Specify device and os_version for testing 13 | "deviceName": "iPhone 11", 14 | "platformName": "ios", 15 | "platformVersion": "13", 16 | 17 | # Add your caps here 18 | }) 19 | 20 | driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", options=options) 21 | 22 | # Test case for the BrowserStack sample iOS app. 23 | # If you have uploaded your app, update the test case here. 24 | text_button = WebDriverWait(driver, 30).until( 25 | EC.element_to_be_clickable((AppiumBy.ACCESSIBILITY_ID, "Text Button")) 26 | ) 27 | text_button.click() 28 | text_input = WebDriverWait(driver, 30).until( 29 | EC.element_to_be_clickable((AppiumBy.ACCESSIBILITY_ID, "Text Input")) 30 | ) 31 | text_input.send_keys("hello@browserstack.com"+"\n") 32 | time.sleep(5) 33 | text_output = WebDriverWait(driver, 30).until( 34 | EC.element_to_be_clickable((AppiumBy.ACCESSIBILITY_ID, "Text Output")) 35 | ) 36 | if text_output!=None and text_output.text=="hello@browserstack.com": 37 | assert True 38 | else: 39 | assert False 40 | 41 | # Invoke driver.quit() after the test is done to indicate that the test is completed. 42 | driver.quit() 43 | -------------------------------------------------------------------------------- /ios/browserstack_sample_local.py: -------------------------------------------------------------------------------- 1 | from appium import webdriver 2 | from appium.options.ios import XCUITestOptions 3 | from appium.webdriver.common.appiumby import AppiumBy 4 | from selenium.webdriver.support.ui import WebDriverWait 5 | from selenium.webdriver.support import expected_conditions as EC 6 | import os 7 | 8 | # Options are only available since client version 2.3.0 9 | # If you use an older client then switch to desired_capabilities 10 | # instead: https://github.com/appium/python-client/pull/720 11 | options = XCUITestOptions().load_capabilities({ 12 | # Specify device and os_version for testing 13 | "deviceName": "iPhone XS", 14 | "platformName": "ios", 15 | "platformVersion": "12" 16 | 17 | # Add your caps here 18 | }) 19 | 20 | driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", options=options) 21 | 22 | # Test case for the BrowserStack sample iOS app. 23 | # If you have uploaded your app, update the test case here. 24 | test_button = WebDriverWait(driver, 30).until( 25 | EC.element_to_be_clickable((AppiumBy.ACCESSIBILITY_ID, "TestBrowserStackLocal")) 26 | ) 27 | test_button.click() 28 | result_element = driver.find_element(AppiumBy.ACCESSIBILITY_ID, "ResultBrowserStackLocal") 29 | result_string = result_element.text.lower() 30 | if result_string.__contains__("not working"): 31 | screenshot_file = "%s/screenshot.png" % os.getcwd() 32 | driver.save_screenshot(screenshot_file) 33 | print ("Screenshot stored at %s" % screenshot_file) 34 | print ("Unexpected BrowserStackLocal test result") 35 | else: 36 | assert(result_string.__contains__("up and running")) 37 | 38 | # Invoke driver.quit() after the test is done to indicate that the test is completed. 39 | driver.quit() 40 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | browserstack-sdk 2 | Appium-Python-Client==2.6.1;python_version >= '3.0' 3 | --------------------------------------------------------------------------------