diff --git a/examples/appium/conftest.py b/examples/appium/conftest.py new file mode 100644 index 0000000..1863ac7 --- /dev/null +++ b/examples/appium/conftest.py @@ -0,0 +1,71 @@ +import pytest +import os +from appium import webdriver +from appium.options.common import AppiumOptions + +from views.home_view import HomeView + +IOS_APP = 'storage:filename=iOS.RealDevice.SauceLabs.Mobile.Sample.app.2.7.1.ipa' +ANDROID_APP = 'storage:filename=Android.SauceLabs.Mobile.Sample.app.2.7.1.apk' +APPIUM = 'https://ondemand.us-west-1.saucelabs.com:443/wd/hub' + + +def create_ios_caps(): + IOS_CAPS = {} + IOS_CAPS['platformName'] = 'iOS' + IOS_CAPS['appium:deviceName'] = 'iPhone.*' + IOS_CAPS['appium:automationName'] = 'XCUITest' + IOS_CAPS['appium:app'] = IOS_APP + IOS_CAPS['sauce:options'] = {} + IOS_CAPS['sauce:options']['appiumVersion'] = 'latest' + IOS_CAPS['sauce:options']['username'] = os.environ.get("SAUCE_USERNAME") + IOS_CAPS['sauce:options']['accessKey'] = os.environ.get("SAUCE_ACCESS_KEY") + IOS_CAPS['sauce:options']['build'] = 'SwagLabs pytest' + IOS_CAPS['sauce:options']['name'] = 'Sign In - iOS' + return IOS_CAPS + + +def create_android_caps(): + ANDROID_CAPS = {} + ANDROID_CAPS['platformName'] = 'Android' + ANDROID_CAPS['appium:deviceName'] = 'Google.*' + ANDROID_CAPS['appium:automationName'] = 'UIAutomator2' + ANDROID_CAPS['appium:app'] = ANDROID_APP + ANDROID_CAPS['sauce:options'] = {} + ANDROID_CAPS['sauce:options']['appiumVersion'] = 'latest' + ANDROID_CAPS['sauce:options']['username'] = os.environ.get("SAUCE_USERNAME") + ANDROID_CAPS['sauce:options']['accessKey'] = os.environ.get("SAUCE_ACCESS_KEY") + ANDROID_CAPS['sauce:options']['build'] = 'SwagLabs pytest' + ANDROID_CAPS['sauce:options']['name'] = 'Sign In - Android' + return ANDROID_CAPS + + +def pytest_addoption(parser): + parser.addoption('--platform', action='store', default='android') + + +@pytest.fixture +def platform(request): + plat = request.config.getoption('platform').lower() + if plat not in ['ios', 'android']: + raise ValueError('--platform value must be ios or android') + return plat + + +@pytest.fixture +def driver(platform): + ios_caps = create_ios_caps() + android_caps = create_android_caps() + if platform == 'ios': + caps = ios_caps + else: + caps = android_caps + driver = webdriver.Remote(APPIUM, options=AppiumOptions().load_capabilities(caps)) + driver._platform = platform + yield driver + driver.quit() + + +@pytest.fixture +def home(driver): + return HomeView(driver) diff --git a/examples/appium/test_login.py b/examples/appium/test_login.py new file mode 100644 index 0000000..af09568 --- /dev/null +++ b/examples/appium/test_login.py @@ -0,0 +1,2 @@ +def test_sign_in(home): + home.sign_in() diff --git a/examples/appium/views/base_view.py b/examples/appium/views/base_view.py new file mode 100644 index 0000000..8a65c91 --- /dev/null +++ b/examples/appium/views/base_view.py @@ -0,0 +1,16 @@ +from selenium.webdriver.support.wait import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC + + +class BaseView(object): + def __init__(self, driver): + self.driver = driver + self.wait = WebDriverWait(self.driver, 10) + + def wait_for(self, locator): + return self.wait.until(EC.presence_of_element_located(locator)) + + def find(self, locator): + return self.driver.find_element(*locator) + + diff --git a/examples/appium/views/home_view.py b/examples/appium/views/home_view.py new file mode 100644 index 0000000..73359b9 --- /dev/null +++ b/examples/appium/views/home_view.py @@ -0,0 +1,27 @@ +import pytest +from selenium import webdriver +from appium.webdriver.common.appiumby import AppiumBy +from views.base_view import BaseView + + +class HomeView(BaseView): + USERNAME_FIELD = (AppiumBy.ACCESSIBILITY_ID, 'test-Username') + PASSWORD_FIELD = (AppiumBy.ACCESSIBILITY_ID, 'test-Password') + LOGIN_BUTTON = (AppiumBy.ACCESSIBILITY_ID, 'test-LOGIN') + DISPLAY_PRODUCTS = (AppiumBy.ACCESSIBILITY_ID, 'test-PRODUCTS') + + def sign_in(self): + self.wait_for(self.USERNAME_FIELD).send_keys('standard_user') + self.wait_for(self.PASSWORD_FIELD).send_keys('secret_sauce') + self.wait_for(self.LOGIN_BUTTON).click() + try: + if self.wait_for(self.DISPLAY_PRODUCTS).is_displayed(): + status = "passed" + else: + status = "failed" + except Exception as e: + print(f"Error finding DISPLAY_PRODUCTS element: {e}") + status = "failed" + self.driver.execute_script("sauce:job-result={}".format(status)) + + assert self.wait_for(self.DISPLAY_PRODUCTS).is_displayed()