Added quantizer type playwright test

This commit is contained in:
Sung-Hyun Kang
2026-05-27 16:06:28 -05:00
parent 481e5cde3e
commit 811f3fb719
6 changed files with 303 additions and 2 deletions
@@ -13,6 +13,7 @@ export interface CollapsibleSectionProps {
onDelete?: () => void;
disabled?: boolean;
disableDelete?: boolean;
testId?: string;
}
export interface CollapsibleSectionState {
@@ -57,6 +58,7 @@ export class CollapsibleSectionComponent extends React.Component<CollapsibleSect
tabIndex={0}
role="button"
aria-expanded={this.state.isExpanded}
data-test={this.props.testId}
>
<Icon iconName={this.state.isExpanded ? "ChevronDown" : "ChevronRight"} />
<Label styles={{ root: { color: "var(--colorNeutralForeground1)" } }}>{this.props.title}</Label>
@@ -426,6 +426,7 @@ export const VectorEmbeddingPoliciesComponent: FunctionComponent<IVectorEmbeddin
</Label>
<Dropdown
disabled={isExistingPolicy(vectorEmbeddingPolicy)}
id={`vector-policy-indexType-${index + 1}`}
required={true}
styles={dropdownStyles}
options={getIndexTypeOptions()}
@@ -838,6 +838,7 @@ export class AddCollectionPanel extends React.Component<AddCollectionPanelProps,
scrollToSection("collapsibleVectorPolicySectionContent");
}}
tooltipContent={ContainerVectorPolicyTooltipContent()}
testId="container-vector-policy-section"
>
<Stack id="collapsibleVectorPolicySectionContent" styles={{ root: { position: "relative" } }}>
<Stack styles={{ root: { paddingLeft: 40 } }}>
+4
View File
@@ -0,0 +1,4 @@
// Temporary init script for Playwright MCP to override browser locale
// This runs before any page scripts, so i18next will detect 'ja' from navigator
Object.defineProperty(navigator, "language", { get: () => "ja" });
Object.defineProperty(navigator, "languages", { get: () => ["ja", "ja-JP"] });
+173 -1
View File
@@ -1,6 +1,13 @@
import { expect, test } from "@playwright/test";
import { DataExplorer, TEST_AUTOSCALE_THROUGHPUT_RU, TestAccount, generateUniqueName } from "../fx";
import {
DataExplorer,
ONE_MINUTE_MS,
TEST_AUTOSCALE_THROUGHPUT_RU,
TestAccount,
generateUniqueName,
getDropdownItemByNameOrPosition,
} from "../fx";
test("SQL database and container CRUD", async ({ page }) => {
const databaseId = generateUniqueName("db");
@@ -50,3 +57,168 @@ test("SQL database and container CRUD", async ({ page }) => {
await expect(databaseNode.element).not.toBeAttached();
});
test.describe("Vector embedding quantizer type in New Container panel", () => {
/**
* Opens the New Container panel and expands the Container Vector Policy section.
* Returns the panel locator and the scoped vector policy content locator.
*/
const openPanelWithVectorPolicy = async (explorer: DataExplorer) => {
const newContainerButton = await explorer.globalCommandButton("New Container");
await newContainerButton.click();
const panel = explorer.panel("New Container");
await panel.waitFor();
// Expand section via its stable data-test id (avoids matching localized title text)
await explorer.frame.getByTestId("container-vector-policy-section").click();
const vectorSection = explorer.frame.locator("#collapsibleVectorPolicySectionContent");
await vectorSection.locator("#add-vector-policy").waitFor();
return { panel, vectorSection };
};
/** Closes the New Container panel without submitting via the Fluent UI Panel close button. */
const closePanel = async (explorer: DataExplorer) => {
await explorer.frame.locator("button.ms-Panel-closeButton").click();
await explorer.panel("New Container").waitFor({ state: "detached" });
};
test("Quantizer type dropdown is disabled by default when index type is none", async ({ page }) => {
const explorer = await DataExplorer.open(page, TestAccount.SQL);
const { vectorSection } = await openPanelWithVectorPolicy(explorer);
await vectorSection.locator("#add-vector-policy").click();
// Index type defaults to "none" — quantizer type must be disabled
const quantizerDropdownBtn = vectorSection.locator("#vector-policy-quantizerType-1");
await expect(quantizerDropdownBtn).toBeDisabled();
await closePanel(explorer);
});
test("Quantizer type dropdown is disabled for flat index type", async ({ page }) => {
const explorer = await DataExplorer.open(page, TestAccount.SQL);
const { vectorSection } = await openPanelWithVectorPolicy(explorer);
await vectorSection.locator("#add-vector-policy").click();
// Select "flat" index type (does not support quantization).
// Use exact match because "flat" is also a substring of "quantizedFlat".
await vectorSection.locator("#vector-policy-indexType-1").click();
await explorer.frame.getByRole("option", { name: "flat", exact: true }).click();
const quantizerDropdownBtn = vectorSection.locator("#vector-policy-quantizerType-1");
await expect(quantizerDropdownBtn).toBeDisabled();
await closePanel(explorer);
});
test("Quantizer type dropdown becomes enabled with diskANN index type and defaults to Product", async ({ page }) => {
const explorer = await DataExplorer.open(page, TestAccount.SQL);
const { vectorSection } = await openPanelWithVectorPolicy(explorer);
await vectorSection.locator("#add-vector-policy").click();
await vectorSection.locator("#vector-policy-indexType-1").click();
await (await getDropdownItemByNameOrPosition(explorer.frame, { name: "diskANN" })).click();
const quantizerDropdownBtn = vectorSection.locator("#vector-policy-quantizerType-1");
await expect(quantizerDropdownBtn).toBeEnabled();
await expect(quantizerDropdownBtn).toContainText("Product");
await closePanel(explorer);
});
test("Quantizer type dropdown becomes enabled with quantizedFlat index type and defaults to Product", async ({
page,
}) => {
const explorer = await DataExplorer.open(page, TestAccount.SQL);
const { vectorSection } = await openPanelWithVectorPolicy(explorer);
await vectorSection.locator("#add-vector-policy").click();
// Select "quantizedFlat" index type — supports quantization
await vectorSection.locator("#vector-policy-indexType-1").click();
await (await getDropdownItemByNameOrPosition(explorer.frame, { name: "quantizedFlat" })).click();
const quantizerDropdownBtn = vectorSection.locator("#vector-policy-quantizerType-1");
await expect(quantizerDropdownBtn).toBeEnabled();
await expect(quantizerDropdownBtn).toContainText("Product");
await closePanel(explorer);
});
test("Quantizer type can be changed to Spherical (Preview)", async ({ page }) => {
const explorer = await DataExplorer.open(page, TestAccount.SQL);
const { vectorSection } = await openPanelWithVectorPolicy(explorer);
await vectorSection.locator("#add-vector-policy").click();
await vectorSection.locator("#vector-policy-indexType-1").click();
await (await getDropdownItemByNameOrPosition(explorer.frame, { name: "diskANN" })).click();
const quantizerDropdownBtn = vectorSection.locator("#vector-policy-quantizerType-1");
await quantizerDropdownBtn.click();
await (await getDropdownItemByNameOrPosition(explorer.frame, { position: 1 })).click();
await expect(quantizerDropdownBtn).not.toContainText("Product");
await closePanel(explorer);
});
test("Creating a container with diskANN index type and Spherical quantizer type succeeds", async ({ page }) => {
const databaseId = generateUniqueName("db");
const containerId = "testvecquantizer";
const explorer = await DataExplorer.open(page, TestAccount.SQL);
await (await explorer.globalCommandButton("New Container")).click();
await explorer.whilePanelOpen(
"New Container",
async (panel, okButton) => {
await panel.getByPlaceholder("Type a new database id").fill(databaseId);
await panel.getByRole("textbox", { name: "Container id, Example Container1" }).fill(containerId);
await panel.getByRole("textbox", { name: "Partition key" }).fill("/pk");
await panel.getByTestId("autoscaleRUInput").fill(TEST_AUTOSCALE_THROUGHPUT_RU.toString());
await explorer.frame.getByTestId("container-vector-policy-section").click();
const vectorSection = explorer.frame.locator("#collapsibleVectorPolicySectionContent");
await vectorSection.locator("#add-vector-policy").waitFor();
await vectorSection.locator("#add-vector-policy").click();
await vectorSection.locator("#vector-policy-path-1").fill("/embedding");
await vectorSection.locator("#vector-policy-dimension-1").fill("1536");
await vectorSection.locator("#vector-policy-indexType-1").click();
await (await getDropdownItemByNameOrPosition(explorer.frame, { name: "diskANN" })).click();
const quantizerDropdownBtn = vectorSection.locator("#vector-policy-quantizerType-1");
await expect(quantizerDropdownBtn).toBeEnabled();
await quantizerDropdownBtn.click();
await (await getDropdownItemByNameOrPosition(explorer.frame, { position: 1 })).click();
await okButton.click();
},
{ closeTimeout: 5 * 60 * 1000 },
);
const containerNode = await explorer.waitForContainerNode(databaseId, containerId);
await expect(containerNode.element).toBeVisible();
// Cleanup
const databaseNode = await explorer.waitForNode(databaseId);
await databaseNode.openContextMenu();
await databaseNode.contextMenuItem("Delete Database").click();
await explorer.whilePanelOpen(
"Delete Database",
async (panel, okButton) => {
await panel.getByRole("textbox", { name: "Confirm by typing the database id" }).fill(databaseId);
await okButton.click();
},
{ closeTimeout: 5 * 60 * 1000 },
);
await expect(databaseNode.element).not.toBeAttached({ timeout: ONE_MINUTE_MS });
});
});
@@ -1,5 +1,11 @@
import { expect, test } from "@playwright/test";
import { CommandBarButton, DataExplorer, ONE_MINUTE_MS, TestAccount } from "../../../fx";
import {
CommandBarButton,
DataExplorer,
getDropdownItemByNameOrPosition,
ONE_MINUTE_MS,
TestAccount,
} from "../../../fx";
import { createTestSQLContainer, TestContainerContext } from "../../../testData";
test.describe("Vector Policy under Scale & Settings", () => {
@@ -190,4 +196,119 @@ test.describe("Vector Policy under Scale & Settings", () => {
const saveButton = explorer.commandBarButton(CommandBarButton.Save);
await expect(saveButton).toBeDisabled();
});
test("Quantizer type dropdown is disabled when index type is none", async () => {
const existingCount = await getPolicyCount();
const addButton = explorer.frame.locator("#add-vector-policy");
await addButton.click();
const newIndex = existingCount + 1;
const quantizerDropdownBtn = explorer.frame.locator(`#vector-policy-quantizerType-${newIndex}`);
await expect(quantizerDropdownBtn).toBeDisabled();
});
test("Quantizer type dropdown is disabled for flat index type", async () => {
const existingCount = await getPolicyCount();
const addButton = explorer.frame.locator("#add-vector-policy");
await addButton.click();
const newIndex = existingCount + 1;
await explorer.frame.locator(`#vector-policy-indexType-${newIndex}`).click();
// Use exact match because "flat" is also a substring of "quantizedFlat".
await explorer.frame.getByRole("option", { name: "flat", exact: true }).click();
const quantizerDropdownBtn = explorer.frame.locator(`#vector-policy-quantizerType-${newIndex}`);
await expect(quantizerDropdownBtn).toBeDisabled();
});
test("Quantizer type dropdown becomes enabled and defaults to Product for diskANN index type", async () => {
const existingCount = await getPolicyCount();
const addButton = explorer.frame.locator("#add-vector-policy");
await addButton.click();
const newIndex = existingCount + 1;
await explorer.frame.locator(`#vector-policy-indexType-${newIndex}`).click();
await (await getDropdownItemByNameOrPosition(explorer.frame, { name: "diskANN" })).click();
const quantizerDropdownBtn = explorer.frame.locator(`#vector-policy-quantizerType-${newIndex}`);
await expect(quantizerDropdownBtn).toBeEnabled();
await expect(quantizerDropdownBtn).toContainText("Product");
});
test("Quantizer type dropdown becomes enabled and defaults to Product for quantizedFlat index type", async () => {
const existingCount = await getPolicyCount();
const addButton = explorer.frame.locator("#add-vector-policy");
await addButton.click();
const newIndex = existingCount + 1;
await explorer.frame.locator(`#vector-policy-indexType-${newIndex}`).click();
await (await getDropdownItemByNameOrPosition(explorer.frame, { name: "quantizedFlat" })).click();
const quantizerDropdownBtn = explorer.frame.locator(`#vector-policy-quantizerType-${newIndex}`);
await expect(quantizerDropdownBtn).toBeEnabled();
await expect(quantizerDropdownBtn).toContainText("Product");
});
test("Quantizer type can be changed to Spherical (Preview)", async () => {
const existingCount = await getPolicyCount();
const addButton = explorer.frame.locator("#add-vector-policy");
await addButton.click();
const newIndex = existingCount + 1;
await explorer.frame.locator(`#vector-policy-path-${newIndex}`).fill("/embedding");
await explorer.frame.locator(`#vector-policy-dimension-${newIndex}`).fill("1536");
await explorer.frame.locator(`#vector-policy-indexType-${newIndex}`).click();
await (await getDropdownItemByNameOrPosition(explorer.frame, { name: "diskANN" })).click();
const quantizerDropdownBtn = explorer.frame.locator(`#vector-policy-quantizerType-${newIndex}`);
await quantizerDropdownBtn.click();
await (await getDropdownItemByNameOrPosition(explorer.frame, { position: 1 })).click();
await expect(quantizerDropdownBtn).not.toContainText("Product");
});
test("Saving a vector policy with diskANN and Spherical quantizer type persists", async () => {
const existingCount = await getPolicyCount();
const addButton = explorer.frame.locator("#add-vector-policy");
await addButton.click();
const newIndex = existingCount + 1;
await explorer.frame.locator(`#vector-policy-path-${newIndex}`).fill("/vecQuantizer");
await explorer.frame.locator(`#vector-policy-dimension-${newIndex}`).fill("1536");
await explorer.frame.locator(`#vector-policy-indexType-${newIndex}`).click();
await (await getDropdownItemByNameOrPosition(explorer.frame, { name: "diskANN" })).click();
const quantizerDropdownBtn = explorer.frame.locator(`#vector-policy-quantizerType-${newIndex}`);
await quantizerDropdownBtn.click();
await (await getDropdownItemByNameOrPosition(explorer.frame, { position: 1 })).click();
// Save
const saveButton = explorer.commandBarButton(CommandBarButton.Save);
await expect(saveButton).toBeEnabled();
await saveButton.click();
await expect(explorer.getConsoleHeaderStatus()).toContainText(`${context.container.id}`, {
timeout: 2 * ONE_MINUTE_MS,
});
await explorer.openScaleAndSettings(context);
await explorer.frame.getByTestId("settings-tab-header/ContainerVectorPolicyTab").click();
await explorer.frame.getByRole("tab", { name: "Vector Policy" }).click();
const savedQuantizerBtn = explorer.frame.locator(`#vector-policy-quantizerType-${newIndex}`);
await expect(savedQuantizerBtn).toContainText("Spherical");
});
});