bingoogolapple.github.io icon indicating copy to clipboard operation
bingoogolapple.github.io copied to clipboard

Appium

Open bingoogolapple opened this issue 4 years ago • 6 comments

image image

bingoogolapple avatar Mar 10 '20 13:03 bingoogolapple

安装

  • 方式一:安装包安装。这种方式可以录制后自动生成对应语言的脚本 https://github.com/appium/appium-desktop/releases
  • 方式二:通过 node 安装
# 安装
cnpm install -g appium
# 启动
appium
# 后台启动
appium &

bingoogolapple avatar Mar 10 '20 13:03 bingoogolapple

Python 调用

  • 安装依赖
pip install Appium-Python-Client
  • HelloWorld
from appium import webdriver
import time
import base64


def hello_world(driver):
    if driver.is_app_installed('com.quark.browser'):
        print('已安装')
    else:
        print('未安装')
        driver.install_app('/Users/wanghao/Desktop/quark_browser.apk')  # 安装 app

    driver.start_activity('com.quark.browser', 'com.ucpro.BrowserActivity')
    time.sleep(2)
    driver.close_app()  # 关闭当前操作的 app,不关闭驱动对象

    # 获取当前打开的页面信息 adb shell dumpsys window windows | grep mFocusedApp
    # 脚本内启动其他 app,quit 方法不会关联打开的其他 app
    driver.start_activity('com.android.settings', '.Settings')
    time.sleep(2)
    driver.start_activity('com.android.browser', '.BrowserActivity')
    time.sleep(2)
    driver.remove_app('com.quark.browser')  # 卸载 app


def push_or_pull_file(driver):
    with open('./appium.txt') as f:
        data = f.read()
        # Python3 中的字符串都为 unicode 编码,而 b64encode 的参数为 byte 类型,需要先转码;生成的数据为 byte 类型,需要将 byte 转换回去
        data = str(base64.b64encode(data.encode('utf-8')), 'utf-8')
        driver.push_file('/sdcard/appium.txt', data)

        data = driver.pull_file('/sdcard/appium.txt')
        print(str(base64.b64decode(data), 'utf-8'))


def page_source(driver):
    driver.start_activity('com.android.settings', '.Settings')
    # 返回当前页面的文档结构,判断特定的元素是否存在
    page_content = driver.page_source
    print(page_content)
    if '应用' in page_content:
        print('存在')
    else:
        print('不存在')


def click(driver):
    driver.start_activity('com.android.settings', '.Settings')
    el = driver.find_element_by_xpath(
        "/hierarchy/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.widget.FrameLayout/android.widget.ScrollView/android.widget.LinearLayout/android.widget.LinearLayout[2]/android.view.ViewGroup/android.widget.FrameLayout[3]/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout")
    el.click()
    time.sleep(2)
    el = driver.find_element_by_accessibility_id("向上导航")
    el.click()


# server 启动参数
desired_caps = {}
# 设备信息
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '6.0.1'
desired_caps['deviceName'] = 'emulator-5554'  # iOS:instruments -s devices  Android:adb devices
# app 信息
# desired_caps['app'] = '/Users/wanghao/Desktop/quark_browser.apk'  # 安装文件路径
# desired_caps['appPackage'] = 'com.quark.browser'  # 启动的包
# desired_caps['appActivity'] = 'com.ucpro.BrowserActivity'  # 启动的 Activity

driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)

# hello_world(driver)
# push_or_pull_file(driver)
# page_source(driver)
click(driver)

driver.quit()  # 关闭驱动对象,同时关闭所有关联的 app,不会关闭脚本内通过 start_activity 启动的其他 app

bingoogolapple avatar Mar 10 '20 14:03 bingoogolapple

shell 解析 apk

DUMP_BADGING_CMD="${ANDROID_HOME}/build-tools/28.0.3/aapt dump badging ${APP_FILE_PATH}"
# 待测试 App 的包名
APP_PACKAGE=$($DUMP_BADGING_CMD | grep package | awk '{print $2}' | sed s/name=//g | tr -d "'")
# 待测试 App 的启动 Activity
APP_LAUNCH_ACTIVITY=$($DUMP_BADGING_CMD | grep launchable | awk '{print $2}' | sed s/name=//g | tr -d "'")
# 待测试 App 的最低兼容版本
APP_MIN_SDK_VERSION=$($DUMP_BADGING_CMD | grep sdkVersion | sed s/sdkVersion://g | tr -d "'")

echo $APP_PACKAGE
echo $APP_LAUNCH_ACTIVITY
echo $APP_MIN_SDK_VERSION

bingoogolapple avatar Mar 15 '20 03:03 bingoogolapple

shell 执行 adb 点击

click_with_key_value() {
  if [[ $# != 3 ]]; then
    echo "usage: click_with_key_value udid key value"
    exit 1
  fi
  udid=$1
  key=$2
  value=$3

  xml_content=$(adb -s $udid shell uiautomator dump /dev/tty | sed s/UI\ hierchary\ dumped\ to:\ \\/dev\\/tty//g)
  if [[ -z "$xml_content" ]]; then
    echo "不存在[$key]节点[$value],无法点击。dump 失败,重新连接"
    adb connect $udid
    adb devices
    return 1
  fi
  node=$(echo $xml_content | xmllint --format - | grep $key=\"${value}\")
  #  echo $node
  if [[ -z "$node" ]]; then
    echo "不存在[$key]节点[$value],无法点击"
    return 1
  else
    echo "点击[$key]节点[$value]成功"
  fi

  coordinate=$(echo $node | awk '{print $NF}' | sed s/bounds=//g | sed s/\\/\>//g | tr -d '"' | sed s/]\\\[/\ /g | sed s/]/\ /g | sed s/,/\ /g | sed s/\\\[/\ /g)
  #  echo $coordinate
  x1=$(echo $coordinate | awk '{print $1}')
  x2=$(echo $coordinate | awk '{print $3}')
  y1=$(echo $coordinate | awk '{print $2}')
  y2=$(echo $coordinate | awk '{print $4}')
  #  echo $[$[x1 + $x2]/2] $[$[y1 + $y2]/2]
  adb -s $udid shell input tap $(($((x1 + $x2)) / 2)) $(($((y1 + $y2)) / 2))
}

click_with_key_value_until_exist() {
  if [[ $# != 3 ]]; then
    echo "usage: click_with_key_value_until_exist udid key value"
    exit 1
  fi
  udid=$1
  key=$2
  value=$3

  for i in {1..10}; do
    sleep 5
    click_with_key_value $udid $key $value
    if [[ $? == 0 ]]; then
      return 0
    fi
  done
  echo "点击[$key]节点[$value]失败"
  return 1
}

click_install_node() {
  if [[ $# != 1 ]]; then
    echo "usage: click_install_node udid"
    exit 1
  fi
  udid=$1

  xml_content=$(adb -s $udid shell uiautomator dump /dev/tty | sed s/UI\ hierchary\ dumped\ to:\ \\/dev\\/tty//g)
  if [[ -z "$xml_content" ]]; then
    echo "不存在安装相关节点,无法点击。dump 失败,重新连接"
    adb connect $udid
    adb devices
    return 1
  fi

  exist_value=1
  text_array=("允许" "继续安装" "仅允许一次" "安装")
  for value in ${text_array[@]}; do
    node=$(echo $xml_content | xmllint --format - | grep text=\"${value}\")
    if [[ -z "$node" ]]; then
      echo "不存在安装相关节点[$value]"
    else
      echo "存在安装相关节点[$value]"
      exist_value=0
      break
    fi
  done
  if [[ $exist_value == 1 ]]; then
    echo "不存在安装相关节点,无法点击"
    return 1
  else
    echo "存在安装相关节点,点击成功"
  fi

  coordinate=$(echo $node | awk '{print $NF}' | sed s/bounds=//g | sed s/\\/\>//g | tr -d '"' | sed s/]\\\[/\ /g | sed s/]/\ /g | sed s/,/\ /g | sed s/\\\[/\ /g)
  #  echo $coordinate
  x1=$(echo $coordinate | awk '{print $1}')
  x2=$(echo $coordinate | awk '{print $3}')
  y1=$(echo $coordinate | awk '{print $2}')
  y2=$(echo $coordinate | awk '{print $4}')
  #  echo $[$[x1 + $x2]/2] $[$[y1 + $y2]/2]
  adb -s $udid shell input tap $(($((x1 + $x2)) / 2)) $(($((y1 + $y2)) / 2))
}

click_install_until_exist() {
  if [[ $# != 1 ]]; then
    echo "usage: click_install_until_exist udid"
    exit 1
  fi
  udid=$1

  sleep 10
  for i in {1..10}; do
    click_install_node $udid
    if [[ $? == 0 ]]; then
      return 0
    fi
    sleep 4
  done
  return 1
}

click_with_text() {
  if [[ $# != 2 ]]; then
    echo "usage: click_with_text udid text"
    exit 1
  fi
  click_with_key_value $1 "text" $2
}

click_with_resource_id() {
  if [[ $# != 2 ]]; then
    echo "usage: click_with_resource_id udid resource_id"
    exit 1
  fi
  click_with_key_value $1 "resource-id" $2
}

click_continue_install_in_child_process() {
  {
    click_install_until_exist $1
    if [[ $? == 0 ]]; then
      click_install_until_exist $1
      if [[ $? == 0 ]]; then
        click_install_until_exist $1
        if [[ $? == 0 ]]; then
          click_install_until_exist $1
        fi
      fi
    fi
  } &
}
click_with_key_value_until_exist emulator-5554 "text" "记住密码"
if [[ $? == 0 ]]; then
  echo "点击成功"
else
  echo "点击失败"
fi

sleep 1

click_with_key_value emulator-5554 "text" "记住密码"
if [[ $? == 0 ]]; then
  echo "点击成功"
else
  echo "点击失败"
fi

sleep 1

click_with_text emulator-5554 "记住密码"
if [[ $? == 0 ]]; then
  echo "点击成功"
else
  echo "点击失败"
fi

bingoogolapple avatar Mar 15 '20 03:03 bingoogolapple

brew install --HEAD libimobiledevice
brew install ideviceinstaller
npm install -g ios-deploy
  • 查看设备列表
idevice_id -l               # 显示当前所连接的设备[udid],包括 usb、WiFi 连接
instruments -s devices      # 列出设备包括模拟器、真机及 mac 电脑本身
  • 启动指定模拟器
xcrun instruments -w "iPhone 8 (11.2)"
  • 安装
xcrun simctl install booted xxx.app
ideviceinstaller -u [udid] -i [xxx.ipa] # 给指定连接的设备安装应用
  • 卸载
xcrun simctl uninstall booted <app identifier>
ideviceinstaller -u [udid] -U [bundleId] # 给指定连接的设备卸载应用
  • 查看设备已安装的应用
ideviceinstaller -u [udid] -l                   # 指定设备,查看安装的第三方应用
ideviceinstaller -u [udid] -l -o list_user      # 指定设备,查看安装的第三方应用
ideviceinstaller -u [udid] -l -o list_system    # 指定设备,查看安装的系统应用
ideviceinstaller -u [udid] -l -o list_all       # 指定设备,查看安装的系统应用和第三方应用
  • 获取设备信息
ideviceinfo -u [udid]                       # 指定设备,获取设备信息
ideviceinfo -u [udid] -k DeviceName         # 指定设备,获取设备名称:iPhone6s
idevicename -u [udid]                       # 指定设备,获取设备名称:iPhone6s
ideviceinfo -u [udid] -k ProductVersion     # 指定设备,获取设备版本:10.3.1
ideviceinfo -u [udid] -k ProductType        # 指定设备,获取设备类型:iPhone8,1
ideviceinfo -u [udid] -k ProductName        # 指定设备,获取设备系统名称:iPhone OS
  • 启动指定应用
xcrun simctl launch booted <app identifier>

ios-deploy

  • 查看当前所连接的设备
ios-deploy -c               # 查看连接的设备包括:usb、wifi 连接
ios-deploy -c --no-wifi     # 查看连接的设备(usb),忽略 WiFi 连接的
  • 安装应用
ios-deploy --id [udid] --bundle [xxx.app]
  • 卸载应用
ios-deploy --id [udid] --uninstall_only --bundle_id [bundleId]
  • 查看已安装应用
ios-deploy --id [udid] --list_bundle_id     # 指定设备安装的所有应用,包括系统应用和第三方应用
ios-deploy --id [udid] --exists --bundle_id     # 指定设备检查指定应用是否已经安装

bingoogolapple avatar Mar 24 '20 05:03 bingoogolapple

https://juejin.im/post/5d7ef540f265da03bb4ada00

bingoogolapple avatar Mar 24 '20 12:03 bingoogolapple