Playwright中如何等待所有加载Spinner消失?表单保存测试失败
表单保存测试加载器等待问题解决方案
表单保存测试失败,原因是加载器阻止操作,尝试多种等待方法均无效。页面会出现2个及以上(有时3个或更多)加载组件元素,需等待所有加载器消失后再执行操作。
你尝试过以下方法但未成功:
- 自定义异步函数:
async waitForLoadersToDisappear() { const loaders = await this.page.getByTestId('form-loader').all(); await Promise.all( loaders.map(async (loader) => { await loader.waitForElementState('hidden'); }), ); }
- 直接使用断言语句:
await expect(page.$$('.loader')).toBeHidden(); await expect(page.locator('div[class="loader"]')).toBeHidden(); await expect(page.getByTestId('form-loader').all()).toBeHidden(); const loader = page.$$('form-loader'); // 也尝试过locator.all(),然后调用waitForElementState('hidden')
以下是针对该问题的有效解决方案:
1. 等待所有加载器从DOM中移除
使用toHaveCount(0)断言,Playwright会自动等待直到所有匹配的加载器元素被移除:
await expect(page.getByTestId('form-loader')).toHaveCount(0);
该方法会持续检查元素数量,直到加载器全部消失,无需手动处理多元素的遍历问题。
2. 等待所有加载器变为隐藏状态(元素仍在DOM中)
如果加载器是通过CSS隐藏(如display: none)而非移除DOM,直接在Locator上使用toBeHidden()断言:
await expect(page.getByTestId('form-loader')).toBeHidden({ timeout: 10000 });
Playwright会自动等待所有匹配的加载器元素都变为隐藏状态,无需手动遍历每个元素。
3. 针对伪元素的等待方案
如果加载器通过::before伪元素显示加载状态,可以通过page.waitForFunction检查伪元素的样式变化:
await page.waitForFunction(() => { const loaders = document.querySelectorAll('[data-testid="form-loader"]'); return Array.from(loaders).every(loader => { const beforeStyle = window.getComputedStyle(loader, '::before'); // 根据实际伪元素的隐藏条件调整,比如content为空或display为none return beforeStyle.display === 'none' || beforeStyle.content === 'none'; }); }, { timeout: 10000 });
4. 修复原自定义函数的逻辑问题
原函数的问题在于一次性获取元素列表,无法处理后续新出现的加载器。修改为持续检查直到所有元素都隐藏:
async waitForLoadersToDisappear() { await page.waitForFunction(async () => { const loaders = await page.getByTestId('form-loader').all(); if (loaders.length === 0) return true; // 等待每个加载器隐藏,超时则返回false继续重试 return Promise.all( loaders.map(loader => loader.waitForElementState('hidden', { timeout: 1000 })) ).then(() => true).catch(() => false); }, { timeout: 10000 }); }
内容的提问来源于stack exchange,提问作者Henrique
相关产品推荐
相关产品推荐

