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]: inputs don't emit selectionchange events #34053

Open
thejackshelton opened this issue Dec 17, 2024 · 1 comment
Open

[Bug]: inputs don't emit selectionchange events #34053

thejackshelton opened this issue Dec 17, 2024 · 1 comment

Comments

@thejackshelton
Copy link

thejackshelton commented Dec 17, 2024

Version

1.46.0

Steps to reproduce

  1. type a character
  2. do a playwright press action with left arrow
  3. notice the selectionchange event does not fire

Expected behavior

selectionchange events to be fired, similar to the native input.

Actual behavior

selectionchange events did not fire.

Additional context

I was working on a headless OTP input, that required the use of selection change events. I noticed the actual behavior in the browser was inconsistent with what I was seeing in the playwright test.

A current workaround is having it take a snapshot of the selectionchange event each time.

async function setupEventListeners(input: Locator) {
  await input.evaluate((el) => {
    return new Promise<void>((resolve) => {
      let lastStart = (el as HTMLInputElement).selectionStart;
      let lastEnd = (el as HTMLInputElement).selectionEnd;
      let stableCount = 0;
      let isResolved = false;

      const checkSelection = () => {
        if (isResolved) return;

        const currentStart = (el as HTMLInputElement).selectionStart;
        const currentEnd = (el as HTMLInputElement).selectionEnd;

        console.log("selection:", currentStart, currentEnd);

        if (currentStart === lastStart && currentEnd === lastEnd) {
          stableCount++;
          if (stableCount >= 3) {
            isResolved = true;
            resolve();
            return;
          }
        } else {
          stableCount = 0;
        }

        lastStart = currentStart;
        lastEnd = currentEnd;
        requestAnimationFrame(checkSelection);
      };

      const selectionListener = () => {
        if (isResolved) return;

        console.log(
          "selection change:",
          (el as HTMLInputElement).selectionStart,
          (el as HTMLInputElement).selectionEnd
        );
        stableCount = 0;
      };

      el.addEventListener("selectionchange", selectionListener);
      checkSelection();

      // Cleanup after 5 seconds to prevent hanging
      setTimeout(() => {
        if (!isResolved) {
          isResolved = true;
          el.removeEventListener("selectionchange", selectionListener);
          resolve();
        }
      }, 5000);
    });
  });
}

Environment

System:
    OS: macOS 15.1
    CPU: (16) arm64 Apple M4 Max
    Memory: 2.77 GB / 48.00 GB
  Binaries:
    Node: 22.12.0 - ~/.nvm/versions/node/v22.12.0/bin/node
    Yarn: 1.22.22 - /usr/local/bin/yarn
    npm: 10.9.0 - ~/.nvm/versions/node/v22.12.0/bin/npm
    pnpm: 9.5.0 - /usr/local/bin/pnpm
    bun: 1.1.7 - ~/.bun/bin/bun
  IDEs:
    VSCode: 0.43.6 - /usr/local/bin/code
  Languages:
    Bash: 3.2.57 - /bin/bash
  npmPackages:
    @playwright/test: ^1.46.0 => 1.46.0
@pavelfeldman
Copy link
Member

pavelfeldman commented Dec 17, 2024

How do I run your example? Please follow the issue template and make sure I can run it locally.

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