Fix playwright tests (#2285)

* Temporarily re-enable key based auth for Mongo and Cassandra tests.

* Increase number of shards for playwright tests.

* Another small bump to test shard count.

* click global new... button then collection in playwright tests

* get new table button

* create and delete container for every individual scale test

* for scale and settings, dont create sample data in container

* run scale tests serially

* refactor scale setup and tear down to be within each test

* record network traces

* record network calls on all retries

* when disposing of database during playwright test, refresh tree to remove deleted database

* refresh tree before  opening scale and settings

* When opening scale and settings, refresh databases

* reload all databases before loading offers

* increase time for change partition key request

* increase time for change partition key request

* refresh databases in test instead of product code

* when refreshing containers, open console window to check for status completion

* close notification console window after seeing desired log

* create and delete a container for each individual test

* dont delete database after every test. leave it to the CI

* Don't refresh databases when opening Scale+Settings and only delete database if running locally

* only open scale and settings at the beginning of each test suite

* get it back to working

* change settings.spect.ts from serial to parallel

* don't delete database after each test

* update container creation throughpout to be 5000

* run tests with no throughput limit on the account

* adjust scale test to reflect no throughput limit on account

* remove test container throughput

* don't refresh collections when clicking settings in product code

* refactor and run cleanup during pr check

* copy cleanup accounts

* run cleanup after playwright tests

* run cleanup every three hours

* revert ci.yml

* update cpk test

* remove cpk

* remove cleanup accounts and add cpk

* add cpk

* remove cpk changes

* revert ci.yml

* run cleanup every two hours

---------

Co-authored-by: Jade Welton <jawelton@microsoft.com>
Co-authored-by: Asier Isayas <aisayas@microsoft.com>
This commit is contained in:
asier-isayas
2026-01-07 00:36:54 -05:00
committed by GitHub
parent 53288dec6f
commit 4ac8cd8fe4
16 changed files with 305 additions and 245 deletions

View File

@@ -1,4 +1,4 @@
import { expect, Locator, test } from "@playwright/test";
import { Browser, expect, Locator, Page, test } from "@playwright/test";
import {
CommandBarButton,
DataExplorer,
@@ -9,121 +9,116 @@ import {
} from "../../fx";
import { createTestSQLContainer, TestContainerContext } from "../../testData";
test.describe("Autoscale and Manual throughput", () => {
let context: TestContainerContext = null!;
let explorer: DataExplorer = null!;
interface SetupResult {
context: TestContainerContext;
page: Page;
explorer: DataExplorer;
}
test.beforeAll("Create Test Database", async () => {
context = await createTestSQLContainer({ includeTestData: true });
test.describe("Autoscale throughput", () => {
let setup: SetupResult;
test.beforeAll(async ({ browser }) => {
setup = await openScaleTab(browser);
// Switch manual -> autoscale once for this suite
const autoscaleRadioButton = setup.explorer.frame.getByText("Autoscale", { exact: true });
await autoscaleRadioButton.click();
await expect(setup.explorer.commandBarButton(CommandBarButton.Save)).toBeEnabled();
await setup.explorer.commandBarButton(CommandBarButton.Save).click();
await expect(setup.explorer.getConsoleHeaderStatus()).toContainText(
`Successfully updated offer for collection ${setup.context.container.id}`,
{ timeout: 2 * ONE_MINUTE_MS },
);
});
test.beforeEach("Open container settings", async ({ page }) => {
explorer = await DataExplorer.open(page, TestAccount.SQL);
// Click Scale & Settings and open Scale tab
await explorer.openScaleAndSettings(context);
const scaleTab = explorer.frame.getByTestId("settings-tab-header/ScaleTab");
await scaleTab.click();
});
test.afterAll("Delete Test Database", async () => {
await context?.dispose();
test.afterAll(async () => {
await cleanup(setup);
});
test("Update autoscale max throughput", async () => {
// By default the created container has manual throughput (Containers created via JS SDK v4.7.0 cannot be created with autoscale throughput)
await switchManualToAutoscaleThroughput();
await getThroughputInput(setup.explorer, "autopilot").fill(TEST_AUTOSCALE_MAX_THROUGHPUT_RU_2K.toString());
await setup.explorer.commandBarButton(CommandBarButton.Save).click();
// Update autoscale max throughput
await getThroughputInput("autopilot").fill(TEST_AUTOSCALE_MAX_THROUGHPUT_RU_2K.toString());
// Save
await explorer.commandBarButton(CommandBarButton.Save).click();
// Read console message
await expect(explorer.getConsoleMessage()).toContainText(
`Successfully updated offer for collection ${context.container.id}`,
{
timeout: 2 * ONE_MINUTE_MS,
},
await expect(setup.explorer.getConsoleHeaderStatus()).toContainText(
`Successfully updated offer for collection ${setup.context.container.id}`,
{ timeout: 2 * ONE_MINUTE_MS },
);
});
test("Update autoscale max throughput passed allowed limit", async () => {
// By default the created container has manual throughput (Containers created via JS SDK v4.7.0 cannot be created with autoscale throughput)
await switchManualToAutoscaleThroughput();
// Get soft allowed max throughput and remove commas
const softAllowedMaxThroughputString = await explorer.frame
const softAllowedMaxThroughputString = await setup.explorer.frame
.getByTestId("soft-allowed-maximum-throughput")
.innerText();
const softAllowedMaxThroughput = Number(softAllowedMaxThroughputString.replace(/,/g, ""));
// Try to set autoscale max throughput above allowed limit
await getThroughputInput("autopilot").fill((softAllowedMaxThroughput * 10).toString());
await expect(explorer.commandBarButton(CommandBarButton.Save)).toBeDisabled();
await expect(getThroughputInputErrorMessage("autopilot")).toContainText(
"This update isn't possible because it would increase the total throughput",
);
await getThroughputInput(setup.explorer, "autopilot").fill((softAllowedMaxThroughput * 10).toString());
await expect(setup.explorer.commandBarButton(CommandBarButton.Save)).toBeDisabled();
await expect(delayedApplyWarning(setup.explorer)).toBeVisible();
});
test("Update autoscale max throughput with invalid increment", async () => {
// By default the created container has manual throughput (Containers created via JS SDK v4.7.0 cannot be created with autoscale throughput)
await switchManualToAutoscaleThroughput();
// Try to set autoscale max throughput with invalid increment
await getThroughputInput("autopilot").fill("1100");
await expect(explorer.commandBarButton(CommandBarButton.Save)).toBeDisabled();
await expect(getThroughputInputErrorMessage("autopilot")).toContainText(
await getThroughputInput(setup.explorer, "autopilot").fill("1100");
await expect(setup.explorer.commandBarButton(CommandBarButton.Save)).toBeDisabled();
await expect(getThroughputInputErrorMessage(setup.explorer, "autopilot")).toContainText(
"Throughput value must be in increments of 1000",
);
});
});
test.describe("Manual throughput", () => {
let setup: SetupResult;
test.beforeAll(async ({ browser }) => {
setup = await openScaleTab(browser);
});
test.afterAll(async () => {
await cleanup(setup);
});
test("Update manual throughput", async () => {
await getThroughputInput("manual").fill(TEST_MANUAL_THROUGHPUT_RU_2K.toString());
await explorer.commandBarButton(CommandBarButton.Save).click();
await expect(explorer.getConsoleMessage()).toContainText(
`Successfully updated offer for collection ${context.container.id}`,
{
timeout: 2 * ONE_MINUTE_MS,
},
await getThroughputInput(setup.explorer, "manual").fill(TEST_MANUAL_THROUGHPUT_RU_2K.toString());
await setup.explorer.commandBarButton(CommandBarButton.Save).click();
await expect(setup.explorer.getConsoleHeaderStatus()).toContainText(
`Successfully updated offer for collection ${setup.context.container.id}`,
{ timeout: 2 * ONE_MINUTE_MS },
);
});
test("Update manual throughput passed allowed limit", async () => {
// Get soft allowed max throughput and remove commas
const softAllowedMaxThroughputString = await explorer.frame
const softAllowedMaxThroughputString = await setup.explorer.frame
.getByTestId("soft-allowed-maximum-throughput")
.innerText();
const softAllowedMaxThroughput = Number(softAllowedMaxThroughputString.replace(/,/g, ""));
// Try to set manual throughput above allowed limit
await getThroughputInput("manual").fill((softAllowedMaxThroughput * 10).toString());
await expect(explorer.commandBarButton(CommandBarButton.Save)).toBeDisabled();
await expect(getThroughputInputErrorMessage("manual")).toContainText(
"This update isn't possible because it would increase the total throughput",
);
await getThroughputInput(setup.explorer, "manual").fill((softAllowedMaxThroughput * 10).toString());
await expect(delayedApplyWarning(setup.explorer)).toBeVisible();
});
// Helper methods
const getThroughputInput = (type: "manual" | "autopilot"): Locator => {
return explorer.frame.getByTestId(`${type}-throughput-input`);
};
const getThroughputInputErrorMessage = (type: "manual" | "autopilot"): Locator => {
return explorer.frame.getByTestId(`${type}-throughput-input-error`);
};
const switchManualToAutoscaleThroughput = async (): Promise<void> => {
const autoscaleRadioButton = explorer.frame.getByText("Autoscale", { exact: true });
await autoscaleRadioButton.click();
await expect(explorer.commandBarButton(CommandBarButton.Save)).toBeEnabled();
await explorer.commandBarButton(CommandBarButton.Save).click();
await expect(explorer.getConsoleMessage()).toContainText(
`Successfully updated offer for collection ${context.container.id}`,
{
timeout: ONE_MINUTE_MS,
},
);
};
});
const delayedApplyWarning = (explorer: DataExplorer): Locator =>
explorer.frame.locator("#updateThroughputDelayedApplyWarningMessage");
const getThroughputInput = (explorer: DataExplorer, type: "manual" | "autopilot"): Locator =>
explorer.frame.getByTestId(`${type}-throughput-input`);
const getThroughputInputErrorMessage = (explorer: DataExplorer, type: "manual" | "autopilot"): Locator =>
explorer.frame.getByTestId(`${type}-throughput-input-error`);
async function openScaleTab(browser: Browser): Promise<SetupResult> {
const context = await createTestSQLContainer();
const page = await browser.newPage();
const explorer = await DataExplorer.open(page, TestAccount.SQL);
await explorer.openScaleAndSettings(context);
await explorer.frame.getByTestId("settings-tab-header/ScaleTab").click();
return { context, page, explorer };
}
async function cleanup({ context }: Partial<SetupResult>) {
if (!process.env.CI) {
await context?.dispose();
}
}