appium iOS tap()函数封装

本文介绍了在iOS UI自动化测试中,由于Flutter页面无法直接定位,采用坐标点击并结合图片校验的方法。为了解决坐标在不同iOS设备上的兼容问题,文章分享了如何封装appium的tap()函数,根据设备宽高比进行适配,确保在iPhone X之前和之后的设备上都能正确执行点击操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在编写iOSUI自动化测试过程中,由于公司app使用flutter开发页面无法通过元素来定位,只能通过坐标来点击,再配合图片对比校验来实现。使用坐标点击就带来一个问题我们通常能看到一个机型的绝对坐标无法在其它iPhone设备上运行,所以考虑将appium中的tap()函数封装一下,实现输入一个坐标值可以在任何iOS设备上执行。代码如下
def my_tap(self, abs_width, abs_height):
‘’’
abs_width:绝对宽度坐标
abs_height:绝对高度坐标
根据绝对坐标算出相对坐标,兼容其它机型,
iphone x 之前的机型宽高比为:9:16 = 0.5625
iPhone x 之后的机型宽高比为:9:19.5 约等于0.46
根据宽高比来适配
‘’’
left = self.driver.get_window_size()[‘width’]
height = self.driver.get_window_size()[‘height’]
num = “%.2f” % (left / height) # 取小数点前两位
if num == ‘0.46’: # iPhonex及以上的设备
relative_width_x = abs_width / 375 # 相对宽度
relative_height_x = abs_height / 812 # 相对高度
actual_width_x = self.driver.get_window_size()[‘width’] # 实际设备的宽度
actual_height_x = self.driver.get_window_size()[‘height’] # 实际设备的高度
self.driver.tap([(relative_width_x * actual_width_x, relative_height_x * actual_height_x)], 100)
elif left / height == 0.5625: # iPhonex及以下的设备
relative_width = abs_width / 414

<think>我们正在解决如何定位并移除Appium中的蒙版元素(覆盖层),以便操作下方的元素。蒙版通常是一个半透明的层,会阻止用户与底层元素的交互。常见的场景包括新手引导、广告弹窗、权限请求等。 关键思路: 1. 定位蒙版元素本身(通常是一个全屏或部分屏幕的视图) 2. 通过点击蒙版上的关闭按钮、跳过按钮,或者直接点击蒙版特定区域来关闭它 3. 如果无法关闭,可以尝试其他方法(如等待超时、模拟返回键等) 具体步骤: 步骤1:识别蒙版元素 使用Appium Inspector或UI Automator Viewer等工具查看蒙版元素的属性。常见的定位方式包括: - 通过ID定位(如果有固定资源ID) - 通过类名定位(如:android.view.View, XCUIElementTypeOther 等通用视图) - 通过文本定位(如“跳过”、“我知道了”等) - 通过XPath定位(当蒙版没有明显特征时,可能需要使用XPath来定位其在整个节点树中的位置) 示例代码(定位蒙版上的关闭按钮): ```java // 通过ID定位关闭按钮(推荐) MobileElement closeBtn = driver.findElement(By.id("com.example:id/btn_close")); // 通过文本定位(适用于按钮上有文字) MobileElement skipBtn = driver.findElement(AppiumBy.androidUIAutomator("new UiSelector().text(\"跳过\")")); // 通过XPath定位(当没有ID和文本时) MobileElement mask = driver.findElement(By.xpath("//android.view.View[@clickable='true' and @bounds='[0,0][1080,1920]']")); ``` 步骤2:关闭蒙版 定位到关闭按钮或可点击区域后,执行点击操作: ```java closeBtn.click(); ``` 如果没有明显的关闭按钮,但蒙版本身可点击关闭,则可以直接点击蒙版元素: ```java mask.click(); ``` 步骤3:处理无法直接关闭的蒙版 如果蒙版没有关闭按钮且不可点击,可以尝试: - 等待蒙版自动消失(设置显式等待) - 模拟物理返回键(适用于按返回键可关闭的情况) - 使用坐标点点击(不推荐,但作为最后手段) 示例(等待蒙版消失): ```java WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.invisibilityOf(mask)); ``` 示例(模拟返回键): ```java driver.pressKey(new KeyEvent(AndroidKey.BACK)); ``` 步骤4:验证蒙版已关闭 在继续操作前,确保蒙版已关闭。可以通过检查蒙版是否消失,或者底层元素是否可操作来判断: ```java // 等待蒙版消失 wait.until(ExpectedConditions.invisibilityOf(mask)); // 或者等待底层元素出现并可点击 wait.until(ExpectedConditions.elementToBeClickable(By.id("com.example:id/underlying_element"))); ``` 步骤5:定位并操作底层元素 确认蒙版关闭后,即可正常操作底层元素: ```java MobileElement targetElement = driver.findElement(By.id("com.example:id/underlying_element")); targetElement.click(); ``` 特殊情况处理: 1. 多层蒙版:可能需要连续关闭多个蒙版。建议封装一个关闭蒙版的函数,在每次操作前调用。 2. 动态加载的蒙版:在页面切换后可能出现新的蒙版,因此需要在关键步骤后添加蒙版检查。 封装关闭蒙版的函数(伪代码): ```java public void closeMaskIfPresent() { try { // 尝试定位关闭按钮 MobileElement closeBtn = driver.findElement(By.id("com.example:id/btn_close")); closeBtn.click(); } catch (NoSuchElementException e) { // 没有蒙版,继续 } } ``` 注意事项: - 蒙版元素的定位可能因应用版本更新而变化,建议使用相对稳定的定位方式(如资源ID)。 - 避免使用绝对坐标点击,因为不同设备分辨率不同。 - 如果蒙版是WebView中的元素,需要先切换到WebView上下文。 引用说明: 定位蒙版元素的方法参考了Appium的常用定位策略[^1],通过关闭按钮的点击来移除蒙版[^2]。处理无法关闭的蒙版时,模拟返回键是一种常见的系统级操作[^3]。 相关问题: 1. Appium中如何定位动态变化的蒙版元素? 2. 如何处理WebView内的蒙版? 3.iOS和Android上处理蒙版有哪些差异? 4. 如何编写健壮性高的蒙版处理函数?</think>### Appium 定位蒙版元素并移除/忽略的方法 蒙版元素(如新手引导、广告弹窗、加载遮罩)会阻挡底层元素的操作。以下是定位并处理蒙版的核心方法: --- ### 一、定位蒙版元素的方法 1. **通过遮罩层特征定位** ```java // 定位全屏半透明蒙版 (Android) MobileElement mask = driver.findElement(By.xpath("//*[contains(@class, 'View') and @clickable='false']")); // iOS定位示例 MobileElement iosMask = driver.findElement(AppiumBy.iOSClassChain("**/XCUIElementTypeOther[`rect.width == ${screenWidth}`]")); ``` 2. **通过关闭按钮定位** ```java // 定位蒙版上的关闭按钮 MobileElement closeBtn = driver.findElement(AppiumBy.accessibilityId("close")); // 或通过文本定位 MobileElement skipBtn = driver.findElement(AppiumBy.androidUIAutomator( "new UiSelector().textContains(\"跳过\")")); ``` 3. **通过坐标定位(最后手段)** ```java // 获取屏幕尺寸 Dimension size = driver.manage().window().getSize(); // 点击右上角关闭区域 (x: 90%宽度, y: 10%高度) new TouchAction(driver).tap(PointOption.point( (int)(size.width * 0.9), (int)(size.height * 0.1) )).perform(); ``` --- ### 二、移除/忽略蒙版的策略 #### 方法1:主动关闭蒙版 ```java // 定位并点击关闭按钮 try { MobileElement closeBtn = driver.findElement(By.id("com.app:id/btn_close")); closeBtn.click(); // 等待蒙版消失 new WebDriverWait(driver, Duration.ofSeconds(5)) .until(ExpectedConditions.invisibilityOf(closeBtn)); } catch (NoSuchElementException e) { // 无蒙版时跳过 } ``` #### 方法2:绕过蒙版定位底层元素 ```java // 通过坐标直接点击底层元素 (需计算元素中心点) MobileElement target = driver.findElement(By.id("target_element")); Point center = target.getCenter(); new TouchAction(driver).tap(PointOption.point(center)).perform(); ``` #### 方法3:强制穿透蒙版(Android专属) ```java // 使用UIAutomator的forceClick属性 String script = "mobile: clickGesture"; Map<String, Object> params = new HashMap<>(); params.put("elementId", ((RemoteWebElement)target).getId()); params.put("force", true); // 关键参数:强制穿透点击 driver.executeScript(script, params); ``` #### 方法4:禁用蒙版(开发环境) ```java // 通过ADB命令关闭应用蒙版 (需root) driver.executeScript("mobile: shell", ImmutableMap.of( "command", "pm disable com.app.package/com.app.MaskActivity" )); ``` --- ### 三、处理动态蒙版的最佳实践 1. **封装蒙版检测函数** ```java public void handleMask() { List<MobileElement> masks = driver.findElements(By.xpath("//*[contains(@text, '跳过')]")); if(!masks.isEmpty()) masks.get(0).click(); } // 在关键操作前调用 handleMask(); driver.findElement(By.id("main_button")).click(); ``` 2. **结合等待策略** ```java // 等待蒙版出现后再关闭 new WebDriverWait(driver, Duration.ofSeconds(10)) .ignoring(NoSuchElementException.class) .until(d -> { d.findElement(By.id("mask")).click(); return true; }); ``` 3. **多平台兼容处理** ```java if (driver.getCapabilities().getPlatformName().equals(Platform.ANDROID)) { // Android处理逻辑 } else { // iOS处理逻辑 driver.findElement(AppiumBy.iOSNsPredicateString("label == '继续'")).click(); } ``` --- ### 关键注意事项 1. **优先级顺序**:优先尝试关闭按钮 > 坐标点击 > 强制穿透 2. **设备适配**:坐标点击需结合屏幕比例计算,使用相对坐标而非绝对坐标 3. **性能影响**:强制穿透(`force=true`)可能破坏页面逻辑,仅作为最后手段[^1] 4. **工具辅助**:使用Appium Inspector的**元素快照**功能分析蒙版层级结构[^4] > 通过组合主动关闭和强制穿透策略,可处理95%的蒙版场景。对于无法关闭的系统级蒙版(如权限弹窗),需使用`driver.switchTo().alert()`处理[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值