剧作家:点击按钮无法可靠工作(不稳定)

MZi*_*Zin 2 ui-automation cypress playwright

1. 初始帖子

我知道 Playwright 有自动等待功能

我有一个测试,有时单击有效,有时无效。下面是代码。



import { test, expect } from '@playwright/test';

test('test', async ({ page }) => {

 await page.goto('https://website.com');

  await page.getByRole('link', { name: 'Log in' }).click();
  await expect(page).toHaveURL('https://website.com/login/');

});
Run Code Online (Sandbox Code Playgroud)

错误:

Expect(received).toHaveURL(expected) 预期字符串:“https://website.com/login/” 收到字符串:“https://website.com”

这是一段带有登录按钮的 HTML

<span data-v-154d6ddf="" class="absolute-top-right">
  <div class="row justify-end q-gutter-x-sm q-pt-lg q-px-sm">
    <div class="col-auto">
      <a tabindex="0" type="button" href="/login/potential" role="link" class="q-btn q-btn-item non-selectable no-outline q-btn--flat q-btn--rectangle text-white q-btn--actionable q-focusable q-hoverable q-btn--no-uppercase q-btn--wrap">
        <span class="q-focus-helper" tabindex="-1"></span>
        <span class="q-btn__wrapper col row q-anchor--skip">
          <span class="q-btn__content text-center col items-center q-anchor--skip justify-center row">
            <span>Log in</span>
          </span>
        </span>
      </a>
    </div>
    <div class="col-auto">
      <a tabindex="0" type="button" href="/signup" role="link" class="q-btn q-btn-item non-selectable no-outline q-btn--standard q-btn--rectangle bg-primary text-white q-btn--actionable q-focusable q-hoverable q-btn--no-uppercase q-btn--wrap">
        <span class="q-focus-helper"></span>
        <span class="q-btn__wrapper col row q-anchor--skip">
          <span class="q-btn__content text-center col items-center q-anchor--skip justify-center row">
            <span>Sign up</span>
          </span>
        </span>
      </a>
    </div>
    <div class="col-auto">
      <label for="f_2334a082-8df9-41a7-9ca0-403e5ce7c237" class="q-field q-validation-component row no-wrap items-start q-select q-field--auto-height q-select--without-input q-select--without-chips q-field--outlined q-field--float q-field--labeled" style="min-width:120px;max-height:20px">
        <div class="q-field__inner relative-position col self-stretch column justify-center">
          <div tabindex="-1" class="q-field__control relative-position row no-wrap">
            <div class="q-field__control-container col relative-position row no-wrap q-anchor--skip">
              <div id="translate" class="q-field__native row items-center">
                <span>English</span>
                <div id="f_2334a082-8df9-41a7-9ca0-403e5ce7c237" tabindex="0" class="no-outline"></div>
              </div>
              <div class="q-field__label no-pointer-events absolute ellipsis">Translate</div>
            </div>
            <div class="q-field__append q-field__marginal row no-wrap items-center q-anchor--skip">
              <i aria-hidden="true" role="presentation" class="q-select__dropdown-icon fal fa-caret-down q-icon notranslate"></i>
            </div>
          </div>
        </div>
      </label>
    </div>
  </div>
</span>
Run Code Online (Sandbox Code Playgroud)

2. 更新

我尝试了这种变体(见下文),看起来它失败的频率较低,但仍然不能 100% 工作。

我也尝试过.click({force: true})。第三次运行失败。

我是测试自动化的新手。刚开始学习剧作家。

我将不胜感激任何意见/建议。谢谢。



import { test, expect } from '@playwright/test';

test('test', async ({ page }) => {

await page.goto('https://website.com');

const loginBtn = page.getByRole('link', { name: 'Log in' });
expect(await loginBtn.evaluate(node => node.isConnected)).toBe(true) ;

  await page.getByRole('link', { name: 'Log in' }).click();
  await expect(page).toHaveURL('https://website.com/login/');

});
Run Code Online (Sandbox Code Playgroud)

3. 更新

“您应该在点击按钮后等待,然后再验证网址。” 这是@jaky-ruby 的建议

我试过这段代码

test('test2', async ({ page }) => {
      await page.goto('https://website.com/');

      // Note that Promise.all prevents a race condition
      // between clicking and expecting navigation result.
      const [response] = await Promise.all([
        page.getByRole('link', { name: 'Log in' }).click(),
        page.waitForNavigation({ url: 'https://website.com/login' }),
      ]);
      await expect(page).toHaveURL('https://website/login');
    ...
    });
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

4. 更新

我在 Cypress 中创建了类似的测试。这是代码

describe("Login", () => {
beforeEach(() => {
    cy.visit(baseUrl);
});

it.only("Login page should open", () => {
    //does not help: cy.wait(3000);
    cy.get('a[href*="login"]').click();
    //does not help: cy.get(':nth-child(1) > .q-btn > .q-btn__wrapper > .q-btn__content > span').click();
    //does not help: cy.get('#q-app > div > span > div > div:nth-child(1) > a > span.q-btn__wrapper.col.row.q-anchor--skip > span').click();
    cy.url().should("eq", authUrl.replace("env", env) + "/login/potential");

});
Run Code Online (Sandbox Code Playgroud)

});

正如你所看到的,我尝试了定位器的不同变体。有趣的是 Cypress 显示了这个错误。不确定这是否与剧作家测试中出现的问题相同。

CypressError
Run Code Online (Sandbox Code Playgroud)

4050 毫秒后超时重试:cy.click() 失败,因为此元素:...被另一个元素覆盖:

在此输入图像描述

在此输入图像描述

在此输入图像描述

我试图在 DOM 中找到该元素,但它不在那里。

5. 更新

我不明白的另一件事是,当我在赛普拉斯中选择“单击”步骤并使用选择器选择我的按钮时,它会向我显示选择器cy.get('[data-layer="Content"]')。同样,当我尝试在 DOM 中搜索它时,它不在那里。

在此输入图像描述

在此输入图像描述

6. 更新

我使用Trace Viewer检查了 Playwright 中的每个步骤。有趣的。日志显示 Playwright 正在等待元素可见且稳定。但是,在附加页面上,“登录”和“注册”按钮均不可见且仍在加载(事实证明您可以检查它。这不仅仅是静态屏幕截图)。我认为,在这个例子中,Playwright 的自动等待可能不够好。可能,元素实际上并不稳定并且仍在加载,但 Playwright 执行的单击不起作用。现在问题是,“我可以做一些额外的等待来确定该元素已加载并且稳定吗?”

在此输入图像描述

MZi*_*Zin 9

好吧,看起来我找到了~~解决方案~~一种让我的测试不那么不稳定的方法。

\n

有时测试仍然失败。我认为,我添加的额外 2 个等待只会为元素加载提供更多时间,因此在大多数情况下,这可能足以让按钮达到稳定状态。这就是点击有效的原因。请注意,在下面的屏幕截图中,“networkidle”为 1.4 秒

\n

这是最终的代码

\n
import { test, expect } from \'@playwright/test\';\n\ntest(\'test\', async ({ page }) => {\n\nawait page.goto(\'https://website.com\');\n  await page.waitForLoadState(\'networkidle\'); // <-  until there are no network connections for at least 500 ms.\n  await page.getByRole(\'link\', { name: \'Log in\' }).waitFor();  // <- wait for element\n  await page.getByRole(\'link\', { name: \'Log in\' }).click();\n  await expect(page).toHaveURL(\'https://website.com/login/\');\n\n});\n\n\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述

\n

在这里分享我一路上发现的一些有趣的链接

\n\n