Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Looping all elements results in some elements being selected multiple times #22517

Closed
1 task done
hex0cter opened this issue Apr 20, 2023 · 4 comments
Closed
1 task done

Comments

@hex0cter
Copy link
Contributor

hex0cter commented Apr 20, 2023

System info

  • Playwright Version: 1.32.3
  • Operating System: [macOS 13.2.1 (22D68)]
  • Browser: [Chromium]
  • Other info:

Source code

  • I provided exact source code that allows reproducing the issue locally.

Link to the GitHub repository with the repro

playwright-locator-loop

or

Config file

// playwright.config.ts

import { PlaywrightTestConfig } from "@playwright/test";

const config: PlaywrightTestConfig = {
  timeout: 60 * 1000,
  retries: 0,
  snapshotDir: "./snapshots",
  reporter: [
    ["html", { outputFolder: `playwright-report` }],
    ["line"],
  ],
  projects: [
    {
      name: "chrome",
      use: {
        browserName: "chromium",
        channel: "chrome",
        headless: true,
        viewport: { width: 1500, height: 730 },
        acceptDownloads: true,
        screenshot: "only-on-failure",
        video: "on",
        trace: "on",
      },
    }
  ],
};

export default config;

Test file (self-contained)

  test("should select all checkboxes by a loop", async ({ page }) => {
    page.goto(
      "https://staging.scrive.com/s/9221714692413010618/9221932570717574475/d0661b5e62380af4"
    );
    await page.waitForLoadState();
    await page.waitForLoadState("networkidle");

    const checkboxes = await page.locator("rect[data-test='checkbox']").all();
    for (const checkbox of checkboxes) {
      await checkbox.click();
    }

    await expect(page.locator("[data-test='signview_sign_btn']")).toBeEnabled();
  });

Steps

  • npm install
  • npm test

Expected

All checkboxes should be checked by the end of the tests. And the Next button on the bottom should be enabled

Actual

Some of the checkboxes are clicked multiple times and others are never clicked. When I looked at the trace, it seems when playwright loops through all the matching elements, it calls locator.click(rect[data-test='checkbox'] >> nth=<n> every time, and the order of that matched list may be non deterministic.

@hex0cter hex0cter changed the title [BUG] Looping all elements results in some elements selected multiple times [BUG] Looping all elements results in some elements being selected multiple times Apr 20, 2023
@dgozman
Copy link
Contributor

dgozman commented Apr 20, 2023

@hex0cter This is expected. Locator.all only works for static lists of elements, without dynamic changes. Let me emphasize that in the docs.

@hex0cter
Copy link
Contributor Author

hex0cter commented Apr 20, 2023

@dgozman Thanks for the explanation. However my perception is that the problem is in locator.nth() instead of locator.all(). Assuming we have the following code:

  test("should select all checkboxes by nth", async ({ page }) => {
    const numberOfCheckboxes = await page.locator("rect[data-test='checkbox']").count();
    for (let i = 0; i < numberOfCheckboxes; i++) {
      await page.locator("rect[data-test='checkbox']").nth(i).click();
    }

    await expect(page.locator("[data-test='signview_sign_btn']")).toBeEnabled();
  });

The result of this test is exactly the same as in the previous one, which indicate locator.nth() do not always guarantee the order of matching element on a dynamic page. Can you confirm that?

Many thanks.

@dgozman
Copy link
Contributor

dgozman commented Apr 20, 2023

The result of this test is exactly the same as in the previous one, which indicate locator.nth() do not always guarantee the order of matching element on a dynamic page. Can you confirm that?

Yes, locator.nth() will get the nth element in the DOM order upon every click() call. If the DOM order of the elements changes over time, it will pick unexpected elements.

@hex0cter
Copy link
Contributor Author

That makes sense. I will use other methods to go through the list then. Again thanks for your explanation!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants