Fix accessible name for New Database panel 'Database id' field (4768133)

The Database id input in the New Database panel is a Fluent UI v8 TextField
that was given a kebab-case `aria-label`. Fluent v8 TextField only honors the
camelCase `ariaLabel` prop and overwrites the input's `aria-label` with
`this.props.ariaLabel` (undefined), so the input had no accessible name and
screen readers fell back to the `title` attribute ("May not end with space...").

Associate the visible "Database id" label with the input via `aria-labelledby`
(the input now resolves to the accessible name "Database id"), matching the
MAS 4.1.2 expected behavior. Replace the enzyme shallow snapshot test with
React Testing Library tests that assert the resolved accessible name, and add
an E2E assertion in the SQL shared-throughput spec.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 966869a1-04d0-4651-9ede-f8cf861ae658
This commit is contained in:
Jade Welton
2026-07-20 14:36:05 -07:00
parent acd2e3d839
commit cf8af4aaa0
4 changed files with 46 additions and 78 deletions
@@ -1,17 +1,34 @@
import { shallow } from "enzyme";
jest.mock("../../../Common/dataAccess/createDatabase");
jest.mock("../../../Shared/Telemetry/TelemetryProcessor");
import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";
import React from "react";
import { updateUserContext } from "../../../UserContext";
import Explorer from "../../Explorer";
import { AddDatabasePanel } from "./AddDatabasePanel";
describe("AddDatabasePanel", () => {
const props = {
explorer: new Explorer(),
closePanel: (): void => undefined,
openNotificationConsole: (): void => undefined,
};
describe("AddDatabasePane Pane", () => {
it("should render Default properly", () => {
const wrapper = shallow(<AddDatabasePanel {...props} />);
expect(wrapper).toMatchSnapshot();
afterEach(() => {
updateUserContext({ apiType: "SQL" });
});
it("programmatically associates the visible 'Database id' label with the input", () => {
updateUserContext({ apiType: "SQL" });
render(<AddDatabasePanel {...props} />);
// getByRole resolves the accessible name via aria-labelledby, which must
// point at the visible "Database id" label (regression guard for bug 4768133).
expect(screen.getByRole("textbox", { name: "Database id" })).toBeInTheDocument();
});
it("uses 'Keyspace id' as the accessible name for Cassandra accounts", () => {
updateUserContext({ apiType: "Cassandra" });
render(<AddDatabasePanel {...props} />);
expect(screen.getByRole("textbox", { name: "Keyspace id" })).toBeInTheDocument();
});
});
@@ -148,7 +148,7 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
<Stack>
<Stack horizontal>
<span className="mandatoryStar">*&nbsp;</span>
<Text className="panelTextBold" variant="small">
<Text id="database-id-label" className="panelTextBold" variant="small">
{databaseIdLabel}
</Text>
<InfoTooltip>{databaseIdTooltipText}</InfoTooltip>
@@ -162,7 +162,7 @@ export const AddDatabasePanel: FunctionComponent<AddDatabasePaneProps> = ({
pattern={ValidCosmosDbIdInputPattern.source}
title={ValidCosmosDbIdDescription}
size={40}
aria-label={databaseIdLabel}
aria-labelledby="database-id-label"
placeholder={databaseIdPlaceHolder}
value={databaseId}
onChange={handleonChangeDBId}
@@ -1,66 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`AddDatabasePane Pane should render Default properly 1`] = `
<RightPaneForm
formError=""
isExecuting={false}
onSubmit={[Function]}
submitButtonText="OK"
>
<div
className="panelMainContent"
>
<Stack>
<Stack
horizontal={true}
>
<span
className="mandatoryStar"
>
* 
</span>
<Text
className="panelTextBold"
variant="small"
>
Database id
</Text>
<InfoTooltip>
A database is a logical container of one or more collections
</InfoTooltip>
</Stack>
<StyledTextFieldBase
aria-label="Database id"
aria-required="true"
autoComplete="off"
autoFocus={true}
data-1p-ignore={true}
data-lpignore={true}
id="database-id"
onChange={[Function]}
pattern="[^\\/?#\\\\]*[^\\/?# \\\\]"
placeholder="Type a new database id"
size={40}
styles={
{
"field": {
"fontSize": 12,
"selectors": {
"::placeholder": {
"fontSize": 12,
},
},
},
"root": {
"width": 300,
},
}
}
title="May not end with space nor contain characters '\\' '/' '#' '?'"
type="text"
value=""
/>
</Stack>
</div>
</RightPaneForm>
`;
@@ -36,6 +36,23 @@ test.describe("Shared Throughput Option Removed from Creation Dialogs", () => {
await panel.waitFor({ state: "detached" });
});
test("New Database panel 'Database id' field has an accessible name", async () => {
// Regression guard for bug 4768133: the "Database id" label must be
// programmatically associated with the edit field, so the input's accessible
// name is "Database id" rather than falling back to its title attribute.
const newDatabaseButton = await explorer.globalCommandButton("New Database");
await newDatabaseButton.click();
const panel = explorer.panel("New Database");
await panel.waitFor();
await expect(panel.getByRole("textbox", { name: "Database id" })).toBeVisible();
const closeButton = explorer.frame.getByLabel("Close New Database");
await closeButton.click();
await panel.waitFor({ state: "detached" });
});
test("New Container panel should not show shared throughput checkbox when creating new database", async () => {
// Open the "New Container" panel
const newContainerButton = await explorer.globalCommandButton("New Container");