appium 二次切换webview后无法找到页面元素

本文解决Appium在Android自动化测试中,二次切换到WebView后无法定位元素的问题。原因为Chromedriver实例未重新生成。通过修改android-hybrid.js文件中的startChromedriverProxy函数,强制每次切换WebView时都创建新的Chromedriver实例。

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

问题:在使用Appium进行android自动化测试时,第一次切换webview可以正常找到元素,但切换到NATIVE_APP后,再次切换到webview时,appium就无法定位元素,且等待一段时间后,自动退出执行。

原因为:Appium第一次切换到Html页面时,会新生成一个Chromedriver;当第二次切换到Html时,会使用已经存在的Chromedriver。

 

解决方式:

  找到Appium\Appium\node_modules\appium\lib\devices\android目录下的android-hybrid.js文件,找到如下代码

androidHybrid.startChromedriverProxy = function (context, cb) {
  cb = _.once(cb);
  logger.debug("Connecting to chrome-backed webview");
  if (this.chromedriver !== null) {
    return cb(new Error("We already have a chromedriver instance running"));
  }

  if (this.sessionChromedrivers[context]) {
      //in the case where we've already set up a chromedriver for a context,'
      //we want to reconnect to it, not create a whole new one
      this.setupExistingChromedriver(context, cb);
    } else {
      this.setupNewChromedriver(context, cb);
    }
   
};

  

然后,修改如下:

androidHybrid.startChromedriverProxy = function (context, cb) {
  cb = _.once(cb);
  logger.debug("Connecting to chrome-backed webview");
  if (this.chromedriver !== null) {
    return cb(new Error("We already have a chromedriver instance running"));
  }

  // 修改时间:2018-07-23  目的:二次切换webview后,chromeDriver未重新生成,无法定位元素
  // if (this.sessionChromedrivers[context]) {
  //   // in the case where we've already set up a chromedriver for a context,
  //   // we want to reconnect to it, not create a whole new one
  //   this.setupExistingChromedriver(context, cb);
  // } else {
   //   this.setupNewChromedriver(context, cb);
   // }
   this.setupNewChromedriver(context,cb);
  // 修改时间:2018-07-23  目的:二次切换webview后,chromeDriver未重新生成,无法定位元素
};

 

转载于:https://www.cnblogs.com/JcHome/p/9429717.html

<think>首先,用户的问题是关于Appium自动化测试中如何切换页面的操作。用户说:“我想在Appium自动化测试中实现页面切换操作方法 请问Appium 自动化测试中如何切换页面”。 我需要参考提供的引用内容来构建回答。引用包括: - [^1]: 关于Appium自动化测试项目,使用Python开发脚本,连接Appium server。 - [^2]: 具体代码示例,展示如何在Appium中定位H5页面元素,包括切换context(从原生到WebView)。 - [^3]: 关于Appium自动化测试的详细指南,包括连接模拟器。 用户的核心需求是“切换页面”的操作方法。在Appium中,“切换页面”可能指的是几种情况: 1. **切换context**:当应用中有WebView(H5页面)时,需要从原生上下文切换WebView上下文,反之亦然。引用[^2]中展示了这个操作:`driver.switch_to.context(context[-1])` 切换WebView,然后 `driver.switch_to.context("NATIVE_APP")` 切换回原生。 2. **切换activity或页面**:在原生应用中,切换页面可能意味着导航到同的activity或fragment。这通常通过元素操作(如点击按钮)来实现,而是直接切换页面。 3. **切换窗口或标签**:如果应用中有多个窗口或标签,类似于Web自动化中的窗口切换。 在引用[^2]中,重点展示了context切换,用于处理混合应用(hybrid apps)。用户的问题提到“页面切换”,结合引用,我认为context切换是主要部分。 回答结构需要清晰,逐步解决问题: 1. **理解需求**:解释Appium中的页面切换概念。 2. **实现方法**:提供具体步骤和代码示例。 3. **注意事项**:包括常见问题和优化。 使用中文回答。确保行内数学表达式用$...$,但这里可能需要数学表达式,因为主题是Appium自动化测试。如果有数学相关,比如性能分析,但用户问题涉及,所以可能需要。 系统指令要求生成相关问题,所以我需要在回答末尾添加相关问题。 参考用户上一次的问题:用户提到了“页面切换操作方法”,所以我应该基于引用提供实用指导。 关键点从引用[^2]: - 获取所有contexts:`contexts = driver.contexts` - 切换WebView:`driver.switch_to.context(contexts[-1])`(假设WebView是最后一个) - 切换回原生:`driver.switch_to.context("NATIVE_APP")` 此外,引用[^3]提到连接模拟器,但用户问题更侧重于操作,所以可能直接相关。 回答结构: 1. **引言**:简要解释Appium中页面切换的含义。 2. **步骤**:详细说明如何切换页面,包括context切换元素导航。 3. **代码示例**:提供类似引用[^2]的代码片段。 4. **注意事项**:如隐式等待、context管理。 5. **生成相关问题**:在末尾。 最后,添加引用标识:[^2] 因为主要参考了代码示例。 完整回答框架: - 解释页面切换Appium中的含义。 - 描述切换context的方法。 - 提供代码示例。 - 讨论其他方式(如通过元素操作导航)。 - 添加相关问题。</think>### Appium自动化测试中的页面切换操作方法 在Appium自动化测试中,“页面切换”通常指在移动应用中导航到同界面或处理混合应用(hybrid apps)中的上下文(context切换。这包括原生页面(Native App)和WebView(H5页面)之间的转换。根据您的需求,我将基于Appium的Python客户端库,详细解释实现方法。核心思路是通过Appium的API来管理上下文或模拟用户操作(如点击按钮)来实现导航。下面逐步说明操作步骤、代码示例和注意事项。 #### 1. **理解页面切换的类型** - **原生页面切换**:在纯原生应用中,页面切换通常通过模拟用户操作(如点击按钮)来触发导航到新activity或fragment。Appium通过元素定位和交互实现。 - **上下文切换Context Switching)**:在混合应用中(如嵌入WebView的H5页面),需要显式切换上下文才能操作同内容。Appium支持在原生(`NATIVE_APP`)和WebView(如`WEBVIEW_com.xkw.client`)之间切换。这是处理页面切换的关键,尤其在涉及H5内容时[^2]。 #### 2. **实现页面切换的步骤** 以下是两种常见场景的操作方法。代码示例基于Python和Appium的WebDriver API,参考了引用[^2]中的实战代码。 ##### (1) 原生页面切换:通过元素操作导航 在原生应用中,页面切换本质是用户交互过程。您需要定位元素(如按钮)并执行点击操作Appium会自动处理页面跳转。 - **步骤**: 1. 确保Driver已初始化并连接到Appium server。 2. 使用隐式或显式等待确保元素操作。 3. 定位目标元素(如返回按钮或导航链接)。 4. 执行点击操作(`click()`),Appium会触发页面跳转。 5. 可选:验证新页面是否加载成功(通过元素存在性检查)。 - **代码示例**: 假设从一个列表页切换到详情页,点击一个元素实现切换。 ```python from appium import webdriver from appium.webdriver.common.appiumby import AppiumBy import time # 初始化Driver(参考引用[^2]的desired_caps配置) desired_caps = { "platformName": "Android", "platformVersion": "7.1.2", "udid": "127.0.0.1:62001", # 模拟器端口,参考引用[^3] "appPackage": "com.xkw.client", "appActivity": "com.zxxk.page.main.LauncherActivity", "noReset": True, "automationName": "uiautomator2" } driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps) driver.implicitly_wait(30) # 隐式等待,确保元素加载 # 示例:从首页切换到活动页(通过点击元素实现页面切换) # 步骤1: 定位首页的元素(如一个图片按钮) home_element = driver.find_element(AppiumBy.ID, "com.xkw.client:id/iv_horizontal_pic") home_element.click() # 执行点击,触发页面切换 time.sleep(2) # 短暂等待新页面加载 # 步骤2: 验证新页面(例如,检查详情页的标题是否存在) detail_element = driver.find_element(AppiumBy.ID, "com.xkw.client:id/tv_detail_title") if detail_element.is_displayed(): print("成功切换到详情页") # 步骤3: 返回上一页(模拟返回操作) driver.back() # 使用Appium的back()方法返回 # 或者定位返回按钮:back_btn = driver.find_element(AppiumBy.ID, "com.xkw.client:id/common_toolbar_back_img") # back_btn.click() ``` ##### (2) 上下文切换:处理WebView(H5页面) 在混合应用中,页面切换涉及上下文管理。Appium允许在原生和WebView之间切换,以操作H5元素。这是引用[^2]的核心内容。 - **步骤**: 1. 获取所有可用上下文(contexts):使用`driver.contexts`列出当前所有上下文。 2. 切换到目标上下文: - 切换WebView:通常选择`WEBVIEW_`开头的上下文(如`contexts[-1]`)。 - 切换回原生:使用`"NATIVE_APP"`。 3. 在WebView操作元素切换WebView后,使用Selenium风格的定位(如CSS选择器)。 4. 切换回原生上下文:完成操作后返回。 - **代码示例**: 参考引用[^2],展示从原生页切换到H5页面并返回。 ```python # 初始化Driver(同上) # 步骤1: 点击入口进入混合页面(例如,活动页包含WebView) driver.find_element(AppiumBy.ID, "com.xkw.client:id/iv_horizontal_pic").click() time.sleep(5) # 等待WebView加载 # 步骤2: 获取所有上下文并切换WebView contexts = driver.contexts # 例如输出:['NATIVE_APP', 'WEBVIEW_com.xkw.client'] print("可用上下文:", contexts) driver.switch_to.context(contexts[-1]) # 切换WebView(假设最后一个) # 步骤3: 在WebView操作H5元素(使用Web定位方式) driver.find_element(AppiumBy.ID, "getgifts").click() # 点击H5按钮 time.sleep(1) # 步骤4: 切换回原生上下文 driver.switch_to.context("NATIVE_APP") # 返回到原生页面 driver.find_element(AppiumBy.ID, "com.xkw.client:id/common_toolbar_back_img").click() # 点击原生返回按钮 ``` #### 3. **注意事项和常见问题** - **上下文管理**: - 在切换上下文前,确保WebView已加载(使用`time.sleep()`或显式等待)。Appium的`contexts`列表可能动态变化。 - WebView操作需要ChromeDriver配置(如引用[^2]中的`chromedriverExecutable`),否则可能报错。 - **性能优化**: - 减少硬编码等待(如`time.sleep()`),改用显式等待(`WebDriverWait`)提高脚本稳定性。 - 在混合应用中,频繁切换上下文可能影响性能。建议批量操作WebView元素。 - **错误处理**: - 如果切换失败,检查上下文名称是否正确(如`"NATIVE_APP"`为固定值)。 - 确保模拟器或设备已正确连接(参考引用[^3],使用`adb connect`命令验证端口)。 - **通用性**: - 此方法适用于Android和iOS,但iOS的WebView上下文名称可能同(如`WEBKIT`前缀)。 - 对于纯页面导航(非上下文),优先使用元素操作而非硬编码坐标。 通过以上方法,您可以在Appium中高效实现页面切换。关键是根据应用类型(原生或混合)选择合适的策略。引用[^2]提供了实战基础,确保代码可复现[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值