This supports mixed quotes locators in JavaScript where we are not sure
what quote is the correct one, so we normalize to unescaped single quote
when comparing with the original.
Drive-by: we were allowing single quotes in Python, Java and .NET, but
these are actually not allowed.
Regressed in #27718.
Fixes#28630.
Usually, we can just chain two locators with `>>` to implement
`Locator.locator(locator)`. However, this does not play nicely with more
advanced inner locators like `or` and `and`:
```ts
const child = page.locator('input').or(page.locator('button'));
page.locator('parent').locator(child);
```
One would expect the above to locate "input or button" inside a
"parent". However, currently it locates "input inside a parent" or
"button", because it's translated to `parent >> input >>
internal:or="button"`.
To fix this, we have to wrap inner locator into `internal:chain` and
query it separately from the parent.
Fixes#23724.
There is no locator counterpart for it. Instead, produce a regex.
Also fix locator generator to not produce incorrect locator in this
case.
Fixes#21649.
Following the `getByText()` and other methods:
- By default, matching is substring and case-insensitive. Before, it was
only case-insensitive, but not substring.
- With new option `exact: true`, matching is full string and
case-sensitive.
- Matching always normalizes whitespace.
- Codegen generates `exact: false` by default.
- `internal:role` treats `[name="foo"i]` as non-exact match.
Various fixes:
- Updated `getByRole` docs to match the reality.
- Locator generator edge cases.
- prefer `role=checkbox` over `input[type=checkbox]`
- prefer `#id` over `input[type=checkbox]` and `role=checkbox`
- prefer `text=foo` over `internal:has-text=foo`
- ignore `none` and `presentation` roles
- remove non-strict support