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

querySelector not work for attr whose value contains colon #632

Closed
ilyydy opened this issue Oct 22, 2022 · 2 comments · Fixed by #997
Closed

querySelector not work for attr whose value contains colon #632

ilyydy opened this issue Oct 22, 2022 · 2 comments · Fixed by #997
Assignees
Labels
bug Something isn't working

Comments

@ilyydy
Copy link

ilyydy commented Oct 22, 2022

Describe the bug
querySelector not work for attr whose value contains colon. But in browser, it will be ok.

To Reproduce

import { Window } from 'happy-dom';

const window = new Window();
const document = window.document;

document.body.innerHTML = `<meta ab="a:b"/>`;
const element = document.querySelector('[ab="a\\:b"]');
console.log(element !== null); // output false
const element1 = document.querySelector('[ab="a:b"]');
console.log(element1 !== null); // output false

Expected behavior
should find meta element

Screenshots
If applicable, add screenshots to help explain your problem.

Device:

  • OS: win10
  • Browser: chrome
  • Version: 106

Additional context
Add any other context about the problem here.

@ilyydy ilyydy added the bug Something isn't working label Oct 22, 2022
@Pumpuli
Copy link

Pumpuli commented Mar 16, 2023

This is actually quite a big problem when happy-dom is used for testing React applications. That's because React's useId() hook returns strings which always seem to contain colon characters. And even if useId() is not used directly, for example Material UI's form field components use it internally. The typical use case for useId() is form controls and their labels:

function PasswordInput() {
  const suffix = useId();

  return (
    <>
      <label>
        Password:
        <input type="password" aria-describedby={`password-${suffix}`} />
      </label>
      <p id={`password-${suffix}`}>Should contain at least 18 characters.</p>
    </>
  );
}

The result of that is something like aria-describedby="password-:r5:" and id="password-:r5:". @testing-library/dom then tries to do .querySelector('[id="password-:r5:"]'), which yields null on happy-dom. The problem can be traced back to the regex that checks whether a selector has a pseudo class:

const PSUEDO_REGEXP =
/(?<!\\):([a-zA-Z-]+)\(([0-9n+-]+|odd|even)\)|(?<!\\):not\(([^)]+)\)|(?<!\\):([a-zA-Z-]+)/g;

However, I'm not sure what's the best way to go about fixing this. Should the regex be made more complicated to make sure that an attribute selector is excluded?

@capricorn86 capricorn86 self-assigned this Jul 17, 2023
capricorn86 added a commit that referenced this issue Jul 19, 2023
…ork-for-attr-whose-value-contains-colon

#632@patch: Adds support for using an escape character in attribute q…
@capricorn86
Copy link
Owner

Thank you for reporting @ilyydy and @Pumpuli ! 🙂

I believe that the query selector for [ab="a:b"] was fixed in v9.10.0.

I have now added support for using an escape character, so that the [ab="a\\:b"] query selector will work.

You can read more about the release here:
https://github.com/capricorn86/happy-dom/releases/tag/v10.5.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants