Use corret FormLabel for attribute with SingleSelectControl id attribute (#38835)

The `<label for="…">` must match `<button id="…">`.

Before `/realms/{{REALM}}/account/personalInfo`:

```html
<div class="pf-v5-c-form__group">
    <div class="pf-v5-c-form__group-label">
        <label class="pf-v5-c-form__label"
               for="attributes.locale" <!-- Does not match `<button id>` -->
        >[…]</label>
    </div>
    <div class="pf-v5-c-form__group-control">
        <button class="pf-v5-c-menu-toggle pf-m-full-width" type="button" aria-label="toggle" aria-expanded="false"
                id="locale" <!-- Does not match `<label for>` -->
                data-ouia-component-type="PF5/MenuToggle"
                data-ouia-safe="true"
                data-ouia-component-id="OUIA-Generated-MenuToggle-5"
        >[…]</button>
    </div>
</div>
```


6d6f9667c6/js/libs/ui-shared/src/controls/select-control/SingleSelectControl.tsx (L77)

Signed-off-by: Ayke Halder <rr-it@users.noreply.github.com>
This commit is contained in:
Ayke Halder 2025-05-01 21:49:36 +02:00 committed by GitHub
parent 9142978c70
commit f58a998426
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 35 additions and 13 deletions

View File

@ -40,7 +40,7 @@ export async function deleteClusterNode(page: Page, host: string) {
}
function getAccessTokenSignatureAlgorithm(page: Page) {
return page.locator("#access🍺token🍺signed🍺response🍺alg");
return page.locator("#attributes\\.access🍺token🍺signed🍺response🍺alg");
}
export async function selectAccessTokenSignatureAlgorithm(
@ -146,11 +146,11 @@ export async function revertAdvanced(page: Page) {
}
function getBrowserFlowInput(page: Page) {
return page.locator("#browser");
return page.locator("#authenticationFlowBindingOverrides\\.browser");
}
function getDirectFlowInput(page: Page) {
return page.locator("#direct_grant");
return page.locator("#authenticationFlowBindingOverrides\\.direct_grant");
}
export async function selectBrowserFlowInput(page: Page, value: string) {

View File

@ -56,7 +56,13 @@ export async function clickGenerate(page: Page) {
export async function assertNameIdFormatDropdown(page: Page) {
const items = ["username", "email", "transient", "persistent"];
for (const item of items) {
await selectItem(page, page.locator("#saml_name_id_format"), item);
await expect(page.locator("#saml_name_id_format")).toHaveText(item);
await selectItem(
page,
page.locator("#attributes\\.saml_name_id_format"),
item,
);
await expect(page.locator("#attributes\\.saml_name_id_format")).toHaveText(
item,
);
}
}

View File

@ -96,7 +96,7 @@ export async function assertPkceMethodExists(
page: Page,
exist: boolean = true,
) {
assertElementExists(page, "#pkceMethod", exist);
assertElementExists(page, "#config\\.pkceMethod", exist);
}
export async function goToMappersTab(page: Page) {

View File

@ -28,8 +28,16 @@ export async function editSAMLSettings(page: Page, samlProviderName: string) {
await assertInvalidUrlNotification(page, "singleLogoutService");
await setUrl(page, "singleLogoutService", "https://valid.com");
await selectItem(page, page.locator("#nameIDPolicyFormat"), "Kerberos");
await selectItem(page, page.locator("#principalType"), "Attribute [Name]");
await selectItem(
page,
page.locator("#config\\.nameIDPolicyFormat"),
"Kerberos",
);
await selectItem(
page,
page.locator("#config\\.principalType"),
"Attribute [Name]",
);
// Toggle SAML switches
const switches = [

View File

@ -19,5 +19,9 @@ export async function fillForm(
},
) {
await selectItem(page, page.getByTestId("alias"), data.name);
await selectItem(page, page.locator("#kc🍺org🍺domain"), data.domain);
await selectItem(
page,
page.locator("#config\\.kc🍺org🍺domain"),
data.domain,
);
}

View File

@ -5,6 +5,7 @@ import { FormErrorText } from "./FormErrorText";
import { HelpItem } from "./HelpItem";
export type FieldProps<T extends FieldValues = FieldValues> = {
id?: string | undefined;
label?: string;
name: string;
labelIcon?: string | ReactNode;
@ -15,6 +16,7 @@ export type FieldProps<T extends FieldValues = FieldValues> = {
type FormLabelProps = FieldProps & Omit<FormGroupProps, "label" | "labelIcon">;
export const FormLabel = ({
id,
name,
label,
labelIcon,
@ -24,10 +26,10 @@ export const FormLabel = ({
}: PropsWithChildren<FormLabelProps>) => (
<FormGroup
label={label || name}
fieldId={name}
fieldId={id || name}
labelIcon={
labelIcon ? (
<HelpItem helpText={labelIcon} fieldLabelId={name} />
<HelpItem helpText={labelIcon} fieldLabelId={id || name} />
) : undefined
}
{...rest}

View File

@ -45,6 +45,7 @@ export const SingleSelectControl = <
return (
<FormLabel
id={id}
name={name}
label={label}
isRequired={required}
@ -74,7 +75,7 @@ export const SingleSelectControl = <
}
toggle={(ref) => (
<MenuToggle
id={id || name.slice(name.lastIndexOf(".") + 1)}
id={id || name}
ref={ref}
onClick={() => setOpen(!open)}
isExpanded={open}

View File

@ -171,6 +171,7 @@ export const TypeaheadSelectControl = <
return (
<FormLabel
id={id}
name={name}
label={label}
isRequired={required}
@ -200,7 +201,7 @@ export const TypeaheadSelectControl = <
toggle={(ref) => (
<MenuToggle
ref={ref}
id={id || name.slice(name.lastIndexOf(".") + 1)}
id={id || name}
variant="typeahead"
onClick={() => {
setOpen(!open);