bingoogolapple / bingoogolapple.github.io

个人主页。同时也通过 Issues 记录学习笔记
http://www.bingoogolapple.cn
86 stars 22 forks source link

Appium #213

Open bingoogolapple opened 4 years ago

bingoogolapple commented 4 years ago

image image

bingoogolapple commented 4 years ago

安装

bingoogolapple commented 4 years ago

Python 调用

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 commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago
brew install --HEAD libimobiledevice
brew install ideviceinstaller
npm install -g ios-deploy

ios-deploy

bingoogolapple commented 4 years ago

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