如何在WebdriverIO中测试窗口切换?遇窗口已关闭错误怎么解决?
解决窗口切换时的"no such window"错误
问题描述
我开发了一个双窗口应用:初始显示第一个窗口,点击按钮后第一个窗口关闭,第二个窗口打开。执行测试时遇到错误:
waitUntil condition failed with the following reason: no such window: target window already closed from unknown error: web view not found
测试代码如下:
beforeEach(async () => { const authButton = await authPageObject.authButton; await authButton.click(); await browser.waitUntil( async () => { const uploadFileButton = await loaderPageObject.uploadFileButton; return uploadFileButton !== undefined; }, { timeout: DEFAULT_TIMEOUT }, ); const handles = await browser.getWindowHandles(); await browser.switchToWindow(handles[1]); await dialogPageObject.showDialog([imagesFilePath]); const images = await loaderPageObject.imagesFileButton; await images.click(); });
问题原因
点击按钮后第一个窗口直接关闭,但测试代码仍在原窗口的上下文里执行waitUntil检查元素,此时原窗口已不存在,必然抛出"找不到窗口"的错误。同时窗口切换的时机错误,应该先确认新窗口出现并切换上下文,再检查新窗口内的元素。
解决方案
- 优先等待窗口上下文切换:点击按钮后,立即等待窗口句柄列表更新,确认新窗口出现后切换过去,避免在已关闭的原窗口中执行操作。
- 调整元素检查时机:切换到新窗口后,再检查该窗口内的目标元素是否存在。
修改后的测试代码:
beforeEach(async () => { // 记录初始窗口句柄 const initialHandles = await browser.getWindowHandles(); const authButton = await authPageObject.authButton; await authButton.click(); // 等待原窗口关闭、新窗口打开,确认当前句柄不是初始句柄 await browser.waitUntil( async () => { const currentHandles = await browser.getWindowHandles(); return currentHandles.length === 1 && currentHandles[0] !== initialHandles[0]; }, { timeout: DEFAULT_TIMEOUT }, ); // 切换到新窗口 const newHandles = await browser.getWindowHandles(); await browser.switchToWindow(newHandles[0]); // 在新窗口上下文内检查目标元素 await browser.waitUntil( async () => { const uploadFileButton = await loaderPageObject.uploadFileButton; return uploadFileButton !== undefined; }, { timeout: DEFAULT_TIMEOUT }, ); await dialogPageObject.showDialog([imagesFilePath]); const images = await loaderPageObject.imagesFileButton; await images.click(); });
关键说明
- 核心逻辑是绝不操作已关闭的窗口上下文,点击按钮后第一时间完成窗口切换,后续所有元素操作都在新窗口中执行。
- 如果业务逻辑是"原窗口关闭+新窗口打开",窗口句柄数量会保持1,但句柄值会变化,因此判断条件需要验证当前句柄与初始句柄不同。
内容的提问来源于stack exchange,提问作者Masquitos
相关产品推荐
相关产品推荐

