【问题标题】:Python Appium implementing Page Object ModelPython Appium 实现页面对象模型
【发布时间】:2017-12-03 10:39:11
【问题描述】:

我正在尝试使用 appium 实现“By”和“Keys”,就像我在 selenium 上所做的那样。

在硒上我可以这样做:

定位器

from selenium.webdriver.common.by import By

class LoginPageLocators(object):
    HEADING = (By.CSS_SELECTOR, 'h3[class="panel-title"]')
    USERNAME = (By.NAME, 'username')
    PASSWORD = (By.NAME, 'password')
    LOGIN_BTN = (By.CSS_SELECTOR, 'input[value="Login"]')

功能

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from base import Page
from locators.locators import *

class LoginPage(Page):

    def __init__(self, context):
        Page.__init__(
            self,
            context)

    def goto_login_page(self, url):
        self.open(url)

    def enter_username(self, username):
        uname = self.find_element(*LoginPageLocators.USERNAME)
        uname.send_keys(username)

    def enter_password(self, password):
        pword = self.find_element(*LoginPageLocators.PASSWORD)
        pword.send_keys(password)

    def click_login(self):
        login = self.find_element(*LoginPageLocators.LOGIN_BTN)
        login.click()

    def verify_dashboard_page(self, page):
        self.verify_page(page)

有没有办法在 appium 中做到这一点?如果我这样做,就没有模块:

 from appium.webdriver.common.by import By
 from appium.webdriver.common.keys import Keys

【问题讨论】:

    标签: python selenium appium python-appium


    【解决方案1】:
    from appium.webdriver.common.mobileby import By
    from appium.webdriver.common.mobileby import MobileBy
    
    class FirstPageLocators(object):
        LOCATOR_ONE = (MobileBy.ACCESSIBILITY_ID, 'id')
        LOCATOR_TWO = (MobileBy.XPATH, 'xpath_value')
    

    【讨论】:

      【解决方案2】:

      我对定位器使用了另一种方式。

      我有 page_object 目录,其中包含应用程序页面的文件和通用文件 - base_page。在 Base_page.py 中,我包含了其他页面的一般操作方法。示例:

      from appium import webdriver
      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.support import expected_conditions as ex_cond
      from src.platform import PLATFORM, IS_IOS
      
      class BasePage:
      
          def __init__(self, driver: webdriver) -> None:
              self._driver = driver
      
          def get_element(self, locator: str, timeout=10):
              by = get_locator_by_string(locator)
              return WebDriverWait(self._driver, timeout).until(
                  ex_cond.visibility_of_element_located(by), ' : '.join(by))
      
          def get_no_element(self, locator: str, timeout=10):
              by = get_locator_by_string(locator)
              element = WebDriverWait(self._driver, timeout).until(
                  ex_cond.invisibility_of_element_located(by), ' : '.join(by))
              if element is None:
                  return 'No element found'
      
      
          def get_element_text(self, locator: str, timeout=10):
              by = get_locator_by_string(locator)
              element = WebDriverWait(self._driver, timeout).until(
                  ex_cond.visibility_of_element_located(by), ' : '.join(by))
              if IS_IOS:
                  return element.get_attribute('label')
              else:
                  return element.text
      
          def get_element_and_click(self, locator: str, timeout=10):
              by = get_locator_by_string(locator)
              element = WebDriverWait(self._driver, timeout).until(
                  ex_cond.visibility_of_element_located(by), ' : '.join(by))
              return element.click()
      

      为了找到定位器的正确方法,我在同一个文件 - base_page.py 中创建了自定义方法。示例:

      def get_locator_by_string(locator_with_type):
          exploided_locator = locator_with_type.split(':', 1)
          by_type = exploided_locator[0]
          locator = exploided_locator[1]
      
          if by_type == 'xpath':
              return (MobileBy.XPATH, locator)
          elif by_type == 'css':
              return (MobileBy.CSS_SELECTOR, locator)
          elif by_type == 'id':
              return (MobileBy.ID, locator)
          elif by_type == 'accessibility_id':
              return (MobileBy.ACCESSIBILITY_ID, locator)
          elif by_type == 'android_uiautomator':
              return (MobileBy.ANDROID_UIAUTOMATOR, locator)
          elif by_type == 'ios_uiautomation':
              return (MobileBy.IOS_UIAUTOMATION, locator)
          elif by_type == 'ios_predicate':
              return (MobileBy.IOS_PREDICATE, locator)
          elif by_type == 'class':
              return (MobileBy.CLASS_NAME, locator)
          else:
              raise Exception(f'Cannot get type of locator. Locator 
                  {locator_with_type}')
      

      Get_locator_by_string 不包含所有搜索方法。有我需要的方法。

      在定位器文件中,我有两种方法 - 适用于 Android 和 iOS。示例:

      import allure
      from src.config import BUNDLE_APP
      from src.ui.base_page import BasePage, locator_for_platform
      
      
      class AuthorPage(BasePage):
      
          _author_title = locator_for_platform({
              'ANDROID': 'id:%s:id/authorName' % BUNDLE_APP,
              'IOS': 'accessibility_id:author_name'
          })
      
          _subscribe_button = locator_for_platform({
              'ANDROID': 'id:%s:id/subscribeBackground' % BUNDLE_APP,
              'IOS': 'accessibility_id:author_subscribe_button'
          })
      
          @allure.step('Press subscribe button')
          def press_subscribe_button(self):
              super().get_element_and_click(self._subscribe_button)
      
          @allure.step('Get subscribe button text')
          def get_subscribe_button_text(self):
              return super().get_element_text(self._subscribe_button_text)
      
          @allure.step('Get author\'s name text')
          def get_author_name_text(self):
              return super().get_element_text(self._author_title)
      

      为了为平台选择正确的定位器,我使用了平台检查的方法。示例:

      def locator_for_platform(selectors):
          return selectors.get(PLATFORM, 'Undefined Selector')
      

      检查当前平台这个文件:

      import os
      from appium import webdriver
      from src import config
      
      
      def get_env(key, default=None):
          return os.environ.get(key=key, default=default)
      
      
      def get():
          if IS_ANDROID:
              return webdriver.Remote(
                  command_executor=config.APPIUM_HOST,
                  desired_capabilities=config.DESIRED_CAPS_ANDROID_RESET
              )
          else:
              return webdriver.Remote(
                  command_executor=config.APPIUM_HOST,
                  desired_capabilities=config.DESIRED_CAPS_ANDROID_RESET
              )
      
      
      PLATFORM = get_env('PLATFORM', 'IOS')
      
      IS_ANDROID = PLATFORM == 'ANDROID'
      IS_IOS = PLATFORM == 'IOS'
      

      以及用于设置当前平台进行测试的最后一个文件:

      #!/usr/bin/env bash
      
      export PLATFORM=IOS
      export PLATFORM=ANDROID
      

      APPIUM_HOST 和 DESIRED_CAPS_ANDROID_RESET / DESIRED_CAPS_ANDROID_RESET 在其他文件中。示例:

      APPIUM_HOST = 'http://localhost:4445/wd/hub'
      
      DESIRED_CAPS_IOS = {
          'platformName': 'iOS',
          'platformVersion': '13.3',
          'deviceName': 'iPhone 8',
          'automationNam': 'XCUITest',
          'app': MY_APP_IOS
      }
      
      DESIRED_CAPS_ANDROID_RESET = {
          'platformName': 'Android',
          'platformVersion': '10',
          'automationName': 'uiautomator2',
          'deviceName': DEVICES['Pixel Emulator (10.0)'],
          'app': MY_APP_ANDROID,
          'unicodeKeyboard': 'true',
          'resetKeyboard': 'true',
          'disableWindowAnimation': 'true',
          'autoWebviewTimeout': '2000',
          'clearDeviceLogsOnStart': 'true'
      }
      

      DEVICES 和 MY_APP_ANDROID 是另一个字典。

      希望我的经验对你有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-19
        • 2014-01-27
        • 2019-04-16
        • 2023-04-08
        相关资源
        最近更新 更多