我正在使用 Playwright 的 JS 库,但在 hover 功能方面遇到了一些问题。我通过 all 调用获得了定位器列表。然后我循环遍历该列表并在列表中的每个定位器上调用悬停。悬停时,每个元素应该改变颜色并打开一个弹出窗口。我在打开不同站点的两个不同测试中执行此操作,但最终呈现相同的 html。两项测试均使用 Chromium 运行。在一项测试中,将鼠标悬停在每个元素上都可以按预期工作(颜色发生变化并且弹出窗口变得可见)。在另一个测试中,列表中的第一个元素将在悬停时改变颜色,但不会打开弹出窗口。如果我手动将鼠标悬停在列表中的第二个元素上(按预期工作),然后循环所有元素,则悬停在所有元素上按预期工作。
以前有人和剧作家遇到过这个问题吗?我特别困惑的是,悬停在一次测试中按预期工作,但在另一次测试中却不然。两个测试都在 iframe 中执行此悬停操作,以防万一这很重要。
我获取所有定位器的功能:
#getAll = async () =>
await this.iframe.locator('.qa-hot-buttons-list.p0.m0').getByRole('button').all();
我在工作测试中的功能:
for (const button of buttons) {
await button.hover();
const buttonPopover = await myController.getActiveButtonPopover();
await expect(buttonPopover).toBeVisible();
}
我在损坏的测试中的功能:
await buttons[1].hover();
for (const button of buttons) {
await button.hover();
const buttonPopover = await myController.getActiveButtonPopover();
await expect(buttonPopover).toBeVisible();
}
您遇到的行为可能是由于 iframe 中元素的加载方式或悬停操作的时间造成的。在损坏的测试中,当触发悬停操作时,元素可能尚未完全准备好进行交互。
在尝试将鼠标悬停在元素上之前,您可能需要引入一些等待或确保元素处于可交互状态。您可以尝试使用 waitForSelector 或 waitForFunction 的组合来确保元素在悬停之前准备好进行交互。
// Wait for the first element in the list to become visible/ready for interaction
await page.waitForSelector('.qa-hot-buttons-list.p0.m0 [role="button"]:nth-of-type(1)');
// Hover over the first element
await buttons[0].hover();
// Wait for a short interval to ensure the hover action triggers properly
await page.waitForTimeout(500); // Adjust timing as needed
// Loop through each button for hover actions
for (const button of buttons) {
await button.hover();
// You might need to add a slight delay here before interacting with the popover
await page.waitForTimeout(500); // Adjust timing as needed
const buttonPopover = await myController.getActiveButtonPopover();
await expect(buttonPopover).toBeVisible();
}
调整 waitForTimeout 中的时间,以更好地适应特定场景中元素的响应能力。这有助于确保在执行悬停操作之前元素已完全加载并准备好进行交互。
此外,考虑到您正在处理 iframe,您可能还需要切换上下文或以不同方式处理 iframe,以确保在正确的框架上下文中执行操作。
如果计时或等待元素不能解决问题,则可能值得探索工作测试和损坏测试之间的环境或配置是否存在任何可能影响行为的差异。