import re import tidevice from wda import Client from Utils.AiUtils import AiUtils from Utils.LogManager import LogManager # 页面控制工具类 class ControlUtils(object): # 获取设备上的app列表 @classmethod def getDeviceAppList(self, udid): device = tidevice.Device(udid) # 获取已安装的应用列表 apps = [] for app in device.installation.iter_installed(): apps.append({ "name": app.get("CFBundleDisplayName", "Unknown"), "bundleId": app.get("CFBundleIdentifier", "Unknown"), "version": app.get("CFBundleShortVersionString", "Unknown"), "path": app.get("Path", "Unknown") }) # 筛选非系统级应用(过滤掉以 com.apple 开头的系统应用) noSystemApps = [app for app in apps if not app["bundleId"].startswith("com.apple")] return noSystemApps # 打开Tik Tok @classmethod def openTikTok(cls, session: Client, udid): apps = cls.getDeviceAppList(udid) tk = "" for app in apps: if app.get("name", "") == "TikTok": tk = app.get("bundleId", "") currentApp = session.app_current() if currentApp != tk: session.app_start(tk) # 关闭Tik Tok @classmethod def closeTikTok(cls, session: Client, udid): apps = cls.getDeviceAppList(udid) tk = "" for app in apps: if app.get("name", "") == "TikTok": tk = app.get("bundleId", "") session.app_stop(tk) # 返回 @classmethod def clickBack(cls, session: Client): try: back = session.xpath("//*[@label='返回']") if back.exists: back.click() return True elif session.xpath("//*[@name='nav_bar_start_back']").exists: back = session.xpath("//*[@name='nav_bar_start_back']") back.click() return True elif session.xpath( "//Window[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]").exists: back = session.xpath( "//Window[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]") back.click() return True else: return False except Exception as e: print(e) return False # 点赞 @classmethod def clickLike(cls, session: Client, udid): scale = session.scale x, y = AiUtils.findImageInScreen("add", udid) print(x, y) if x > -1: print("点赞了") session.click(x // scale, y // scale + 50) return True else: print("没有找到目标") return False # 点击搜索 @classmethod def clickSearch(cls, session: Client): obj = session.xpath("//*[@name='搜索']") try: if obj.exists: obj.click() return True except Exception as e: print(e) return False # 点击收件箱按钮 @classmethod def clickMsgBox(cls, session: Client): box = session.xpath("//XCUIElementTypeButton[name='a11y_vo_inbox']") if box.exists: box.click() return True else: return False # 获取主播详情页的第一个视频 @classmethod def clickFirstVideoFromDetailPage(cls, session: Client): # videoCell = session.xpath( # '//Window/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[1]/Other[2]/Other[1]/ScrollView[1]/Other[1]/CollectionView[1]/Cell[2]') videoCell = session.xpath( '(//XCUIElementTypeCollectionView//XCUIElementTypeCell[.//XCUIElementTypeImage[@name="profile_video"]])[1]').get( timeout=5) tab = session.xpath('//XCUIElementTypeButton[@name="TTKProfileTabVideoButton_0"]').get(timeout=2) # 某些版本 tab.value 可能就是数量;或者 tab.label 类似 “作品 7” m = re.search(r"\d+", tab.label) num = 0 if m: # 判断当前的作品的数量 num = int(m.group()) print("作品数量为:", num) if videoCell is not None: videoCell.click() # 点击视频 print("找到主页的第一个视频") return True, num else: print("没有找到主页的第一个视频") return False, num