You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让WebDriverIO等待React Native Web页面完全加载完成

问题核心原因与解决方案

React Native Web应用渲染时会内置过渡动画、动态样式修改逻辑,普通的WebdriverIO元素等待方法无法适配这类场景,结合你当前代码的问题,优化方案如下:

现有代码问题

  • 代码中直接使用document.querySelector("#View")属于浏览器端原生API,无法在Node环境运行的WebdriverIO测试脚本中执行,会直接抛出未定义错误,需删除
  • waitFor系列方法传参不规范,WebdriverIO v7及以上版本需统一使用对象格式传参,否则超时配置不生效
  • 未做iframe上下文切换,仅识别到iframe元素存在无法操作内部元素,必须切换上下文后才可访问iframe内DOM
  • 未处理RN Web的过渡动画等待逻辑,页面切换过程中元素DOM已存在但处于动画中,点击、可见性判断都会失效
  • Appium移动端环境未校验当前处于WEBVIEW上下文,可能会错误识别原生控件导致元素查找失败

优化后代码

describe('My Login application', async () => {
  beforeEach(async () => {
    // 先确认当前在WEBVIEW上下文,适配Appium移动端浏览器环境
    const contexts = await browser.getContexts();
    const webContext = contexts.find(ctx => ctx.includes('WEBVIEW'));
    if (webContext) await browser.switchContext(webContext);
    
    await browser.url('./');
    // 等待页面加载完成、网络空闲
    await browser.waitUntil(async () => {
      return await browser.execute(() => {
        return window.performance.timing.loadEventEnd > 0 
          && window.performance.getEntriesByType('resource').every(r => r.responseEnd > 0)
      })
    }, { timeout: 30000, interval: 500 });
    await browser.setTimeout({'script': 30000})
  });

  it('turn pages', async function () {
    const view = $('#View')
    // 同时校验存在+可见,适配RN Web渲染逻辑
    await view.waitForExist({ timeout: 25000 });
    await view.waitForDisplayed({ timeout: 10000 });
    const isview = await view.isDisplayed();
    console.log('isview:' + isview)
    if(isview) {
      const header = $('.header__wrapper')
      await header.waitForClickable({ timeout: 30000 });
      await header.click();
      // 等待页面跳转动画完成
      await browser.pause(1000);
      
      const orderView = $('.OrderView');
      await orderView.waitForDisplayed({ timeout: 30000 });
      console.log('order value:' + await orderView.getHTML());
      console.log('checking title:')
      
      const title1 = await $('.chapter-title')
      await title1.waitForExist({timeout: 50000});
      await title1.waitForDisplayed({timeout: 10000});
      console.log('checking html:')
      console.log('html value:' + await title1.getHTML())
      
      const form = await $('iframe')
      await form.waitForExist({ timeout: 15000 });
      // 切换到iframe上下文
      await browser.switchToFrame(form);
      console.log('已切换到iframe上下文')

      await browser.setTimeout({'script': 20000})
      // 激活页面焦点,避免移动端按键不生效
      await browser.execute(() => document.body.focus());
      await browser.keys("ArrowLeft")
      await browser.keys("Enter")

      const container = await $('.container');
      await container.waitForExist({timeout: 50000});
      await container.waitForDisplayed({timeout: 10000});
      // 测试完成后可切回主上下文
      // await browser.switchToParentFrame();
      await browser.pause(3000);
    }
  });
});

额外适配RN Web的等待优化

可以封装自定义等待方法,适配RN Web的动态样式逻辑:

async function waitForRnElementDisplayed(selector, timeout = 30000) {
  await browser.waitUntil(async () => {
    const el = await $(selector);
    const isDisplayed = await el.isDisplayed();
    if (!isDisplayed) return false;
    // 额外校验元素透明度、transform动画状态
    const styles = await el.getCSSProperties(['opacity', 'transform']);
    return styles.opacity > 0.9 && styles.transform === 'matrix(1, 0, 0, 1, 0, 0)';
  }, { timeout, interval: 500 });
}

后续查找RN Web元素时直接调用该方法即可,避免动画过程中的误判。

内容的提问来源于stack exchange,提问作者brocheppu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 22:09:00