如何用Protractor处理Angular网站弹窗/窗口?切换代码失效求助
解决Protractor弹窗窗口切换失效的问题
我来帮你排查下这个弹窗切换失效的问题~你的代码里可能存在几个常见的疏漏,我给你梳理下针对性的解决方案:
1. 先等待弹窗完全加载再获取句柄
你当前直接调用getAllWindowHandles(),很大概率是在弹窗还没完全打开、句柄还没被浏览器注册的时候就执行了,导致handles数组里只有父窗口的句柄,自然切不到弹窗。可以用browser.wait()来等待句柄数量变为2,确保弹窗已经加载:
// 先引入ExpectedConditions,后面等待元素会用到 const EC = protractor.ExpectedConditions; it('should switch to popUp\'s handle', function () { console.log("ASDASD"); // 等待弹窗出现,确保句柄数量变为2 browser.wait(() => { return browser.driver.getAllWindowHandles().then(handles => handles.length === 2); }, 10000, '弹窗未在规定时间内加载完成'); browser.driver.getAllWindowHandles().then(function (handles) { // 获取当前父窗口句柄,避免依赖固定索引的不确定性 browser.driver.getWindowHandle().then(parentHandle => { // 过滤出非父窗口的句柄,这就是弹窗的句柄 const popUpHandle = handles.find(handle => handle !== parentHandle); browser.driver.switchTo().window(popUpHandle); // 等待弹窗内的目标元素可点击后再操作 browser.wait(EC.elementToBeClickable(element(by.xpath("//span[contains(@class,'mat-button-wrapper')]"))), 5000); element(by.xpath("//span[contains(@class,'mat-button-wrapper')]")).click(); }); }); });
2. 不要依赖固定索引获取弹窗句柄
有时候弹窗的句柄不一定是handles[1](比如浏览器后台有其他标签页时),通过对比当前父窗口句柄来过滤弹窗句柄,会让代码更稳定可靠。
3. 切换窗口后必须等待元素可交互
切换到弹窗后,直接点击元素很可能因为元素还没渲染完成、处于不可点击状态而失败,所以一定要加上elementToBeClickable的等待条件,确保元素就绪后再执行点击操作。
另外还要注意:如果你的弹窗是Angular自带的模态框(比如MatDialog这类),那根本不需要切换窗口句柄,因为模态框本身就在当前窗口的DOM结构里,直接定位操作元素即可。你可以先检查下弹窗的类型哦~
内容的提问来源于stack exchange,提问作者Rani
相关产品推荐
相关产品推荐

