From 3f01ce5ff01018bfeb31c49585e4f43830221c1a Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Wed, 21 Jan 2026 08:06:18 -0800 Subject: [PATCH 01/19] dont refresh tree when opening scale & settings --- test/fx.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/fx.ts b/test/fx.ts index 1de8be90d..6a65b652c 100644 --- a/test/fx.ts +++ b/test/fx.ts @@ -515,14 +515,14 @@ export class DataExplorer { const containerNode = await this.waitForContainerNode(context.database.id, context.container.id); await containerNode.expand(); - // refresh tree to remove deleted database - const consoleMessages = await this.getNotificationConsoleMessages(); - const refreshButton = this.frame.getByTestId("Sidebar/RefreshButton"); - await refreshButton.click(); - await expect(consoleMessages).toContainText("Successfully refreshed databases", { - timeout: ONE_MINUTE_MS, - }); - await this.collapseNotificationConsole(); + // // refresh tree to remove deleted database + // const consoleMessages = await this.getNotificationConsoleMessages(); + // const refreshButton = this.frame.getByTestId("Sidebar/RefreshButton"); + // await refreshButton.click(); + // await expect(consoleMessages).toContainText("Successfully refreshed databases", { + // timeout: ONE_MINUTE_MS, + // }); + // await this.collapseNotificationConsole(); const scaleAndSettingsButton = this.frame.getByTestId( `TreeNode:${context.database.id}/${context.container.id}/Scale & Settings`, From d32ccfef1315b84dbd6209f24c3f1ed4ddaea337 Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Wed, 21 Jan 2026 09:13:46 -0800 Subject: [PATCH 02/19] disable offline/online migration tests --- .../containercopy/offlineMigration.spec.ts | 418 +++++++++--------- .../sql/containercopy/onlineMigration.spec.ts | 298 ++++++------- 2 files changed, 358 insertions(+), 358 deletions(-) diff --git a/test/sql/containercopy/offlineMigration.spec.ts b/test/sql/containercopy/offlineMigration.spec.ts index de9597d49..e9de9e00b 100644 --- a/test/sql/containercopy/offlineMigration.spec.ts +++ b/test/sql/containercopy/offlineMigration.spec.ts @@ -1,258 +1,258 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { expect, Frame, Locator, Page, test } from "@playwright/test"; -import { truncateName } from "../../../src/Explorer/ContainerCopy/CopyJobUtils"; -import { - ContainerCopy, - getAccountName, - getDropdownItemByNameOrPosition, - interceptAndInspectApiRequest, - TestAccount, - waitForApiResponse, -} from "../../fx"; -import { createMultipleTestContainers } from "../../testData"; +// /* eslint-disable @typescript-eslint/no-explicit-any */ +// import { expect, Frame, Locator, Page, test } from "@playwright/test"; +// import { truncateName } from "../../../src/Explorer/ContainerCopy/CopyJobUtils"; +// import { +// ContainerCopy, +// getAccountName, +// getDropdownItemByNameOrPosition, +// interceptAndInspectApiRequest, +// TestAccount, +// waitForApiResponse, +// } from "../../fx"; +// import { createMultipleTestContainers } from "../../testData"; -test.describe("Container Copy - Offline Migration", () => { - let page: Page; - let wrapper: Locator; - let panel: Locator; - let frame: Frame; - let expectedJobName: string; - let targetAccountName: string; - let expectedSubscriptionName: string; - let expectedCopyJobNameInitial: string; +// test.describe("Container Copy - Offline Migration", () => { +// let page: Page; +// let wrapper: Locator; +// let panel: Locator; +// let frame: Frame; +// let expectedJobName: string; +// let targetAccountName: string; +// let expectedSubscriptionName: string; +// let expectedCopyJobNameInitial: string; - test.beforeEach("Setup for offline migration test", async ({ browser }) => { - await createMultipleTestContainers({ accountType: TestAccount.SQLContainerCopyOnly, containerCount: 2 }); +// test.beforeEach("Setup for offline migration test", async ({ browser }) => { +// await createMultipleTestContainers({ accountType: TestAccount.SQLContainerCopyOnly, containerCount: 2 }); - page = await browser.newPage(); - ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); - expectedJobName = `offline_test_job_${Date.now()}`; - targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); - }); +// page = await browser.newPage(); +// ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); +// expectedJobName = `offline_test_job_${Date.now()}`; +// targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); +// }); - test.afterEach("Cleanup after offline migration test", async () => { - await page.unroute(/.*/, (route) => route.continue()); - await page.close(); - }); +// test.afterEach("Cleanup after offline migration test", async () => { +// await page.unroute(/.*/, (route) => route.continue()); +// await page.close(); +// }); - test("Successfully create and manage offline migration copy job", async () => { - expect(wrapper).not.toBeNull(); - await wrapper.locator(".commandBarContainer").waitFor({ state: "visible" }); +// test("Successfully create and manage offline migration copy job", async () => { +// expect(wrapper).not.toBeNull(); +// await wrapper.locator(".commandBarContainer").waitFor({ state: "visible" }); - // Open Create Copy Job panel - const createCopyJobButton = wrapper.getByTestId("CommandBar/Button:Create Copy Job"); - await expect(createCopyJobButton).toBeVisible(); - await createCopyJobButton.click(); - panel = frame.getByTestId("Panel:Create copy job"); - await expect(panel).toBeVisible(); +// // Open Create Copy Job panel +// const createCopyJobButton = wrapper.getByTestId("CommandBar/Button:Create Copy Job"); +// await expect(createCopyJobButton).toBeVisible(); +// await createCopyJobButton.click(); +// panel = frame.getByTestId("Panel:Create copy job"); +// await expect(panel).toBeVisible(); - // Reduced wait time for better performance - await page.waitForTimeout(2000); +// // Reduced wait time for better performance +// await page.waitForTimeout(2000); - // Setup subscription and account - const subscriptionDropdown = panel.getByTestId("subscription-dropdown"); - const expectedAccountName = targetAccountName; - expectedSubscriptionName = await subscriptionDropdown.locator("span.ms-Dropdown-title").innerText(); +// // Setup subscription and account +// const subscriptionDropdown = panel.getByTestId("subscription-dropdown"); +// const expectedAccountName = targetAccountName; +// expectedSubscriptionName = await subscriptionDropdown.locator("span.ms-Dropdown-title").innerText(); - await subscriptionDropdown.click(); - const subscriptionItem = await getDropdownItemByNameOrPosition( - frame, - { name: expectedSubscriptionName }, - { ariaLabel: "Subscription" }, - ); - await subscriptionItem.click(); +// await subscriptionDropdown.click(); +// const subscriptionItem = await getDropdownItemByNameOrPosition( +// frame, +// { name: expectedSubscriptionName }, +// { ariaLabel: "Subscription" }, +// ); +// await subscriptionItem.click(); - // Select account - const accountDropdown = panel.getByTestId("account-dropdown"); - await expect(accountDropdown).toHaveText(new RegExp(expectedAccountName)); - await accountDropdown.click(); +// // Select account +// const accountDropdown = panel.getByTestId("account-dropdown"); +// await expect(accountDropdown).toHaveText(new RegExp(expectedAccountName)); +// await accountDropdown.click(); - const accountItem = await getDropdownItemByNameOrPosition( - frame, - { name: expectedAccountName }, - { ariaLabel: "Account" }, - ); - await accountItem.click(); +// const accountItem = await getDropdownItemByNameOrPosition( +// frame, +// { name: expectedAccountName }, +// { ariaLabel: "Account" }, +// ); +// await accountItem.click(); - // Test offline migration mode toggle functionality - const migrationTypeContainer = panel.getByTestId("migration-type"); +// // Test offline migration mode toggle functionality +// const migrationTypeContainer = panel.getByTestId("migration-type"); - // First test online mode (should show permissions screen) - const onlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Online mode/i }); - await onlineCopyRadioButton.click({ force: true }); - await expect(migrationTypeContainer.getByTestId("migration-type-description-online")).toBeVisible(); +// // First test online mode (should show permissions screen) +// const onlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Online mode/i }); +// await onlineCopyRadioButton.click({ force: true }); +// await expect(migrationTypeContainer.getByTestId("migration-type-description-online")).toBeVisible(); - await panel.getByRole("button", { name: "Next" }).click(); - await expect(panel.getByTestId("Panel:AssignPermissionsContainer")).toBeVisible(); - await expect(panel.getByText("Online container copy", { exact: true })).toBeVisible(); +// await panel.getByRole("button", { name: "Next" }).click(); +// await expect(panel.getByTestId("Panel:AssignPermissionsContainer")).toBeVisible(); +// await expect(panel.getByText("Online container copy", { exact: true })).toBeVisible(); - // Go back and switch to offline mode - await panel.getByRole("button", { name: "Previous" }).click(); +// // Go back and switch to offline mode +// await panel.getByRole("button", { name: "Previous" }).click(); - const offlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Offline mode/i }); - await offlineCopyRadioButton.click({ force: true }); - await expect(migrationTypeContainer.getByTestId("migration-type-description-offline")).toBeVisible(); +// const offlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Offline mode/i }); +// await offlineCopyRadioButton.click({ force: true }); +// await expect(migrationTypeContainer.getByTestId("migration-type-description-offline")).toBeVisible(); - await panel.getByRole("button", { name: "Next" }).click(); +// await panel.getByRole("button", { name: "Next" }).click(); - // Verify we skip permissions screen in offline mode - await expect(panel.getByTestId("Panel:SelectSourceAndTargetContainers")).toBeVisible(); - await expect(panel.getByTestId("Panel:AssignPermissionsContainer")).not.toBeVisible(); +// // Verify we skip permissions screen in offline mode +// await expect(panel.getByTestId("Panel:SelectSourceAndTargetContainers")).toBeVisible(); +// await expect(panel.getByTestId("Panel:AssignPermissionsContainer")).not.toBeVisible(); - // Test source and target container selection with validation - const sourceContainerDropdown = panel.getByTestId("source-containerDropdown"); - expect(sourceContainerDropdown).toBeVisible(); - await expect(sourceContainerDropdown).toHaveClass(/(^|\s)is-disabled(\s|$)/); +// // Test source and target container selection with validation +// const sourceContainerDropdown = panel.getByTestId("source-containerDropdown"); +// expect(sourceContainerDropdown).toBeVisible(); +// await expect(sourceContainerDropdown).toHaveClass(/(^|\s)is-disabled(\s|$)/); - // Select source database first (containers are disabled until database is selected) - const sourceDatabaseDropdown = panel.getByTestId("source-databaseDropdown"); - await sourceDatabaseDropdown.click(); - const sourceDbDropdownItem = await getDropdownItemByNameOrPosition( - frame, - { position: 0 }, - { ariaLabel: "Database" }, - ); - await sourceDbDropdownItem.click(); +// // Select source database first (containers are disabled until database is selected) +// const sourceDatabaseDropdown = panel.getByTestId("source-databaseDropdown"); +// await sourceDatabaseDropdown.click(); +// const sourceDbDropdownItem = await getDropdownItemByNameOrPosition( +// frame, +// { position: 0 }, +// { ariaLabel: "Database" }, +// ); +// await sourceDbDropdownItem.click(); - // Now container dropdown should be enabled - await expect(sourceContainerDropdown).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); - await sourceContainerDropdown.click(); - const sourceContainerDropdownItem = await getDropdownItemByNameOrPosition( - frame, - { position: 0 }, - { ariaLabel: "Container" }, - ); - await sourceContainerDropdownItem.click(); +// // Now container dropdown should be enabled +// await expect(sourceContainerDropdown).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); +// await sourceContainerDropdown.click(); +// const sourceContainerDropdownItem = await getDropdownItemByNameOrPosition( +// frame, +// { position: 0 }, +// { ariaLabel: "Container" }, +// ); +// await sourceContainerDropdownItem.click(); - // Test target container selection - const targetContainerDropdown = panel.getByTestId("target-containerDropdown"); - expect(targetContainerDropdown).toBeVisible(); - await expect(targetContainerDropdown).toHaveClass(/(^|\s)is-disabled(\s|$)/); +// // Test target container selection +// const targetContainerDropdown = panel.getByTestId("target-containerDropdown"); +// expect(targetContainerDropdown).toBeVisible(); +// await expect(targetContainerDropdown).toHaveClass(/(^|\s)is-disabled(\s|$)/); - const targetDatabaseDropdown = panel.getByTestId("target-databaseDropdown"); - await targetDatabaseDropdown.click(); - const targetDbDropdownItem = await getDropdownItemByNameOrPosition( - frame, - { position: 0 }, - { ariaLabel: "Database" }, - ); - await targetDbDropdownItem.click(); +// const targetDatabaseDropdown = panel.getByTestId("target-databaseDropdown"); +// await targetDatabaseDropdown.click(); +// const targetDbDropdownItem = await getDropdownItemByNameOrPosition( +// frame, +// { position: 0 }, +// { ariaLabel: "Database" }, +// ); +// await targetDbDropdownItem.click(); - await expect(targetContainerDropdown).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); - await targetContainerDropdown.click(); +// await expect(targetContainerDropdown).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); +// await targetContainerDropdown.click(); - // First try selecting the same container (should show error) - const targetContainerDropdownItem1 = await getDropdownItemByNameOrPosition( - frame, - { position: 0 }, - { ariaLabel: "Container" }, - ); - await targetContainerDropdownItem1.click(); +// // First try selecting the same container (should show error) +// const targetContainerDropdownItem1 = await getDropdownItemByNameOrPosition( +// frame, +// { position: 0 }, +// { ariaLabel: "Container" }, +// ); +// await targetContainerDropdownItem1.click(); - await panel.getByRole("button", { name: "Next" }).click(); +// await panel.getByRole("button", { name: "Next" }).click(); - // Verify validation error for same source and target containers - const errorContainer = panel.getByTestId("Panel:ErrorContainer"); - await expect(errorContainer).toBeVisible(); - await expect(errorContainer).toHaveText(/Source and destination containers cannot be the same/i); +// // Verify validation error for same source and target containers +// const errorContainer = panel.getByTestId("Panel:ErrorContainer"); +// await expect(errorContainer).toBeVisible(); +// await expect(errorContainer).toHaveText(/Source and destination containers cannot be the same/i); - // Select different target container - await targetContainerDropdown.click(); - const targetContainerDropdownItem2 = await getDropdownItemByNameOrPosition( - frame, - { position: 1 }, - { ariaLabel: "Container" }, - ); - await targetContainerDropdownItem2.click(); +// // Select different target container +// await targetContainerDropdown.click(); +// const targetContainerDropdownItem2 = await getDropdownItemByNameOrPosition( +// frame, +// { position: 1 }, +// { ariaLabel: "Container" }, +// ); +// await targetContainerDropdownItem2.click(); - // Generate expected job name based on selections - const selectedSourceDatabase = await sourceDatabaseDropdown.innerText(); - const selectedSourceContainer = await sourceContainerDropdown.innerText(); - const selectedTargetDatabase = await targetDatabaseDropdown.innerText(); - const selectedTargetContainer = await targetContainerDropdown.innerText(); - expectedCopyJobNameInitial = `${truncateName(selectedSourceDatabase)}.${truncateName( - selectedSourceContainer, - )}_${truncateName(selectedTargetDatabase)}.${truncateName(selectedTargetContainer)}`; +// // Generate expected job name based on selections +// const selectedSourceDatabase = await sourceDatabaseDropdown.innerText(); +// const selectedSourceContainer = await sourceContainerDropdown.innerText(); +// const selectedTargetDatabase = await targetDatabaseDropdown.innerText(); +// const selectedTargetContainer = await targetContainerDropdown.innerText(); +// expectedCopyJobNameInitial = `${truncateName(selectedSourceDatabase)}.${truncateName( +// selectedSourceContainer, +// )}_${truncateName(selectedTargetDatabase)}.${truncateName(selectedTargetContainer)}`; - await panel.getByRole("button", { name: "Next" }).click(); +// await panel.getByRole("button", { name: "Next" }).click(); - // Error should disappear and preview should be visible - await expect(errorContainer).not.toBeVisible(); - await expect(panel.getByTestId("Panel:PreviewCopyJob")).toBeVisible(); +// // Error should disappear and preview should be visible +// await expect(errorContainer).not.toBeVisible(); +// await expect(panel.getByTestId("Panel:PreviewCopyJob")).toBeVisible(); - // Verify job preview details - const previewContainer = panel.getByTestId("Panel:PreviewCopyJob"); - await expect(previewContainer).toBeVisible(); - await expect(previewContainer.getByTestId("source-subscription-name")).toHaveText(expectedSubscriptionName); - await expect(previewContainer.getByTestId("source-account-name")).toHaveText(expectedAccountName); +// // Verify job preview details +// const previewContainer = panel.getByTestId("Panel:PreviewCopyJob"); +// await expect(previewContainer).toBeVisible(); +// await expect(previewContainer.getByTestId("source-subscription-name")).toHaveText(expectedSubscriptionName); +// await expect(previewContainer.getByTestId("source-account-name")).toHaveText(expectedAccountName); - const jobNameInput = previewContainer.getByTestId("job-name-textfield"); - await expect(jobNameInput).toHaveValue(new RegExp(expectedCopyJobNameInitial)); +// const jobNameInput = previewContainer.getByTestId("job-name-textfield"); +// await expect(jobNameInput).toHaveValue(new RegExp(expectedCopyJobNameInitial)); - const primaryBtn = panel.getByRole("button", { name: "Copy", exact: true }); - await expect(primaryBtn).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); +// const primaryBtn = panel.getByRole("button", { name: "Copy", exact: true }); +// await expect(primaryBtn).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); - // Test invalid job name validation (spaces not allowed) - await jobNameInput.fill("test job name"); - await expect(primaryBtn).toHaveClass(/(^|\s)is-disabled(\s|$)/); +// // Test invalid job name validation (spaces not allowed) +// await jobNameInput.fill("test job name"); +// await expect(primaryBtn).toHaveClass(/(^|\s)is-disabled(\s|$)/); - // Test duplicate job name error handling - const duplicateJobName = "test-job-name-1"; - await jobNameInput.fill(duplicateJobName); +// // Test duplicate job name error handling +// const duplicateJobName = "test-job-name-1"; +// await jobNameInput.fill(duplicateJobName); - const copyButton = panel.getByRole("button", { name: "Copy", exact: true }); - const expectedErrorMessage = `Duplicate job name '${duplicateJobName}'`; +// const copyButton = panel.getByRole("button", { name: "Copy", exact: true }); +// const expectedErrorMessage = `Duplicate job name '${duplicateJobName}'`; - await interceptAndInspectApiRequest( - page, - `${expectedAccountName}/dataTransferJobs/${duplicateJobName}`, - "PUT", - new Error(expectedErrorMessage), - (url?: string) => url?.includes(duplicateJobName) ?? false, - ); +// await interceptAndInspectApiRequest( +// page, +// `${expectedAccountName}/dataTransferJobs/${duplicateJobName}`, +// "PUT", +// new Error(expectedErrorMessage), +// (url?: string) => url?.includes(duplicateJobName) ?? false, +// ); - let errorThrown = false; - try { - await copyButton.click(); - await page.waitForTimeout(2000); - } catch (error: any) { - errorThrown = true; - expect(error.message).toContain("not allowed"); - } +// let errorThrown = false; +// try { +// await copyButton.click(); +// await page.waitForTimeout(2000); +// } catch (error: any) { +// errorThrown = true; +// expect(error.message).toContain("not allowed"); +// } - if (!errorThrown) { - const errorContainer = panel.getByTestId("Panel:ErrorContainer"); - await expect(errorContainer).toBeVisible(); - await expect(errorContainer).toHaveText(new RegExp(expectedErrorMessage, "i")); - } +// if (!errorThrown) { +// const errorContainer = panel.getByTestId("Panel:ErrorContainer"); +// await expect(errorContainer).toBeVisible(); +// await expect(errorContainer).toHaveText(new RegExp(expectedErrorMessage, "i")); +// } - await expect(panel).toBeVisible(); +// await expect(panel).toBeVisible(); - // Test successful job creation with valid job name - const validJobName = expectedJobName; +// // Test successful job creation with valid job name +// const validJobName = expectedJobName; - const copyJobCreationPromise = waitForApiResponse( - page, - `${expectedAccountName}/dataTransferJobs/${validJobName}`, - "PUT", - ); +// const copyJobCreationPromise = waitForApiResponse( +// page, +// `${expectedAccountName}/dataTransferJobs/${validJobName}`, +// "PUT", +// ); - await jobNameInput.fill(validJobName); - await expect(copyButton).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); +// await jobNameInput.fill(validJobName); +// await expect(copyButton).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); - await copyButton.click(); +// await copyButton.click(); - const response = await copyJobCreationPromise; - expect(response.ok()).toBe(true); +// const response = await copyJobCreationPromise; +// expect(response.ok()).toBe(true); - // Verify panel closes and job appears in the list - await expect(panel).not.toBeVisible({ timeout: 5000 }); +// // Verify panel closes and job appears in the list +// await expect(panel).not.toBeVisible({ timeout: 5000 }); - const jobsListContainer = wrapper.locator(".CopyJobListContainer .ms-DetailsList-contentWrapper .ms-List-page"); - await jobsListContainer.waitFor({ state: "visible", timeout: 5000 }); +// const jobsListContainer = wrapper.locator(".CopyJobListContainer .ms-DetailsList-contentWrapper .ms-List-page"); +// await jobsListContainer.waitFor({ state: "visible", timeout: 5000 }); - const jobItem = jobsListContainer.getByText(validJobName); - await jobItem.waitFor({ state: "visible", timeout: 5000 }); - await expect(jobItem).toBeVisible(); - }); -}); +// const jobItem = jobsListContainer.getByText(validJobName); +// await jobItem.waitFor({ state: "visible", timeout: 5000 }); +// await expect(jobItem).toBeVisible(); +// }); +// }); diff --git a/test/sql/containercopy/onlineMigration.spec.ts b/test/sql/containercopy/onlineMigration.spec.ts index 3914f6002..0d1bd0209 100644 --- a/test/sql/containercopy/onlineMigration.spec.ts +++ b/test/sql/containercopy/onlineMigration.spec.ts @@ -1,185 +1,185 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { expect, Frame, Locator, Page, test } from "@playwright/test"; -import { - ContainerCopy, - getAccountName, - getDropdownItemByNameOrPosition, - TestAccount, - waitForApiResponse, -} from "../../fx"; -import { createMultipleTestContainers } from "../../testData"; +// /* eslint-disable @typescript-eslint/no-explicit-any */ +// import { expect, Frame, Locator, Page, test } from "@playwright/test"; +// import { +// ContainerCopy, +// getAccountName, +// getDropdownItemByNameOrPosition, +// TestAccount, +// waitForApiResponse, +// } from "../../fx"; +// import { createMultipleTestContainers } from "../../testData"; -test.describe("Container Copy - Online Migration", () => { - let page: Page; - let wrapper: Locator; - let panel: Locator; - let frame: Frame; - let targetAccountName: string; +// test.describe("Container Copy - Online Migration", () => { +// let page: Page; +// let wrapper: Locator; +// let panel: Locator; +// let frame: Frame; +// let targetAccountName: string; - test.beforeEach("Setup for online migration test", async ({ browser }) => { - await createMultipleTestContainers({ accountType: TestAccount.SQLContainerCopyOnly, containerCount: 2 }); +// test.beforeEach("Setup for online migration test", async ({ browser }) => { +// await createMultipleTestContainers({ accountType: TestAccount.SQLContainerCopyOnly, containerCount: 2 }); - page = await browser.newPage(); - ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); - targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); - }); +// page = await browser.newPage(); +// ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); +// targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); +// }); - test.afterEach("Cleanup after online migration test", async () => { - await page.unroute(/.*/, (route) => route.continue()); - await page.close(); - }); +// test.afterEach("Cleanup after online migration test", async () => { +// await page.unroute(/.*/, (route) => route.continue()); +// await page.close(); +// }); - test("Successfully create and manage online migration copy job", async () => { - expect(wrapper).not.toBeNull(); - await wrapper.locator(".commandBarContainer").waitFor({ state: "visible" }); +// test("Successfully create and manage online migration copy job", async () => { +// expect(wrapper).not.toBeNull(); +// await wrapper.locator(".commandBarContainer").waitFor({ state: "visible" }); - // Open Create Copy Job panel - const createCopyJobButton = wrapper.getByTestId("CommandBar/Button:Create Copy Job"); - await expect(createCopyJobButton).toBeVisible(); - await createCopyJobButton.click(); - panel = frame.getByTestId("Panel:Create copy job"); - await expect(panel).toBeVisible(); +// // Open Create Copy Job panel +// const createCopyJobButton = wrapper.getByTestId("CommandBar/Button:Create Copy Job"); +// await expect(createCopyJobButton).toBeVisible(); +// await createCopyJobButton.click(); +// panel = frame.getByTestId("Panel:Create copy job"); +// await expect(panel).toBeVisible(); - // Reduced wait time for better performance - await page.waitForTimeout(1000); +// // Reduced wait time for better performance +// await page.waitForTimeout(1000); - // Enable online migration mode - const migrationTypeContainer = panel.getByTestId("migration-type"); - const onlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Online mode/i }); - await onlineCopyRadioButton.click({ force: true }); +// // Enable online migration mode +// const migrationTypeContainer = panel.getByTestId("migration-type"); +// const onlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Online mode/i }); +// await onlineCopyRadioButton.click({ force: true }); - await expect(migrationTypeContainer.getByTestId("migration-type-description-online")).toBeVisible(); +// await expect(migrationTypeContainer.getByTestId("migration-type-description-online")).toBeVisible(); - await panel.getByRole("button", { name: "Next" }).click(); +// await panel.getByRole("button", { name: "Next" }).click(); - // Verify permissions screen is shown for online migration - const permissionScreen = panel.getByTestId("Panel:AssignPermissionsContainer"); - await expect(permissionScreen).toBeVisible(); - await expect(permissionScreen.getByText("Online container copy", { exact: true })).toBeVisible(); +// // Verify permissions screen is shown for online migration +// const permissionScreen = panel.getByTestId("Panel:AssignPermissionsContainer"); +// await expect(permissionScreen).toBeVisible(); +// await expect(permissionScreen.getByText("Online container copy", { exact: true })).toBeVisible(); - // Skip permissions setup and proceed to container selection - await panel.getByRole("button", { name: "Next" }).click(); +// // Skip permissions setup and proceed to container selection +// await panel.getByRole("button", { name: "Next" }).click(); - // Configure source and target containers for online migration - const sourceDatabaseDropdown = panel.getByTestId("source-databaseDropdown"); - await sourceDatabaseDropdown.click(); - const sourceDbDropdownItem = await getDropdownItemByNameOrPosition( - frame, - { position: 0 }, - { ariaLabel: "Database" }, - ); - await sourceDbDropdownItem.click(); +// // Configure source and target containers for online migration +// const sourceDatabaseDropdown = panel.getByTestId("source-databaseDropdown"); +// await sourceDatabaseDropdown.click(); +// const sourceDbDropdownItem = await getDropdownItemByNameOrPosition( +// frame, +// { position: 0 }, +// { ariaLabel: "Database" }, +// ); +// await sourceDbDropdownItem.click(); - const sourceContainerDropdown = panel.getByTestId("source-containerDropdown"); - await sourceContainerDropdown.click(); - const sourceContainerDropdownItem = await getDropdownItemByNameOrPosition( - frame, - { position: 0 }, - { ariaLabel: "Container" }, - ); - await sourceContainerDropdownItem.click(); +// const sourceContainerDropdown = panel.getByTestId("source-containerDropdown"); +// await sourceContainerDropdown.click(); +// const sourceContainerDropdownItem = await getDropdownItemByNameOrPosition( +// frame, +// { position: 0 }, +// { ariaLabel: "Container" }, +// ); +// await sourceContainerDropdownItem.click(); - const targetDatabaseDropdown = panel.getByTestId("target-databaseDropdown"); - await targetDatabaseDropdown.click(); - const targetDbDropdownItem = await getDropdownItemByNameOrPosition( - frame, - { position: 0 }, - { ariaLabel: "Database" }, - ); - await targetDbDropdownItem.click(); +// const targetDatabaseDropdown = panel.getByTestId("target-databaseDropdown"); +// await targetDatabaseDropdown.click(); +// const targetDbDropdownItem = await getDropdownItemByNameOrPosition( +// frame, +// { position: 0 }, +// { ariaLabel: "Database" }, +// ); +// await targetDbDropdownItem.click(); - const targetContainerDropdown = panel.getByTestId("target-containerDropdown"); - await targetContainerDropdown.click(); - const targetContainerDropdownItem = await getDropdownItemByNameOrPosition( - frame, - { position: 1 }, - { ariaLabel: "Container" }, - ); - await targetContainerDropdownItem.click(); +// const targetContainerDropdown = panel.getByTestId("target-containerDropdown"); +// await targetContainerDropdown.click(); +// const targetContainerDropdownItem = await getDropdownItemByNameOrPosition( +// frame, +// { position: 1 }, +// { ariaLabel: "Container" }, +// ); +// await targetContainerDropdownItem.click(); - await panel.getByRole("button", { name: "Next" }).click(); +// await panel.getByRole("button", { name: "Next" }).click(); - // Verify job preview and create the online migration job - const previewContainer = panel.getByTestId("Panel:PreviewCopyJob"); - await expect(previewContainer.getByTestId("source-account-name")).toHaveText(targetAccountName); +// // Verify job preview and create the online migration job +// const previewContainer = panel.getByTestId("Panel:PreviewCopyJob"); +// await expect(previewContainer.getByTestId("source-account-name")).toHaveText(targetAccountName); - const jobNameInput = previewContainer.getByTestId("job-name-textfield"); - const onlineMigrationJobName = await jobNameInput.inputValue(); +// const jobNameInput = previewContainer.getByTestId("job-name-textfield"); +// const onlineMigrationJobName = await jobNameInput.inputValue(); - const copyButton = panel.getByRole("button", { name: "Copy", exact: true }); +// const copyButton = panel.getByRole("button", { name: "Copy", exact: true }); - const copyJobCreationPromise = waitForApiResponse( - page, - `${targetAccountName}/dataTransferJobs/${onlineMigrationJobName}`, - "PUT", - ); - await copyButton.click(); - await page.waitForTimeout(1000); // Reduced wait time +// const copyJobCreationPromise = waitForApiResponse( +// page, +// `${targetAccountName}/dataTransferJobs/${onlineMigrationJobName}`, +// "PUT", +// ); +// await copyButton.click(); +// await page.waitForTimeout(1000); // Reduced wait time - const response = await copyJobCreationPromise; - expect(response.ok()).toBe(true); +// const response = await copyJobCreationPromise; +// expect(response.ok()).toBe(true); - // Verify panel closes and job appears in the list - await expect(panel).not.toBeVisible({ timeout: 5000 }); +// // Verify panel closes and job appears in the list +// await expect(panel).not.toBeVisible({ timeout: 5000 }); - const jobsListContainer = wrapper.locator(".CopyJobListContainer .ms-DetailsList-contentWrapper .ms-List-page"); - await jobsListContainer.waitFor({ state: "visible", timeout: 5000 }); +// const jobsListContainer = wrapper.locator(".CopyJobListContainer .ms-DetailsList-contentWrapper .ms-List-page"); +// await jobsListContainer.waitFor({ state: "visible", timeout: 5000 }); - let jobRow, statusCell, actionMenuButton; - jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); - statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); - await jobRow.waitFor({ state: "visible", timeout: 5000 }); +// let jobRow, statusCell, actionMenuButton; +// jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); +// statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); +// await jobRow.waitFor({ state: "visible", timeout: 5000 }); - // Verify job status changes to queued state - await expect(statusCell).toContainText(/running|queued|pending/i, { timeout: 5000 }); +// // Verify job status changes to queued state +// await expect(statusCell).toContainText(/running|queued|pending/i, { timeout: 5000 }); - // Test job lifecycle management through action menu - actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); - await actionMenuButton.click(); +// // Test job lifecycle management through action menu +// actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); +// await actionMenuButton.click(); - // Test pause functionality - const pauseAction = frame.locator(".ms-ContextualMenu-list button:has-text('Pause')"); - await pauseAction.click(); +// // Test pause functionality +// const pauseAction = frame.locator(".ms-ContextualMenu-list button:has-text('Pause')"); +// await pauseAction.click(); - const pauseResponse = await waitForApiResponse( - page, - `${targetAccountName}/dataTransferJobs/${onlineMigrationJobName}/pause`, - "POST", - ); - expect(pauseResponse.ok()).toBe(true); +// const pauseResponse = await waitForApiResponse( +// page, +// `${targetAccountName}/dataTransferJobs/${onlineMigrationJobName}/pause`, +// "POST", +// ); +// expect(pauseResponse.ok()).toBe(true); - // Verify job status changes to paused - jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); - await jobRow.waitFor({ state: "visible", timeout: 5000 }); - statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); - await expect(statusCell).toContainText(/paused/i, { timeout: 5000 }); - await page.waitForTimeout(1000); +// // Verify job status changes to paused +// jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); +// await jobRow.waitFor({ state: "visible", timeout: 5000 }); +// statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); +// await expect(statusCell).toContainText(/paused/i, { timeout: 5000 }); +// await page.waitForTimeout(1000); - // Test cancel job functionality - actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); - await actionMenuButton.click(); - await frame.locator(".ms-ContextualMenu-list button:has-text('Cancel')").click(); +// // Test cancel job functionality +// actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); +// await actionMenuButton.click(); +// await frame.locator(".ms-ContextualMenu-list button:has-text('Cancel')").click(); - // Verify cancellation confirmation dialog - await expect(frame.locator(".ms-Dialog-main")).toBeVisible({ timeout: 2000 }); - await expect(frame.locator(".ms-Dialog-main")).toContainText(onlineMigrationJobName); +// // Verify cancellation confirmation dialog +// await expect(frame.locator(".ms-Dialog-main")).toBeVisible({ timeout: 2000 }); +// await expect(frame.locator(".ms-Dialog-main")).toContainText(onlineMigrationJobName); - const cancelDialogButton = frame.locator(".ms-Dialog-main").getByTestId("DialogButton:Cancel"); - await expect(cancelDialogButton).toBeVisible(); - await cancelDialogButton.click(); - await expect(frame.locator(".ms-Dialog-main")).not.toBeVisible(); +// const cancelDialogButton = frame.locator(".ms-Dialog-main").getByTestId("DialogButton:Cancel"); +// await expect(cancelDialogButton).toBeVisible(); +// await cancelDialogButton.click(); +// await expect(frame.locator(".ms-Dialog-main")).not.toBeVisible(); - actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); - await actionMenuButton.click(); - await frame.locator(".ms-ContextualMenu-list button:has-text('Cancel')").click(); +// actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); +// await actionMenuButton.click(); +// await frame.locator(".ms-ContextualMenu-list button:has-text('Cancel')").click(); - const confirmDialogButton = frame.locator(".ms-Dialog-main").getByTestId("DialogButton:Confirm"); - await expect(confirmDialogButton).toBeVisible(); - await confirmDialogButton.click(); +// const confirmDialogButton = frame.locator(".ms-Dialog-main").getByTestId("DialogButton:Confirm"); +// await expect(confirmDialogButton).toBeVisible(); +// await confirmDialogButton.click(); - // Verify final job status is cancelled - jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); - statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); - await expect(statusCell).toContainText(/cancelled/i, { timeout: 5000 }); - }); -}); +// // Verify final job status is cancelled +// jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); +// statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); +// await expect(statusCell).toContainText(/cancelled/i, { timeout: 5000 }); +// }); +// }); From 561eb6d1fa2d099a2773a42fcc25141ea263757b Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Thu, 22 Jan 2026 08:30:15 -0800 Subject: [PATCH 03/19] delete db after each test --- test/sql/document.spec.ts | 4 +--- test/sql/query.spec.ts | 9 +++------ test/sql/scaleAndSettings/changePartitionKey.spec.ts | 9 +++------ test/sql/scaleAndSettings/scale.spec.ts | 4 +--- test/sql/scaleAndSettings/settings.spec.ts | 9 +++------ test/sql/scripts/trigger.spec.ts | 8 +++----- test/sql/scripts/userDefinedFunction.spec.ts | 8 +++----- 7 files changed, 17 insertions(+), 34 deletions(-) diff --git a/test/sql/document.spec.ts b/test/sql/document.spec.ts index 5d17c22c3..a093da376 100644 --- a/test/sql/document.spec.ts +++ b/test/sql/document.spec.ts @@ -136,9 +136,7 @@ test.describe.serial("Upload Item", () => { if (existsSync(uploadDocumentDirPath)) { rmdirSync(uploadDocumentDirPath); } - if (!process.env.CI) { - await context?.dispose(); - } + await context?.dispose(); }); test.afterEach("Close Upload Items panel if still open", async () => { diff --git a/test/sql/query.spec.ts b/test/sql/query.spec.ts index f9dfc80f9..6368c4327 100644 --- a/test/sql/query.spec.ts +++ b/test/sql/query.spec.ts @@ -30,12 +30,9 @@ test.beforeEach("Open new query tab", async ({ page }) => { await explorer.frame.getByTestId("NotificationConsole/Contents").waitFor(); }); -// Delete database only if not running in CI -if (!process.env.CI) { - test.afterAll("Delete Test Database", async () => { - await context?.dispose(); - }); -} +test.afterAll("Delete Test Database", async () => { + await context?.dispose(); +}); test("Query results", async () => { // Run the query and verify the results diff --git a/test/sql/scaleAndSettings/changePartitionKey.spec.ts b/test/sql/scaleAndSettings/changePartitionKey.spec.ts index 1f23d3154..b92d65ee7 100644 --- a/test/sql/scaleAndSettings/changePartitionKey.spec.ts +++ b/test/sql/scaleAndSettings/changePartitionKey.spec.ts @@ -23,12 +23,9 @@ test.describe("Change Partition Key", () => { await PartitionKeyTab.click(); }); - // Delete database only if not running in CI - if (!process.env.CI) { - test.afterEach("Delete Test Database", async () => { - await context?.dispose(); - }); - } + test.afterEach("Delete Test Database", async () => { + await context?.dispose(); + }); test("Change partition key path", async ({ page }) => { await expect(explorer.frame.getByText("/partitionKey")).toBeVisible(); diff --git a/test/sql/scaleAndSettings/scale.spec.ts b/test/sql/scaleAndSettings/scale.spec.ts index d12db999c..d886b2def 100644 --- a/test/sql/scaleAndSettings/scale.spec.ts +++ b/test/sql/scaleAndSettings/scale.spec.ts @@ -118,7 +118,5 @@ async function openScaleTab(browser: Browser): Promise { } async function cleanup({ context }: Partial) { - if (!process.env.CI) { - await context?.dispose(); - } + await context?.dispose(); } diff --git a/test/sql/scaleAndSettings/settings.spec.ts b/test/sql/scaleAndSettings/settings.spec.ts index 3f14422eb..f60889574 100644 --- a/test/sql/scaleAndSettings/settings.spec.ts +++ b/test/sql/scaleAndSettings/settings.spec.ts @@ -17,12 +17,9 @@ test.describe("Settings under Scale & Settings", () => { await settingsTab.click(); }); - // Delete database only if not running in CI - if (!process.env.CI) { - test.afterAll("Delete Test Database", async () => { - await context?.dispose(); - }); - } + test.afterAll("Delete Test Database", async () => { + await context?.dispose(); + }); test("Update TTL to On (no default)", async () => { const ttlOnNoDefaultRadioButton = explorer.frame.getByRole("radio", { name: "ttl-on-no-default-option" }); diff --git a/test/sql/scripts/trigger.spec.ts b/test/sql/scripts/trigger.spec.ts index 6874c2aac..9792466d5 100644 --- a/test/sql/scripts/trigger.spec.ts +++ b/test/sql/scripts/trigger.spec.ts @@ -26,11 +26,9 @@ test.describe("Triggers", () => { explorer = await DataExplorer.open(page, TestAccount.SQL); }); - if (!process.env.CI) { - test.afterAll("Delete Test Database", async () => { - await context?.dispose(); - }); - } + test.afterAll("Delete Test Database", async () => { + await context?.dispose(); + }); test("Add and delete trigger", async ({ page }, testInfo) => { // Open container context menu and click New Trigger diff --git a/test/sql/scripts/userDefinedFunction.spec.ts b/test/sql/scripts/userDefinedFunction.spec.ts index 911b1f4ce..c46b19989 100644 --- a/test/sql/scripts/userDefinedFunction.spec.ts +++ b/test/sql/scripts/userDefinedFunction.spec.ts @@ -19,11 +19,9 @@ test.describe("User Defined Functions", () => { explorer = await DataExplorer.open(page, TestAccount.SQL); }); - if (!process.env.CI) { - test.afterAll("Delete Test Database", async () => { - await context?.dispose(); - }); - } + test.afterAll("Delete Test Database", async () => { + await context?.dispose(); + }); test("Add, execute, and delete user defined function", async ({ page }, testInfo) => { // Open container context menu and click New UDF From 7665f60fdddd597a535fe8e45949dfe26ec9e82d Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Thu, 22 Jan 2026 12:32:58 -0800 Subject: [PATCH 04/19] DEBUG: expand console for mongo testing --- test/mongo/document.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/mongo/document.spec.ts b/test/mongo/document.spec.ts index b6703c49a..60cd0be08 100644 --- a/test/mongo/document.spec.ts +++ b/test/mongo/document.spec.ts @@ -26,6 +26,8 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { await documentsTab.documentsFilter.waitFor(); await documentsTab.documentsListPane.waitFor(); await expect(documentsTab.resultsEditor.locator).toBeAttached({ timeout: 60 * 1000 }); + + await explorer.expandNotificationConsole(); }); test.afterEach(async ({ page }) => { await page.unrouteAll({ behavior: "ignoreErrors" }); From 094fd4d6f4f7e473ab1036bc8c66a37262b743d5 Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Thu, 22 Jan 2026 12:33:17 -0800 Subject: [PATCH 05/19] find first execute button for stored procedure --- test/sql/scripts/storedProcedure.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sql/scripts/storedProcedure.spec.ts b/test/sql/scripts/storedProcedure.spec.ts index 35fb4e0f8..9b53f384d 100644 --- a/test/sql/scripts/storedProcedure.spec.ts +++ b/test/sql/scripts/storedProcedure.spec.ts @@ -43,7 +43,7 @@ test.describe("Stored Procedures", () => { ); // Execute stored procedure - const executeButton = explorer.commandBarButton(CommandBarButton.Execute); + const executeButton = explorer.commandBarButton(CommandBarButton.Execute).first(); await executeButton.click(); const executeSidePanelButton = explorer.frame.getByTestId("Panel/OkButton"); await executeSidePanelButton.click(); From 544ac890c6eec2bf1cbf234409ee4186dfc65285 Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Thu, 22 Jan 2026 13:34:17 -0800 Subject: [PATCH 06/19] DEBUG: wait for editor to process changes --- test/mongo/document.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/mongo/document.spec.ts b/test/mongo/document.spec.ts index 60cd0be08..af1095d5f 100644 --- a/test/mongo/document.spec.ts +++ b/test/mongo/document.spec.ts @@ -50,7 +50,7 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { expect(resultData?._id).not.toBeNull(); expect(resultData?._id).toEqual(docId); }); - test(`should be able to create and delete new document from ${docId}`, async () => { + test(`should be able to create and delete new document from ${docId}`, async ({ page }) => { const span = documentsTab.documentsListPane.getByText(docId, { exact: true }).nth(0); await span.waitFor(); await expect(span).toBeVisible(); @@ -73,6 +73,7 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { }; await documentsTab.resultsEditor.setText(JSON.stringify(newDocument)); + await page.waitForTimeout(2000); // wait for editor to process changes const saveButton = await explorer.waitForCommandBarButton("Save", 5000); await saveButton.click({ timeout: 5000 }); await expect(saveButton).toBeHidden({ timeout: 5000 }); From 4a5ed80c6c23f6bdf4ca108358494b4fe951ccdf Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Thu, 22 Jan 2026 13:54:10 -0800 Subject: [PATCH 07/19] increase wait time to 5s --- test/fx.ts | 4 +++- test/mongo/document.spec.ts | 10 +++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/test/fx.ts b/test/fx.ts index 6a65b652c..75de1f672 100644 --- a/test/fx.ts +++ b/test/fx.ts @@ -378,9 +378,11 @@ type PanelOpenOptions = { export enum CommandBarButton { Save = "Save", + Delete = "Delete", Execute = "Execute", ExecuteQuery = "Execute Query", UploadItem = "Upload Item", + NewDocument = "New Document", } /** Helper class that provides locator methods for DataExplorer components, on top of a Frame */ @@ -478,7 +480,7 @@ export class DataExplorer { return await this.waitForNode(`${databaseId}/${containerId}/Documents`); } - async waitForCommandBarButton(label: string, timeout?: number): Promise { + async waitForCommandBarButton(label: CommandBarButton, timeout?: number): Promise { const commandBar = this.commandBarButton(label); await commandBar.waitFor({ state: "visible", timeout }); return commandBar; diff --git a/test/mongo/document.spec.ts b/test/mongo/document.spec.ts index af1095d5f..122922527 100644 --- a/test/mongo/document.spec.ts +++ b/test/mongo/document.spec.ts @@ -1,7 +1,7 @@ import { expect, test } from "@playwright/test"; import { setupCORSBypass } from "../CORSBypass"; -import { DataExplorer, DocumentsTab, TestAccount } from "../fx"; +import { CommandBarButton, DataExplorer, DocumentsTab, TestAccount } from "../fx"; import { retry, serializeMongoToJson, setPartitionKeys } from "../testData"; import { documentTestCases } from "./testCases"; @@ -58,7 +58,7 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { await span.click(); let newDocumentId; await retry(async () => { - const newDocumentButton = await explorer.waitForCommandBarButton("New Document", 5000); + const newDocumentButton = await explorer.waitForCommandBarButton(CommandBarButton.NewDocument, 5000); await expect(newDocumentButton).toBeVisible(); await expect(newDocumentButton).toBeEnabled(); await newDocumentButton.click(); @@ -73,8 +73,8 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { }; await documentsTab.resultsEditor.setText(JSON.stringify(newDocument)); - await page.waitForTimeout(2000); // wait for editor to process changes - const saveButton = await explorer.waitForCommandBarButton("Save", 5000); + await page.waitForTimeout(5000); // wait for editor to process changes + const saveButton = await explorer.waitForCommandBarButton(CommandBarButton.Save, 5000); await saveButton.click({ timeout: 5000 }); await expect(saveButton).toBeHidden({ timeout: 5000 }); }, 3); @@ -87,7 +87,7 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { await newSpan.click(); await expect(documentsTab.resultsEditor.locator).toBeAttached({ timeout: 60 * 1000 }); - const deleteButton = await explorer.waitForCommandBarButton("Delete", 5000); + const deleteButton = await explorer.waitForCommandBarButton(CommandBarButton.Delete, 5000); await deleteButton.click(); const deleteDialogButton = await explorer.waitForDialogButton("Delete", 5000); From fd9cb0026ca4d7d029e086ca6bff2d40d42ead1d Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Thu, 22 Jan 2026 14:28:54 -0800 Subject: [PATCH 08/19] verify document text was set --- test/mongo/document.spec.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/mongo/document.spec.ts b/test/mongo/document.spec.ts index 122922527..8383d9edb 100644 --- a/test/mongo/document.spec.ts +++ b/test/mongo/document.spec.ts @@ -73,7 +73,11 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { }; await documentsTab.resultsEditor.setText(JSON.stringify(newDocument)); - await page.waitForTimeout(5000); // wait for editor to process changes + // Verify that the document text was set correctly + await expect + .poll(async () => await documentsTab.resultsEditor.text(), { timeout: 5000 }) + .toEqual(JSON.stringify(newDocument)); + const saveButton = await explorer.waitForCommandBarButton(CommandBarButton.Save, 5000); await saveButton.click({ timeout: 5000 }); await expect(saveButton).toBeHidden({ timeout: 5000 }); From c5da4eb25b81673112bf94c51e48ac400f3b8947 Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Fri, 23 Jan 2026 07:46:01 -0800 Subject: [PATCH 09/19] keep document spec as original --- test/mongo/document.spec.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/mongo/document.spec.ts b/test/mongo/document.spec.ts index 8383d9edb..d665216d6 100644 --- a/test/mongo/document.spec.ts +++ b/test/mongo/document.spec.ts @@ -73,11 +73,6 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { }; await documentsTab.resultsEditor.setText(JSON.stringify(newDocument)); - // Verify that the document text was set correctly - await expect - .poll(async () => await documentsTab.resultsEditor.text(), { timeout: 5000 }) - .toEqual(JSON.stringify(newDocument)); - const saveButton = await explorer.waitForCommandBarButton(CommandBarButton.Save, 5000); await saveButton.click({ timeout: 5000 }); await expect(saveButton).toBeHidden({ timeout: 5000 }); From 8027e5899ddd88c4b43b8addaf45391cb590be42 Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Fri, 23 Jan 2026 08:20:01 -0800 Subject: [PATCH 10/19] debug new document and save document count --- test/mongo/document.spec.ts | 40 ++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/test/mongo/document.spec.ts b/test/mongo/document.spec.ts index d665216d6..0968ff03c 100644 --- a/test/mongo/document.spec.ts +++ b/test/mongo/document.spec.ts @@ -57,25 +57,37 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { await span.click(); let newDocumentId; + let retryCount = 0; await retry(async () => { - const newDocumentButton = await explorer.waitForCommandBarButton(CommandBarButton.NewDocument, 5000); - await expect(newDocumentButton).toBeVisible(); - await expect(newDocumentButton).toBeEnabled(); - await newDocumentButton.click(); + try { + const newDocumentButton = await explorer.waitForCommandBarButton(CommandBarButton.NewDocument, 5000); + await expect(newDocumentButton).toBeVisible(); + await expect(newDocumentButton).toBeEnabled(); + await newDocumentButton.click(); + console.log(`DEBUG: Clicked New Document button - retryCount=${retryCount}`); + await expect(documentsTab.resultsEditor.locator).toBeAttached({ timeout: 60 * 1000 }); - await expect(documentsTab.resultsEditor.locator).toBeAttached({ timeout: 60 * 1000 }); + newDocumentId = `${Date.now().toString()}-delete`; - newDocumentId = `${Date.now().toString()}-delete`; + const newDocument = { + _id: newDocumentId, + ...setPartitionKeys(partitionKeys || []), + }; - const newDocument = { - _id: newDocumentId, - ...setPartitionKeys(partitionKeys || []), - }; + await documentsTab.resultsEditor.setText(JSON.stringify(newDocument)); + const saveButton = await explorer.waitForCommandBarButton(CommandBarButton.Save, 5000); + await saveButton.click({ timeout: 5000 }); + console.log(`DEBUG: Clicked Save button - retryCount=${retryCount}`); - await documentsTab.resultsEditor.setText(JSON.stringify(newDocument)); - const saveButton = await explorer.waitForCommandBarButton(CommandBarButton.Save, 5000); - await saveButton.click({ timeout: 5000 }); - await expect(saveButton).toBeHidden({ timeout: 5000 }); + await expect(saveButton).toBeHidden({ timeout: 5000 }); + } catch (err) { + retryCount++; + console.warn( + `DEBUG: Attempt ${retryCount} to create new document from ${docId} failed: ${(err as Error).message}`, + ); + + throw err; + } }, 3); await documentsTab.setFilter(`{_id: "${newDocumentId}"}`); From 574769ba89147e6f2d7e014025a480559f35e755 Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Fri, 23 Jan 2026 09:13:14 -0800 Subject: [PATCH 11/19] when loading a document, wait for document text to appear then click new document --- test/mongo/document.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/mongo/document.spec.ts b/test/mongo/document.spec.ts index 0968ff03c..2b880fea2 100644 --- a/test/mongo/document.spec.ts +++ b/test/mongo/document.spec.ts @@ -50,12 +50,14 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { expect(resultData?._id).not.toBeNull(); expect(resultData?._id).toEqual(docId); }); - test(`should be able to create and delete new document from ${docId}`, async ({ page }) => { + test(`should be able to create and delete new document from ${docId}`, async () => { const span = documentsTab.documentsListPane.getByText(docId, { exact: true }).nth(0); await span.waitFor(); await expect(span).toBeVisible(); await span.click(); + expect(await documentsTab.resultsEditor.text()).toContain(docId); + let newDocumentId; let retryCount = 0; await retry(async () => { From b3501e7dc829bb1bcc6763a2f07a1bc26f6119f6 Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Fri, 23 Jan 2026 09:34:02 -0800 Subject: [PATCH 12/19] wait for document to be loaded --- test/fx.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/fx.ts b/test/fx.ts index 75de1f672..e15abd498 100644 --- a/test/fx.ts +++ b/test/fx.ts @@ -63,6 +63,9 @@ export const TEST_MANUAL_THROUGHPUT_RU_2K = 2000; export const ONE_MINUTE_MS: number = 60 * 1000; function tryGetStandardName(accountType: TestAccount) { + if (accountType === TestAccount.MongoReadonly) { + return "aisayas-e2e-mongo-readonly"; + } if (process.env.DE_TEST_ACCOUNT_PREFIX) { const actualPrefix = process.env.DE_TEST_ACCOUNT_PREFIX.endsWith("-") ? process.env.DE_TEST_ACCOUNT_PREFIX From 19ffb5696d7fc47b0edf9d4334622838936aa895 Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Fri, 23 Jan 2026 12:37:45 -0800 Subject: [PATCH 13/19] remove debug statement --- test/fx.ts | 6 +- test/mongo/document.spec.ts | 5 +- .../containercopy/offlineMigration.spec.ts | 424 +++++++++--------- .../sql/containercopy/onlineMigration.spec.ts | 304 ++++++------- 4 files changed, 369 insertions(+), 370 deletions(-) diff --git a/test/fx.ts b/test/fx.ts index e15abd498..19e61e355 100644 --- a/test/fx.ts +++ b/test/fx.ts @@ -63,9 +63,9 @@ export const TEST_MANUAL_THROUGHPUT_RU_2K = 2000; export const ONE_MINUTE_MS: number = 60 * 1000; function tryGetStandardName(accountType: TestAccount) { - if (accountType === TestAccount.MongoReadonly) { - return "aisayas-e2e-mongo-readonly"; - } + // if (accountType === TestAccount.MongoReadonly) { + // return "aisayas-e2e-mongo-readonly"; + // } if (process.env.DE_TEST_ACCOUNT_PREFIX) { const actualPrefix = process.env.DE_TEST_ACCOUNT_PREFIX.endsWith("-") ? process.env.DE_TEST_ACCOUNT_PREFIX diff --git a/test/mongo/document.spec.ts b/test/mongo/document.spec.ts index 2b880fea2..956eb747f 100644 --- a/test/mongo/document.spec.ts +++ b/test/mongo/document.spec.ts @@ -50,14 +50,13 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { expect(resultData?._id).not.toBeNull(); expect(resultData?._id).toEqual(docId); }); - test(`should be able to create and delete new document from ${docId}`, async () => { + test(`should be able to create and delete new document from ${docId}`, async ({ page }) => { const span = documentsTab.documentsListPane.getByText(docId, { exact: true }).nth(0); await span.waitFor(); await expect(span).toBeVisible(); await span.click(); - expect(await documentsTab.resultsEditor.text()).toContain(docId); - + await page.waitForTimeout(5000); // wait for 5 seconds to ensure document is fully loaded let newDocumentId; let retryCount = 0; await retry(async () => { diff --git a/test/sql/containercopy/offlineMigration.spec.ts b/test/sql/containercopy/offlineMigration.spec.ts index e99610cb4..6d11a69f5 100644 --- a/test/sql/containercopy/offlineMigration.spec.ts +++ b/test/sql/containercopy/offlineMigration.spec.ts @@ -1,262 +1,262 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { expect, Frame, Locator, Page, test } from "@playwright/test"; -import { truncateName } from "../../../src/Explorer/ContainerCopy/CopyJobUtils"; -import { - ContainerCopy, - getAccountName, - getDropdownItemByNameOrPosition, - interceptAndInspectApiRequest, - TestAccount, - waitForApiResponse, -} from "../../fx"; -import { createMultipleTestContainers } from "../../testData"; +// /* eslint-disable @typescript-eslint/no-explicit-any */ +// import { expect, Frame, Locator, Page, test } from "@playwright/test"; +// import { truncateName } from "../../../src/Explorer/ContainerCopy/CopyJobUtils"; +// import { +// ContainerCopy, +// getAccountName, +// getDropdownItemByNameOrPosition, +// interceptAndInspectApiRequest, +// TestAccount, +// waitForApiResponse, +// } from "../../fx"; +// import { createMultipleTestContainers } from "../../testData"; -test.describe("Container Copy - Offline Migration", () => { - let page: Page; - let wrapper: Locator; - let panel: Locator; - let frame: Frame; - let expectedJobName: string; - let targetAccountName: string; - let expectedSubscriptionName: string; - let expectedCopyJobNameInitial: string; +// test.describe("Container Copy - Offline Migration", () => { +// let page: Page; +// let wrapper: Locator; +// let panel: Locator; +// let frame: Frame; +// let expectedJobName: string; +// let targetAccountName: string; +// let expectedSubscriptionName: string; +// let expectedCopyJobNameInitial: string; - test.beforeEach("Setup for offline migration test", async ({ browser }) => { - await createMultipleTestContainers({ accountType: TestAccount.SQLContainerCopyOnly, containerCount: 2 }); +// test.beforeEach("Setup for offline migration test", async ({ browser }) => { +// await createMultipleTestContainers({ accountType: TestAccount.SQLContainerCopyOnly, containerCount: 2 }); - page = await browser.newPage(); - ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); - expectedJobName = `offline_test_job_${Date.now()}`; - targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); - }); +// page = await browser.newPage(); +// ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); +// expectedJobName = `offline_test_job_${Date.now()}`; +// targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); +// }); - test.afterEach("Cleanup after offline migration test", async () => { - await page.unroute(/.*/, (route) => route.continue()); - await page.close(); - }); +// test.afterEach("Cleanup after offline migration test", async () => { +// await page.unroute(/.*/, (route) => route.continue()); +// await page.close(); +// }); - test("Successfully create and manage offline migration copy job", async () => { - expect(wrapper).not.toBeNull(); - await wrapper.locator(".commandBarContainer").waitFor({ state: "visible" }); +// test("Successfully create and manage offline migration copy job", async () => { +// expect(wrapper).not.toBeNull(); +// await wrapper.locator(".commandBarContainer").waitFor({ state: "visible" }); - // Open Create Copy Job panel - const createCopyJobButton = wrapper.getByTestId("CommandBar/Button:Create Copy Job"); - await expect(createCopyJobButton).toBeVisible(); - await createCopyJobButton.click(); - panel = frame.getByTestId("Panel:Create copy job"); - await expect(panel).toBeVisible(); +// // Open Create Copy Job panel +// const createCopyJobButton = wrapper.getByTestId("CommandBar/Button:Create Copy Job"); +// await expect(createCopyJobButton).toBeVisible(); +// await createCopyJobButton.click(); +// panel = frame.getByTestId("Panel:Create copy job"); +// await expect(panel).toBeVisible(); - // Reduced wait time for better performance - await page.waitForTimeout(2000); +// // Reduced wait time for better performance +// await page.waitForTimeout(2000); - // Setup subscription and account - const subscriptionDropdown = panel.getByTestId("subscription-dropdown"); - const expectedAccountName = targetAccountName; - expectedSubscriptionName = await subscriptionDropdown.locator("span.ms-Dropdown-title").innerText(); +// // Setup subscription and account +// const subscriptionDropdown = panel.getByTestId("subscription-dropdown"); +// const expectedAccountName = targetAccountName; +// expectedSubscriptionName = await subscriptionDropdown.locator("span.ms-Dropdown-title").innerText(); - await subscriptionDropdown.click(); - const subscriptionItem = await getDropdownItemByNameOrPosition( - frame, - { name: expectedSubscriptionName }, - { ariaLabel: "Subscription" }, - ); - await subscriptionItem.click(); +// await subscriptionDropdown.click(); +// const subscriptionItem = await getDropdownItemByNameOrPosition( +// frame, +// { name: expectedSubscriptionName }, +// { ariaLabel: "Subscription" }, +// ); +// await subscriptionItem.click(); - // Select account - const accountDropdown = panel.getByTestId("account-dropdown"); - await expect(accountDropdown).toHaveText(new RegExp(expectedAccountName)); - await accountDropdown.click(); +// // Select account +// const accountDropdown = panel.getByTestId("account-dropdown"); +// await expect(accountDropdown).toHaveText(new RegExp(expectedAccountName)); +// await accountDropdown.click(); - const accountItem = await getDropdownItemByNameOrPosition( - frame, - { name: expectedAccountName }, - { ariaLabel: "Account" }, - ); - await accountItem.click(); +// const accountItem = await getDropdownItemByNameOrPosition( +// frame, +// { name: expectedAccountName }, +// { ariaLabel: "Account" }, +// ); +// await accountItem.click(); - // Test offline migration mode toggle functionality - const migrationTypeContainer = panel.getByTestId("migration-type"); +// // Test offline migration mode toggle functionality +// const migrationTypeContainer = panel.getByTestId("migration-type"); - // First test online mode (should show permissions screen) - const onlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Online mode/i }); - await onlineCopyRadioButton.click({ force: true }); - await expect(migrationTypeContainer.getByTestId("migration-type-description-online")).toBeVisible(); +// // First test online mode (should show permissions screen) +// const onlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Online mode/i }); +// await onlineCopyRadioButton.click({ force: true }); +// await expect(migrationTypeContainer.getByTestId("migration-type-description-online")).toBeVisible(); - await panel.getByRole("button", { name: "Next" }).click(); - await expect(panel.getByTestId("Panel:AssignPermissionsContainer")).toBeVisible(); - await expect(panel.getByText("Online container copy", { exact: true })).toBeVisible(); +// await panel.getByRole("button", { name: "Next" }).click(); +// await expect(panel.getByTestId("Panel:AssignPermissionsContainer")).toBeVisible(); +// await expect(panel.getByText("Online container copy", { exact: true })).toBeVisible(); - // Go back and switch to offline mode - await panel.getByRole("button", { name: "Previous" }).click(); +// // Go back and switch to offline mode +// await panel.getByRole("button", { name: "Previous" }).click(); - const offlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Offline mode/i }); - await offlineCopyRadioButton.click({ force: true }); - await expect(migrationTypeContainer.getByTestId("migration-type-description-offline")).toBeVisible(); +// const offlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Offline mode/i }); +// await offlineCopyRadioButton.click({ force: true }); +// await expect(migrationTypeContainer.getByTestId("migration-type-description-offline")).toBeVisible(); - await panel.getByRole("button", { name: "Next" }).click(); +// await panel.getByRole("button", { name: "Next" }).click(); - // Verify we skip permissions screen in offline mode - await expect(panel.getByTestId("Panel:SelectSourceAndTargetContainers")).toBeVisible(); - await expect(panel.getByTestId("Panel:AssignPermissionsContainer")).not.toBeVisible(); +// // Verify we skip permissions screen in offline mode +// await expect(panel.getByTestId("Panel:SelectSourceAndTargetContainers")).toBeVisible(); +// await expect(panel.getByTestId("Panel:AssignPermissionsContainer")).not.toBeVisible(); - // Test source and target container selection with validation - const sourceContainerDropdown = panel.getByTestId("source-containerDropdown"); - expect(sourceContainerDropdown).toBeVisible(); - await expect(sourceContainerDropdown).toHaveClass(/(^|\s)is-disabled(\s|$)/); +// // Test source and target container selection with validation +// const sourceContainerDropdown = panel.getByTestId("source-containerDropdown"); +// expect(sourceContainerDropdown).toBeVisible(); +// await expect(sourceContainerDropdown).toHaveClass(/(^|\s)is-disabled(\s|$)/); - // Select source database first (containers are disabled until database is selected) - const sourceDatabaseDropdown = panel.getByTestId("source-databaseDropdown"); - await sourceDatabaseDropdown.click(); - const sourceDbDropdownItem = await getDropdownItemByNameOrPosition( - frame, - { position: 0 }, - { ariaLabel: "Database" }, - ); - await sourceDbDropdownItem.click(); +// // Select source database first (containers are disabled until database is selected) +// const sourceDatabaseDropdown = panel.getByTestId("source-databaseDropdown"); +// await sourceDatabaseDropdown.click(); +// const sourceDbDropdownItem = await getDropdownItemByNameOrPosition( +// frame, +// { position: 0 }, +// { ariaLabel: "Database" }, +// ); +// await sourceDbDropdownItem.click(); - // Now container dropdown should be enabled - await expect(sourceContainerDropdown).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); - await sourceContainerDropdown.click(); - const sourceContainerDropdownItem = await getDropdownItemByNameOrPosition( - frame, - { position: 0 }, - { ariaLabel: "Container" }, - ); - await sourceContainerDropdownItem.click(); +// // Now container dropdown should be enabled +// await expect(sourceContainerDropdown).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); +// await sourceContainerDropdown.click(); +// const sourceContainerDropdownItem = await getDropdownItemByNameOrPosition( +// frame, +// { position: 0 }, +// { ariaLabel: "Container" }, +// ); +// await sourceContainerDropdownItem.click(); - // Test target container selection - const targetContainerDropdown = panel.getByTestId("target-containerDropdown"); - expect(targetContainerDropdown).toBeVisible(); - await expect(targetContainerDropdown).toHaveClass(/(^|\s)is-disabled(\s|$)/); +// // Test target container selection +// const targetContainerDropdown = panel.getByTestId("target-containerDropdown"); +// expect(targetContainerDropdown).toBeVisible(); +// await expect(targetContainerDropdown).toHaveClass(/(^|\s)is-disabled(\s|$)/); - const targetDatabaseDropdown = panel.getByTestId("target-databaseDropdown"); - await targetDatabaseDropdown.click(); - const targetDbDropdownItem = await getDropdownItemByNameOrPosition( - frame, - { position: 0 }, - { ariaLabel: "Database" }, - ); - await targetDbDropdownItem.click(); +// const targetDatabaseDropdown = panel.getByTestId("target-databaseDropdown"); +// await targetDatabaseDropdown.click(); +// const targetDbDropdownItem = await getDropdownItemByNameOrPosition( +// frame, +// { position: 0 }, +// { ariaLabel: "Database" }, +// ); +// await targetDbDropdownItem.click(); - await expect(targetContainerDropdown).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); - await targetContainerDropdown.click(); +// await expect(targetContainerDropdown).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); +// await targetContainerDropdown.click(); - // First try selecting the same container (should show error) - const targetContainerDropdownItem1 = await getDropdownItemByNameOrPosition( - frame, - { position: 0 }, - { ariaLabel: "Container" }, - ); - await targetContainerDropdownItem1.click(); +// // First try selecting the same container (should show error) +// const targetContainerDropdownItem1 = await getDropdownItemByNameOrPosition( +// frame, +// { position: 0 }, +// { ariaLabel: "Container" }, +// ); +// await targetContainerDropdownItem1.click(); - await panel.getByRole("button", { name: "Next" }).click(); +// await panel.getByRole("button", { name: "Next" }).click(); - // Verify validation error for same source and target containers - const errorContainer = panel.getByTestId("Panel:ErrorContainer"); - await expect(errorContainer).toBeVisible(); - await expect(errorContainer).toHaveText(/Source and destination containers cannot be the same/i); +// // Verify validation error for same source and target containers +// const errorContainer = panel.getByTestId("Panel:ErrorContainer"); +// await expect(errorContainer).toBeVisible(); +// await expect(errorContainer).toHaveText(/Source and destination containers cannot be the same/i); - // Select different target container - await targetContainerDropdown.click(); - const targetContainerDropdownItem2 = await getDropdownItemByNameOrPosition( - frame, - { position: 1 }, - { ariaLabel: "Container" }, - ); - await targetContainerDropdownItem2.click(); +// // Select different target container +// await targetContainerDropdown.click(); +// const targetContainerDropdownItem2 = await getDropdownItemByNameOrPosition( +// frame, +// { position: 1 }, +// { ariaLabel: "Container" }, +// ); +// await targetContainerDropdownItem2.click(); - // Generate expected job name based on selections - const selectedSourceDatabase = await sourceDatabaseDropdown.innerText(); - const selectedSourceContainer = await sourceContainerDropdown.innerText(); - const selectedTargetDatabase = await targetDatabaseDropdown.innerText(); - const selectedTargetContainer = await targetContainerDropdown.innerText(); - expectedCopyJobNameInitial = `${truncateName(selectedSourceDatabase)}.${truncateName( - selectedSourceContainer, - )}_${truncateName(selectedTargetDatabase)}.${truncateName(selectedTargetContainer)}`; +// // Generate expected job name based on selections +// const selectedSourceDatabase = await sourceDatabaseDropdown.innerText(); +// const selectedSourceContainer = await sourceContainerDropdown.innerText(); +// const selectedTargetDatabase = await targetDatabaseDropdown.innerText(); +// const selectedTargetContainer = await targetContainerDropdown.innerText(); +// expectedCopyJobNameInitial = `${truncateName(selectedSourceDatabase)}.${truncateName( +// selectedSourceContainer, +// )}_${truncateName(selectedTargetDatabase)}.${truncateName(selectedTargetContainer)}`; - await panel.getByRole("button", { name: "Next" }).click(); +// await panel.getByRole("button", { name: "Next" }).click(); - // Error should disappear and preview should be visible - await expect(errorContainer).not.toBeVisible(); - await expect(panel.getByTestId("Panel:PreviewCopyJob")).toBeVisible(); +// // Error should disappear and preview should be visible +// await expect(errorContainer).not.toBeVisible(); +// await expect(panel.getByTestId("Panel:PreviewCopyJob")).toBeVisible(); - // Verify job preview details - const previewContainer = panel.getByTestId("Panel:PreviewCopyJob"); - await expect(previewContainer).toBeVisible(); - await expect(previewContainer.getByTestId("source-subscription-name")).toHaveText(expectedSubscriptionName); - await expect(previewContainer.getByTestId("source-account-name")).toHaveText(expectedAccountName); +// // Verify job preview details +// const previewContainer = panel.getByTestId("Panel:PreviewCopyJob"); +// await expect(previewContainer).toBeVisible(); +// await expect(previewContainer.getByTestId("source-subscription-name")).toHaveText(expectedSubscriptionName); +// await expect(previewContainer.getByTestId("source-account-name")).toHaveText(expectedAccountName); - const jobNameInput = previewContainer.getByTestId("job-name-textfield"); - await expect(jobNameInput).toHaveValue(new RegExp(expectedCopyJobNameInitial)); +// const jobNameInput = previewContainer.getByTestId("job-name-textfield"); +// await expect(jobNameInput).toHaveValue(new RegExp(expectedCopyJobNameInitial)); - const primaryBtn = panel.getByRole("button", { name: "Copy", exact: true }); - await expect(primaryBtn).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); +// const primaryBtn = panel.getByRole("button", { name: "Copy", exact: true }); +// await expect(primaryBtn).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); - // Test invalid job name validation (spaces not allowed) - await jobNameInput.fill("test job name"); - await expect(primaryBtn).toHaveClass(/(^|\s)is-disabled(\s|$)/); +// // Test invalid job name validation (spaces not allowed) +// await jobNameInput.fill("test job name"); +// await expect(primaryBtn).toHaveClass(/(^|\s)is-disabled(\s|$)/); - // Test duplicate job name error handling - const duplicateJobName = "test-job-name-1"; - await jobNameInput.fill(duplicateJobName); +// // Test duplicate job name error handling +// const duplicateJobName = "test-job-name-1"; +// await jobNameInput.fill(duplicateJobName); - const copyButton = panel.getByRole("button", { name: "Copy", exact: true }); - const expectedErrorMessage = `Duplicate job name '${duplicateJobName}'`; +// const copyButton = panel.getByRole("button", { name: "Copy", exact: true }); +// const expectedErrorMessage = `Duplicate job name '${duplicateJobName}'`; - await interceptAndInspectApiRequest( - page, - `${expectedAccountName}/dataTransferJobs/${duplicateJobName}`, - "PUT", - new Error(expectedErrorMessage), - (url?: string) => url?.includes(duplicateJobName) ?? false, - ); +// await interceptAndInspectApiRequest( +// page, +// `${expectedAccountName}/dataTransferJobs/${duplicateJobName}`, +// "PUT", +// new Error(expectedErrorMessage), +// (url?: string) => url?.includes(duplicateJobName) ?? false, +// ); - let errorThrown = false; - try { - await copyButton.click(); - await page.waitForTimeout(2000); - } catch (error: any) { - errorThrown = true; - expect(error.message).toContain("not allowed"); - } +// let errorThrown = false; +// try { +// await copyButton.click(); +// await page.waitForTimeout(2000); +// } catch (error: any) { +// errorThrown = true; +// expect(error.message).toContain("not allowed"); +// } - if (!errorThrown) { - const errorContainer = panel.getByTestId("Panel:ErrorContainer"); - await expect(errorContainer).toBeVisible(); - await expect(errorContainer).toHaveText(new RegExp(expectedErrorMessage, "i")); - } +// if (!errorThrown) { +// const errorContainer = panel.getByTestId("Panel:ErrorContainer"); +// await expect(errorContainer).toBeVisible(); +// await expect(errorContainer).toHaveText(new RegExp(expectedErrorMessage, "i")); +// } - await expect(panel).toBeVisible(); +// await expect(panel).toBeVisible(); - // Test successful job creation with valid job name - const validJobName = expectedJobName; +// // Test successful job creation with valid job name +// const validJobName = expectedJobName; - const copyJobCreationPromise = waitForApiResponse( - page, - `${expectedAccountName}/dataTransferJobs/${validJobName}`, - "PUT", - ); +// const copyJobCreationPromise = waitForApiResponse( +// page, +// `${expectedAccountName}/dataTransferJobs/${validJobName}`, +// "PUT", +// ); - await jobNameInput.fill(validJobName); - await expect(copyButton).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); +// await jobNameInput.fill(validJobName); +// await expect(copyButton).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); - await copyButton.click(); +// await copyButton.click(); - const response = await copyJobCreationPromise; - expect(response.ok()).toBe(true); +// const response = await copyJobCreationPromise; +// expect(response.ok()).toBe(true); - // Verify panel closes and job appears in the list - await expect(panel).not.toBeVisible(); +// // Verify panel closes and job appears in the list +// await expect(panel).not.toBeVisible(); - const filterTextField = wrapper.getByTestId("CopyJobsList/FilterTextField"); - await filterTextField.waitFor({ state: "visible" }); - await filterTextField.fill(validJobName); +// const filterTextField = wrapper.getByTestId("CopyJobsList/FilterTextField"); +// await filterTextField.waitFor({ state: "visible" }); +// await filterTextField.fill(validJobName); - const jobsListContainer = wrapper.locator(".CopyJobListContainer .ms-DetailsList-contentWrapper .ms-List-page"); - await jobsListContainer.waitFor({ state: "visible" }); +// const jobsListContainer = wrapper.locator(".CopyJobListContainer .ms-DetailsList-contentWrapper .ms-List-page"); +// await jobsListContainer.waitFor({ state: "visible" }); - const jobItem = jobsListContainer.getByText(validJobName); - await jobItem.waitFor({ state: "visible" }); - await expect(jobItem).toBeVisible(); - }); -}); +// const jobItem = jobsListContainer.getByText(validJobName); +// await jobItem.waitFor({ state: "visible" }); +// await expect(jobItem).toBeVisible(); +// }); +// }); diff --git a/test/sql/containercopy/onlineMigration.spec.ts b/test/sql/containercopy/onlineMigration.spec.ts index e11b3decd..6570799b9 100644 --- a/test/sql/containercopy/onlineMigration.spec.ts +++ b/test/sql/containercopy/onlineMigration.spec.ts @@ -1,189 +1,189 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { expect, Frame, Locator, Page, test } from "@playwright/test"; -import { - ContainerCopy, - getAccountName, - getDropdownItemByNameOrPosition, - TestAccount, - waitForApiResponse, -} from "../../fx"; -import { createMultipleTestContainers } from "../../testData"; +// /* eslint-disable @typescript-eslint/no-explicit-any */ +// import { expect, Frame, Locator, Page, test } from "@playwright/test"; +// import { +// ContainerCopy, +// getAccountName, +// getDropdownItemByNameOrPosition, +// TestAccount, +// waitForApiResponse, +// } from "../../fx"; +// import { createMultipleTestContainers } from "../../testData"; -test.describe("Container Copy - Online Migration", () => { - let page: Page; - let wrapper: Locator; - let panel: Locator; - let frame: Frame; - let targetAccountName: string; +// test.describe("Container Copy - Online Migration", () => { +// let page: Page; +// let wrapper: Locator; +// let panel: Locator; +// let frame: Frame; +// let targetAccountName: string; - test.beforeEach("Setup for online migration test", async ({ browser }) => { - await createMultipleTestContainers({ accountType: TestAccount.SQLContainerCopyOnly, containerCount: 2 }); +// test.beforeEach("Setup for online migration test", async ({ browser }) => { +// await createMultipleTestContainers({ accountType: TestAccount.SQLContainerCopyOnly, containerCount: 2 }); - page = await browser.newPage(); - ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); - targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); - }); +// page = await browser.newPage(); +// ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); +// targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); +// }); - test.afterEach("Cleanup after online migration test", async () => { - await page.unroute(/.*/, (route) => route.continue()); - await page.close(); - }); +// test.afterEach("Cleanup after online migration test", async () => { +// await page.unroute(/.*/, (route) => route.continue()); +// await page.close(); +// }); - test("Successfully create and manage online migration copy job", async () => { - expect(wrapper).not.toBeNull(); - await wrapper.locator(".commandBarContainer").waitFor({ state: "visible" }); +// test("Successfully create and manage online migration copy job", async () => { +// expect(wrapper).not.toBeNull(); +// await wrapper.locator(".commandBarContainer").waitFor({ state: "visible" }); - // Open Create Copy Job panel - const createCopyJobButton = wrapper.getByTestId("CommandBar/Button:Create Copy Job"); - await expect(createCopyJobButton).toBeVisible(); - await createCopyJobButton.click(); - panel = frame.getByTestId("Panel:Create copy job"); - await expect(panel).toBeVisible(); +// // Open Create Copy Job panel +// const createCopyJobButton = wrapper.getByTestId("CommandBar/Button:Create Copy Job"); +// await expect(createCopyJobButton).toBeVisible(); +// await createCopyJobButton.click(); +// panel = frame.getByTestId("Panel:Create copy job"); +// await expect(panel).toBeVisible(); - // Reduced wait time for better performance - await page.waitForTimeout(1000); +// // Reduced wait time for better performance +// await page.waitForTimeout(1000); - // Enable online migration mode - const migrationTypeContainer = panel.getByTestId("migration-type"); - const onlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Online mode/i }); - await onlineCopyRadioButton.click({ force: true }); +// // Enable online migration mode +// const migrationTypeContainer = panel.getByTestId("migration-type"); +// const onlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Online mode/i }); +// await onlineCopyRadioButton.click({ force: true }); - await expect(migrationTypeContainer.getByTestId("migration-type-description-online")).toBeVisible(); +// await expect(migrationTypeContainer.getByTestId("migration-type-description-online")).toBeVisible(); - await panel.getByRole("button", { name: "Next" }).click(); +// await panel.getByRole("button", { name: "Next" }).click(); - // Verify permissions screen is shown for online migration - const permissionScreen = panel.getByTestId("Panel:AssignPermissionsContainer"); - await expect(permissionScreen).toBeVisible(); - await expect(permissionScreen.getByText("Online container copy", { exact: true })).toBeVisible(); +// // Verify permissions screen is shown for online migration +// const permissionScreen = panel.getByTestId("Panel:AssignPermissionsContainer"); +// await expect(permissionScreen).toBeVisible(); +// await expect(permissionScreen.getByText("Online container copy", { exact: true })).toBeVisible(); - // Skip permissions setup and proceed to container selection - await panel.getByRole("button", { name: "Next" }).click(); +// // Skip permissions setup and proceed to container selection +// await panel.getByRole("button", { name: "Next" }).click(); - // Configure source and target containers for online migration - const sourceDatabaseDropdown = panel.getByTestId("source-databaseDropdown"); - await sourceDatabaseDropdown.click(); - const sourceDbDropdownItem = await getDropdownItemByNameOrPosition( - frame, - { position: 0 }, - { ariaLabel: "Database" }, - ); - await sourceDbDropdownItem.click(); +// // Configure source and target containers for online migration +// const sourceDatabaseDropdown = panel.getByTestId("source-databaseDropdown"); +// await sourceDatabaseDropdown.click(); +// const sourceDbDropdownItem = await getDropdownItemByNameOrPosition( +// frame, +// { position: 0 }, +// { ariaLabel: "Database" }, +// ); +// await sourceDbDropdownItem.click(); - const sourceContainerDropdown = panel.getByTestId("source-containerDropdown"); - await sourceContainerDropdown.click(); - const sourceContainerDropdownItem = await getDropdownItemByNameOrPosition( - frame, - { position: 0 }, - { ariaLabel: "Container" }, - ); - await sourceContainerDropdownItem.click(); +// const sourceContainerDropdown = panel.getByTestId("source-containerDropdown"); +// await sourceContainerDropdown.click(); +// const sourceContainerDropdownItem = await getDropdownItemByNameOrPosition( +// frame, +// { position: 0 }, +// { ariaLabel: "Container" }, +// ); +// await sourceContainerDropdownItem.click(); - const targetDatabaseDropdown = panel.getByTestId("target-databaseDropdown"); - await targetDatabaseDropdown.click(); - const targetDbDropdownItem = await getDropdownItemByNameOrPosition( - frame, - { position: 0 }, - { ariaLabel: "Database" }, - ); - await targetDbDropdownItem.click(); +// const targetDatabaseDropdown = panel.getByTestId("target-databaseDropdown"); +// await targetDatabaseDropdown.click(); +// const targetDbDropdownItem = await getDropdownItemByNameOrPosition( +// frame, +// { position: 0 }, +// { ariaLabel: "Database" }, +// ); +// await targetDbDropdownItem.click(); - const targetContainerDropdown = panel.getByTestId("target-containerDropdown"); - await targetContainerDropdown.click(); - const targetContainerDropdownItem = await getDropdownItemByNameOrPosition( - frame, - { position: 1 }, - { ariaLabel: "Container" }, - ); - await targetContainerDropdownItem.click(); +// const targetContainerDropdown = panel.getByTestId("target-containerDropdown"); +// await targetContainerDropdown.click(); +// const targetContainerDropdownItem = await getDropdownItemByNameOrPosition( +// frame, +// { position: 1 }, +// { ariaLabel: "Container" }, +// ); +// await targetContainerDropdownItem.click(); - await panel.getByRole("button", { name: "Next" }).click(); +// await panel.getByRole("button", { name: "Next" }).click(); - // Verify job preview and create the online migration job - const previewContainer = panel.getByTestId("Panel:PreviewCopyJob"); - await expect(previewContainer.getByTestId("source-account-name")).toHaveText(targetAccountName); +// // Verify job preview and create the online migration job +// const previewContainer = panel.getByTestId("Panel:PreviewCopyJob"); +// await expect(previewContainer.getByTestId("source-account-name")).toHaveText(targetAccountName); - const jobNameInput = previewContainer.getByTestId("job-name-textfield"); - const onlineMigrationJobName = await jobNameInput.inputValue(); +// const jobNameInput = previewContainer.getByTestId("job-name-textfield"); +// const onlineMigrationJobName = await jobNameInput.inputValue(); - const copyButton = panel.getByRole("button", { name: "Copy", exact: true }); +// const copyButton = panel.getByRole("button", { name: "Copy", exact: true }); - const copyJobCreationPromise = waitForApiResponse( - page, - `${targetAccountName}/dataTransferJobs/${onlineMigrationJobName}`, - "PUT", - ); - await copyButton.click(); - await page.waitForTimeout(1000); // Reduced wait time +// const copyJobCreationPromise = waitForApiResponse( +// page, +// `${targetAccountName}/dataTransferJobs/${onlineMigrationJobName}`, +// "PUT", +// ); +// await copyButton.click(); +// await page.waitForTimeout(1000); // Reduced wait time - const response = await copyJobCreationPromise; - expect(response.ok()).toBe(true); +// const response = await copyJobCreationPromise; +// expect(response.ok()).toBe(true); - // Verify panel closes and job appears in the list - await expect(panel).not.toBeVisible(); +// // Verify panel closes and job appears in the list +// await expect(panel).not.toBeVisible(); - const filterTextField = wrapper.getByTestId("CopyJobsList/FilterTextField"); - await filterTextField.waitFor({ state: "visible" }); - await filterTextField.fill(onlineMigrationJobName); +// const filterTextField = wrapper.getByTestId("CopyJobsList/FilterTextField"); +// await filterTextField.waitFor({ state: "visible" }); +// await filterTextField.fill(onlineMigrationJobName); - const jobsListContainer = wrapper.locator(".CopyJobListContainer .ms-DetailsList-contentWrapper .ms-List-page"); - await jobsListContainer.waitFor({ state: "visible" }); +// const jobsListContainer = wrapper.locator(".CopyJobListContainer .ms-DetailsList-contentWrapper .ms-List-page"); +// await jobsListContainer.waitFor({ state: "visible" }); - let jobRow, statusCell, actionMenuButton; - jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); - statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); - await jobRow.waitFor({ state: "visible" }); +// let jobRow, statusCell, actionMenuButton; +// jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); +// statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); +// await jobRow.waitFor({ state: "visible" }); - // Verify job status changes to queued state - await expect(statusCell).toContainText(/running|queued|pending/i); +// // Verify job status changes to queued state +// await expect(statusCell).toContainText(/running|queued|pending/i); - // Test job lifecycle management through action menu - actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); - await actionMenuButton.click(); +// // Test job lifecycle management through action menu +// actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); +// await actionMenuButton.click(); - // Test pause functionality - const pauseAction = frame.locator(".ms-ContextualMenu-list button:has-text('Pause')"); - await pauseAction.click(); +// // Test pause functionality +// const pauseAction = frame.locator(".ms-ContextualMenu-list button:has-text('Pause')"); +// await pauseAction.click(); - const pauseResponse = await waitForApiResponse( - page, - `${targetAccountName}/dataTransferJobs/${onlineMigrationJobName}/pause`, - "POST", - ); - expect(pauseResponse.ok()).toBe(true); +// const pauseResponse = await waitForApiResponse( +// page, +// `${targetAccountName}/dataTransferJobs/${onlineMigrationJobName}/pause`, +// "POST", +// ); +// expect(pauseResponse.ok()).toBe(true); - // Verify job status changes to paused - jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); - await jobRow.waitFor({ state: "visible", timeout: 5000 }); - statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); - await expect(statusCell).toContainText(/paused/i, { timeout: 5000 }); - await page.waitForTimeout(1000); +// // Verify job status changes to paused +// jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); +// await jobRow.waitFor({ state: "visible", timeout: 5000 }); +// statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); +// await expect(statusCell).toContainText(/paused/i, { timeout: 5000 }); +// await page.waitForTimeout(1000); - // Test cancel job functionality - actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); - await actionMenuButton.click(); - await frame.locator(".ms-ContextualMenu-list button:has-text('Cancel')").click(); +// // Test cancel job functionality +// actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); +// await actionMenuButton.click(); +// await frame.locator(".ms-ContextualMenu-list button:has-text('Cancel')").click(); - // Verify cancellation confirmation dialog - await expect(frame.locator(".ms-Dialog-main")).toBeVisible({ timeout: 2000 }); - await expect(frame.locator(".ms-Dialog-main")).toContainText(onlineMigrationJobName); +// // Verify cancellation confirmation dialog +// await expect(frame.locator(".ms-Dialog-main")).toBeVisible({ timeout: 2000 }); +// await expect(frame.locator(".ms-Dialog-main")).toContainText(onlineMigrationJobName); - const cancelDialogButton = frame.locator(".ms-Dialog-main").getByTestId("DialogButton:Cancel"); - await expect(cancelDialogButton).toBeVisible(); - await cancelDialogButton.click(); - await expect(frame.locator(".ms-Dialog-main")).not.toBeVisible(); +// const cancelDialogButton = frame.locator(".ms-Dialog-main").getByTestId("DialogButton:Cancel"); +// await expect(cancelDialogButton).toBeVisible(); +// await cancelDialogButton.click(); +// await expect(frame.locator(".ms-Dialog-main")).not.toBeVisible(); - actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); - await actionMenuButton.click(); - await frame.locator(".ms-ContextualMenu-list button:has-text('Cancel')").click(); +// actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); +// await actionMenuButton.click(); +// await frame.locator(".ms-ContextualMenu-list button:has-text('Cancel')").click(); - const confirmDialogButton = frame.locator(".ms-Dialog-main").getByTestId("DialogButton:Confirm"); - await expect(confirmDialogButton).toBeVisible(); - await confirmDialogButton.click(); +// const confirmDialogButton = frame.locator(".ms-Dialog-main").getByTestId("DialogButton:Confirm"); +// await expect(confirmDialogButton).toBeVisible(); +// await confirmDialogButton.click(); - // Verify final job status is cancelled - jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); - statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); - await expect(statusCell).toContainText(/cancelled/i, { timeout: 5000 }); - }); -}); +// // Verify final job status is cancelled +// jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); +// statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); +// await expect(statusCell).toContainText(/cancelled/i, { timeout: 5000 }); +// }); +// }); From 7eecfa28c5e19ce66db6419f86b6d3548447f9da Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Fri, 23 Jan 2026 13:25:35 -0800 Subject: [PATCH 14/19] wait for results to attach --- test/mongo/document.spec.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/mongo/document.spec.ts b/test/mongo/document.spec.ts index 956eb747f..9643ca868 100644 --- a/test/mongo/document.spec.ts +++ b/test/mongo/document.spec.ts @@ -56,7 +56,8 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { await expect(span).toBeVisible(); await span.click(); - await page.waitForTimeout(5000); // wait for 5 seconds to ensure document is fully loaded + await expect(documentsTab.resultsEditor.locator).toBeAttached({ timeout: 60 * 1000 }); + // await page.waitForTimeout(5000); // wait for 5 seconds to ensure document is fully loaded. waitforTimeout is not recommended generally but here we are working around flakiness in the test env let newDocumentId; let retryCount = 0; await retry(async () => { From ea7f2d513fbca36a0328343345dd2662b894f155 Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Fri, 23 Jan 2026 13:37:53 -0800 Subject: [PATCH 15/19] do forced wait instead --- test/mongo/document.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/mongo/document.spec.ts b/test/mongo/document.spec.ts index 9643ca868..77d477404 100644 --- a/test/mongo/document.spec.ts +++ b/test/mongo/document.spec.ts @@ -56,8 +56,8 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { await expect(span).toBeVisible(); await span.click(); - await expect(documentsTab.resultsEditor.locator).toBeAttached({ timeout: 60 * 1000 }); - // await page.waitForTimeout(5000); // wait for 5 seconds to ensure document is fully loaded. waitforTimeout is not recommended generally but here we are working around flakiness in the test env + // await expect(documentsTab.resultsEditor.locator).toBeAttached({ timeout: 60 * 1000 }); + await page.waitForTimeout(5000); // wait for 5 seconds to ensure document is fully loaded. waitforTimeout is not recommended generally but here we are working around flakiness in the test env let newDocumentId; let retryCount = 0; await retry(async () => { From 0fbf8b6a2ff2ea048bf80e88c8272a9be078bfec Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Fri, 23 Jan 2026 13:52:18 -0800 Subject: [PATCH 16/19] cleanup tests --- test/fx.ts | 12 ---------- test/mongo/document.spec.ts | 44 +++++++++++++------------------------ 2 files changed, 15 insertions(+), 41 deletions(-) diff --git a/test/fx.ts b/test/fx.ts index 19e61e355..f9313b6ca 100644 --- a/test/fx.ts +++ b/test/fx.ts @@ -63,9 +63,6 @@ export const TEST_MANUAL_THROUGHPUT_RU_2K = 2000; export const ONE_MINUTE_MS: number = 60 * 1000; function tryGetStandardName(accountType: TestAccount) { - // if (accountType === TestAccount.MongoReadonly) { - // return "aisayas-e2e-mongo-readonly"; - // } if (process.env.DE_TEST_ACCOUNT_PREFIX) { const actualPrefix = process.env.DE_TEST_ACCOUNT_PREFIX.endsWith("-") ? process.env.DE_TEST_ACCOUNT_PREFIX @@ -520,15 +517,6 @@ export class DataExplorer { const containerNode = await this.waitForContainerNode(context.database.id, context.container.id); await containerNode.expand(); - // // refresh tree to remove deleted database - // const consoleMessages = await this.getNotificationConsoleMessages(); - // const refreshButton = this.frame.getByTestId("Sidebar/RefreshButton"); - // await refreshButton.click(); - // await expect(consoleMessages).toContainText("Successfully refreshed databases", { - // timeout: ONE_MINUTE_MS, - // }); - // await this.collapseNotificationConsole(); - const scaleAndSettingsButton = this.frame.getByTestId( `TreeNode:${context.database.id}/${context.container.id}/Scale & Settings`, ); diff --git a/test/mongo/document.spec.ts b/test/mongo/document.spec.ts index 77d477404..cf98ebcc7 100644 --- a/test/mongo/document.spec.ts +++ b/test/mongo/document.spec.ts @@ -26,8 +26,6 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { await documentsTab.documentsFilter.waitFor(); await documentsTab.documentsListPane.waitFor(); await expect(documentsTab.resultsEditor.locator).toBeAttached({ timeout: 60 * 1000 }); - - await explorer.expandNotificationConsole(); }); test.afterEach(async ({ page }) => { await page.unrouteAll({ behavior: "ignoreErrors" }); @@ -56,40 +54,28 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { await expect(span).toBeVisible(); await span.click(); - // await expect(documentsTab.resultsEditor.locator).toBeAttached({ timeout: 60 * 1000 }); await page.waitForTimeout(5000); // wait for 5 seconds to ensure document is fully loaded. waitforTimeout is not recommended generally but here we are working around flakiness in the test env + let newDocumentId; - let retryCount = 0; await retry(async () => { - try { - const newDocumentButton = await explorer.waitForCommandBarButton(CommandBarButton.NewDocument, 5000); - await expect(newDocumentButton).toBeVisible(); - await expect(newDocumentButton).toBeEnabled(); - await newDocumentButton.click(); - console.log(`DEBUG: Clicked New Document button - retryCount=${retryCount}`); - await expect(documentsTab.resultsEditor.locator).toBeAttached({ timeout: 60 * 1000 }); + const newDocumentButton = await explorer.waitForCommandBarButton(CommandBarButton.NewDocument, 5000); + await expect(newDocumentButton).toBeVisible(); + await expect(newDocumentButton).toBeEnabled(); + await newDocumentButton.click(); + await expect(documentsTab.resultsEditor.locator).toBeAttached({ timeout: 60 * 1000 }); - newDocumentId = `${Date.now().toString()}-delete`; + newDocumentId = `${Date.now().toString()}-delete`; - const newDocument = { - _id: newDocumentId, - ...setPartitionKeys(partitionKeys || []), - }; + const newDocument = { + _id: newDocumentId, + ...setPartitionKeys(partitionKeys || []), + }; - await documentsTab.resultsEditor.setText(JSON.stringify(newDocument)); - const saveButton = await explorer.waitForCommandBarButton(CommandBarButton.Save, 5000); - await saveButton.click({ timeout: 5000 }); - console.log(`DEBUG: Clicked Save button - retryCount=${retryCount}`); + await documentsTab.resultsEditor.setText(JSON.stringify(newDocument)); + const saveButton = await explorer.waitForCommandBarButton(CommandBarButton.Save, 5000); + await saveButton.click({ timeout: 5000 }); - await expect(saveButton).toBeHidden({ timeout: 5000 }); - } catch (err) { - retryCount++; - console.warn( - `DEBUG: Attempt ${retryCount} to create new document from ${docId} failed: ${(err as Error).message}`, - ); - - throw err; - } + await expect(saveButton).toBeHidden({ timeout: 5000 }); }, 3); await documentsTab.setFilter(`{_id: "${newDocumentId}"}`); From 3acaf560fdc3be0c9289856cde0795aef9c774b1 Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Fri, 23 Jan 2026 13:53:12 -0800 Subject: [PATCH 17/19] uncomment container copy tests --- .../containercopy/offlineMigration.spec.ts | 424 +++++++++--------- .../sql/containercopy/onlineMigration.spec.ts | 304 ++++++------- 2 files changed, 364 insertions(+), 364 deletions(-) diff --git a/test/sql/containercopy/offlineMigration.spec.ts b/test/sql/containercopy/offlineMigration.spec.ts index 6d11a69f5..e99610cb4 100644 --- a/test/sql/containercopy/offlineMigration.spec.ts +++ b/test/sql/containercopy/offlineMigration.spec.ts @@ -1,262 +1,262 @@ -// /* eslint-disable @typescript-eslint/no-explicit-any */ -// import { expect, Frame, Locator, Page, test } from "@playwright/test"; -// import { truncateName } from "../../../src/Explorer/ContainerCopy/CopyJobUtils"; -// import { -// ContainerCopy, -// getAccountName, -// getDropdownItemByNameOrPosition, -// interceptAndInspectApiRequest, -// TestAccount, -// waitForApiResponse, -// } from "../../fx"; -// import { createMultipleTestContainers } from "../../testData"; +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { expect, Frame, Locator, Page, test } from "@playwright/test"; +import { truncateName } from "../../../src/Explorer/ContainerCopy/CopyJobUtils"; +import { + ContainerCopy, + getAccountName, + getDropdownItemByNameOrPosition, + interceptAndInspectApiRequest, + TestAccount, + waitForApiResponse, +} from "../../fx"; +import { createMultipleTestContainers } from "../../testData"; -// test.describe("Container Copy - Offline Migration", () => { -// let page: Page; -// let wrapper: Locator; -// let panel: Locator; -// let frame: Frame; -// let expectedJobName: string; -// let targetAccountName: string; -// let expectedSubscriptionName: string; -// let expectedCopyJobNameInitial: string; +test.describe("Container Copy - Offline Migration", () => { + let page: Page; + let wrapper: Locator; + let panel: Locator; + let frame: Frame; + let expectedJobName: string; + let targetAccountName: string; + let expectedSubscriptionName: string; + let expectedCopyJobNameInitial: string; -// test.beforeEach("Setup for offline migration test", async ({ browser }) => { -// await createMultipleTestContainers({ accountType: TestAccount.SQLContainerCopyOnly, containerCount: 2 }); + test.beforeEach("Setup for offline migration test", async ({ browser }) => { + await createMultipleTestContainers({ accountType: TestAccount.SQLContainerCopyOnly, containerCount: 2 }); -// page = await browser.newPage(); -// ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); -// expectedJobName = `offline_test_job_${Date.now()}`; -// targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); -// }); + page = await browser.newPage(); + ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); + expectedJobName = `offline_test_job_${Date.now()}`; + targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); + }); -// test.afterEach("Cleanup after offline migration test", async () => { -// await page.unroute(/.*/, (route) => route.continue()); -// await page.close(); -// }); + test.afterEach("Cleanup after offline migration test", async () => { + await page.unroute(/.*/, (route) => route.continue()); + await page.close(); + }); -// test("Successfully create and manage offline migration copy job", async () => { -// expect(wrapper).not.toBeNull(); -// await wrapper.locator(".commandBarContainer").waitFor({ state: "visible" }); + test("Successfully create and manage offline migration copy job", async () => { + expect(wrapper).not.toBeNull(); + await wrapper.locator(".commandBarContainer").waitFor({ state: "visible" }); -// // Open Create Copy Job panel -// const createCopyJobButton = wrapper.getByTestId("CommandBar/Button:Create Copy Job"); -// await expect(createCopyJobButton).toBeVisible(); -// await createCopyJobButton.click(); -// panel = frame.getByTestId("Panel:Create copy job"); -// await expect(panel).toBeVisible(); + // Open Create Copy Job panel + const createCopyJobButton = wrapper.getByTestId("CommandBar/Button:Create Copy Job"); + await expect(createCopyJobButton).toBeVisible(); + await createCopyJobButton.click(); + panel = frame.getByTestId("Panel:Create copy job"); + await expect(panel).toBeVisible(); -// // Reduced wait time for better performance -// await page.waitForTimeout(2000); + // Reduced wait time for better performance + await page.waitForTimeout(2000); -// // Setup subscription and account -// const subscriptionDropdown = panel.getByTestId("subscription-dropdown"); -// const expectedAccountName = targetAccountName; -// expectedSubscriptionName = await subscriptionDropdown.locator("span.ms-Dropdown-title").innerText(); + // Setup subscription and account + const subscriptionDropdown = panel.getByTestId("subscription-dropdown"); + const expectedAccountName = targetAccountName; + expectedSubscriptionName = await subscriptionDropdown.locator("span.ms-Dropdown-title").innerText(); -// await subscriptionDropdown.click(); -// const subscriptionItem = await getDropdownItemByNameOrPosition( -// frame, -// { name: expectedSubscriptionName }, -// { ariaLabel: "Subscription" }, -// ); -// await subscriptionItem.click(); + await subscriptionDropdown.click(); + const subscriptionItem = await getDropdownItemByNameOrPosition( + frame, + { name: expectedSubscriptionName }, + { ariaLabel: "Subscription" }, + ); + await subscriptionItem.click(); -// // Select account -// const accountDropdown = panel.getByTestId("account-dropdown"); -// await expect(accountDropdown).toHaveText(new RegExp(expectedAccountName)); -// await accountDropdown.click(); + // Select account + const accountDropdown = panel.getByTestId("account-dropdown"); + await expect(accountDropdown).toHaveText(new RegExp(expectedAccountName)); + await accountDropdown.click(); -// const accountItem = await getDropdownItemByNameOrPosition( -// frame, -// { name: expectedAccountName }, -// { ariaLabel: "Account" }, -// ); -// await accountItem.click(); + const accountItem = await getDropdownItemByNameOrPosition( + frame, + { name: expectedAccountName }, + { ariaLabel: "Account" }, + ); + await accountItem.click(); -// // Test offline migration mode toggle functionality -// const migrationTypeContainer = panel.getByTestId("migration-type"); + // Test offline migration mode toggle functionality + const migrationTypeContainer = panel.getByTestId("migration-type"); -// // First test online mode (should show permissions screen) -// const onlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Online mode/i }); -// await onlineCopyRadioButton.click({ force: true }); -// await expect(migrationTypeContainer.getByTestId("migration-type-description-online")).toBeVisible(); + // First test online mode (should show permissions screen) + const onlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Online mode/i }); + await onlineCopyRadioButton.click({ force: true }); + await expect(migrationTypeContainer.getByTestId("migration-type-description-online")).toBeVisible(); -// await panel.getByRole("button", { name: "Next" }).click(); -// await expect(panel.getByTestId("Panel:AssignPermissionsContainer")).toBeVisible(); -// await expect(panel.getByText("Online container copy", { exact: true })).toBeVisible(); + await panel.getByRole("button", { name: "Next" }).click(); + await expect(panel.getByTestId("Panel:AssignPermissionsContainer")).toBeVisible(); + await expect(panel.getByText("Online container copy", { exact: true })).toBeVisible(); -// // Go back and switch to offline mode -// await panel.getByRole("button", { name: "Previous" }).click(); + // Go back and switch to offline mode + await panel.getByRole("button", { name: "Previous" }).click(); -// const offlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Offline mode/i }); -// await offlineCopyRadioButton.click({ force: true }); -// await expect(migrationTypeContainer.getByTestId("migration-type-description-offline")).toBeVisible(); + const offlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Offline mode/i }); + await offlineCopyRadioButton.click({ force: true }); + await expect(migrationTypeContainer.getByTestId("migration-type-description-offline")).toBeVisible(); -// await panel.getByRole("button", { name: "Next" }).click(); + await panel.getByRole("button", { name: "Next" }).click(); -// // Verify we skip permissions screen in offline mode -// await expect(panel.getByTestId("Panel:SelectSourceAndTargetContainers")).toBeVisible(); -// await expect(panel.getByTestId("Panel:AssignPermissionsContainer")).not.toBeVisible(); + // Verify we skip permissions screen in offline mode + await expect(panel.getByTestId("Panel:SelectSourceAndTargetContainers")).toBeVisible(); + await expect(panel.getByTestId("Panel:AssignPermissionsContainer")).not.toBeVisible(); -// // Test source and target container selection with validation -// const sourceContainerDropdown = panel.getByTestId("source-containerDropdown"); -// expect(sourceContainerDropdown).toBeVisible(); -// await expect(sourceContainerDropdown).toHaveClass(/(^|\s)is-disabled(\s|$)/); + // Test source and target container selection with validation + const sourceContainerDropdown = panel.getByTestId("source-containerDropdown"); + expect(sourceContainerDropdown).toBeVisible(); + await expect(sourceContainerDropdown).toHaveClass(/(^|\s)is-disabled(\s|$)/); -// // Select source database first (containers are disabled until database is selected) -// const sourceDatabaseDropdown = panel.getByTestId("source-databaseDropdown"); -// await sourceDatabaseDropdown.click(); -// const sourceDbDropdownItem = await getDropdownItemByNameOrPosition( -// frame, -// { position: 0 }, -// { ariaLabel: "Database" }, -// ); -// await sourceDbDropdownItem.click(); + // Select source database first (containers are disabled until database is selected) + const sourceDatabaseDropdown = panel.getByTestId("source-databaseDropdown"); + await sourceDatabaseDropdown.click(); + const sourceDbDropdownItem = await getDropdownItemByNameOrPosition( + frame, + { position: 0 }, + { ariaLabel: "Database" }, + ); + await sourceDbDropdownItem.click(); -// // Now container dropdown should be enabled -// await expect(sourceContainerDropdown).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); -// await sourceContainerDropdown.click(); -// const sourceContainerDropdownItem = await getDropdownItemByNameOrPosition( -// frame, -// { position: 0 }, -// { ariaLabel: "Container" }, -// ); -// await sourceContainerDropdownItem.click(); + // Now container dropdown should be enabled + await expect(sourceContainerDropdown).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); + await sourceContainerDropdown.click(); + const sourceContainerDropdownItem = await getDropdownItemByNameOrPosition( + frame, + { position: 0 }, + { ariaLabel: "Container" }, + ); + await sourceContainerDropdownItem.click(); -// // Test target container selection -// const targetContainerDropdown = panel.getByTestId("target-containerDropdown"); -// expect(targetContainerDropdown).toBeVisible(); -// await expect(targetContainerDropdown).toHaveClass(/(^|\s)is-disabled(\s|$)/); + // Test target container selection + const targetContainerDropdown = panel.getByTestId("target-containerDropdown"); + expect(targetContainerDropdown).toBeVisible(); + await expect(targetContainerDropdown).toHaveClass(/(^|\s)is-disabled(\s|$)/); -// const targetDatabaseDropdown = panel.getByTestId("target-databaseDropdown"); -// await targetDatabaseDropdown.click(); -// const targetDbDropdownItem = await getDropdownItemByNameOrPosition( -// frame, -// { position: 0 }, -// { ariaLabel: "Database" }, -// ); -// await targetDbDropdownItem.click(); + const targetDatabaseDropdown = panel.getByTestId("target-databaseDropdown"); + await targetDatabaseDropdown.click(); + const targetDbDropdownItem = await getDropdownItemByNameOrPosition( + frame, + { position: 0 }, + { ariaLabel: "Database" }, + ); + await targetDbDropdownItem.click(); -// await expect(targetContainerDropdown).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); -// await targetContainerDropdown.click(); + await expect(targetContainerDropdown).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); + await targetContainerDropdown.click(); -// // First try selecting the same container (should show error) -// const targetContainerDropdownItem1 = await getDropdownItemByNameOrPosition( -// frame, -// { position: 0 }, -// { ariaLabel: "Container" }, -// ); -// await targetContainerDropdownItem1.click(); + // First try selecting the same container (should show error) + const targetContainerDropdownItem1 = await getDropdownItemByNameOrPosition( + frame, + { position: 0 }, + { ariaLabel: "Container" }, + ); + await targetContainerDropdownItem1.click(); -// await panel.getByRole("button", { name: "Next" }).click(); + await panel.getByRole("button", { name: "Next" }).click(); -// // Verify validation error for same source and target containers -// const errorContainer = panel.getByTestId("Panel:ErrorContainer"); -// await expect(errorContainer).toBeVisible(); -// await expect(errorContainer).toHaveText(/Source and destination containers cannot be the same/i); + // Verify validation error for same source and target containers + const errorContainer = panel.getByTestId("Panel:ErrorContainer"); + await expect(errorContainer).toBeVisible(); + await expect(errorContainer).toHaveText(/Source and destination containers cannot be the same/i); -// // Select different target container -// await targetContainerDropdown.click(); -// const targetContainerDropdownItem2 = await getDropdownItemByNameOrPosition( -// frame, -// { position: 1 }, -// { ariaLabel: "Container" }, -// ); -// await targetContainerDropdownItem2.click(); + // Select different target container + await targetContainerDropdown.click(); + const targetContainerDropdownItem2 = await getDropdownItemByNameOrPosition( + frame, + { position: 1 }, + { ariaLabel: "Container" }, + ); + await targetContainerDropdownItem2.click(); -// // Generate expected job name based on selections -// const selectedSourceDatabase = await sourceDatabaseDropdown.innerText(); -// const selectedSourceContainer = await sourceContainerDropdown.innerText(); -// const selectedTargetDatabase = await targetDatabaseDropdown.innerText(); -// const selectedTargetContainer = await targetContainerDropdown.innerText(); -// expectedCopyJobNameInitial = `${truncateName(selectedSourceDatabase)}.${truncateName( -// selectedSourceContainer, -// )}_${truncateName(selectedTargetDatabase)}.${truncateName(selectedTargetContainer)}`; + // Generate expected job name based on selections + const selectedSourceDatabase = await sourceDatabaseDropdown.innerText(); + const selectedSourceContainer = await sourceContainerDropdown.innerText(); + const selectedTargetDatabase = await targetDatabaseDropdown.innerText(); + const selectedTargetContainer = await targetContainerDropdown.innerText(); + expectedCopyJobNameInitial = `${truncateName(selectedSourceDatabase)}.${truncateName( + selectedSourceContainer, + )}_${truncateName(selectedTargetDatabase)}.${truncateName(selectedTargetContainer)}`; -// await panel.getByRole("button", { name: "Next" }).click(); + await panel.getByRole("button", { name: "Next" }).click(); -// // Error should disappear and preview should be visible -// await expect(errorContainer).not.toBeVisible(); -// await expect(panel.getByTestId("Panel:PreviewCopyJob")).toBeVisible(); + // Error should disappear and preview should be visible + await expect(errorContainer).not.toBeVisible(); + await expect(panel.getByTestId("Panel:PreviewCopyJob")).toBeVisible(); -// // Verify job preview details -// const previewContainer = panel.getByTestId("Panel:PreviewCopyJob"); -// await expect(previewContainer).toBeVisible(); -// await expect(previewContainer.getByTestId("source-subscription-name")).toHaveText(expectedSubscriptionName); -// await expect(previewContainer.getByTestId("source-account-name")).toHaveText(expectedAccountName); + // Verify job preview details + const previewContainer = panel.getByTestId("Panel:PreviewCopyJob"); + await expect(previewContainer).toBeVisible(); + await expect(previewContainer.getByTestId("source-subscription-name")).toHaveText(expectedSubscriptionName); + await expect(previewContainer.getByTestId("source-account-name")).toHaveText(expectedAccountName); -// const jobNameInput = previewContainer.getByTestId("job-name-textfield"); -// await expect(jobNameInput).toHaveValue(new RegExp(expectedCopyJobNameInitial)); + const jobNameInput = previewContainer.getByTestId("job-name-textfield"); + await expect(jobNameInput).toHaveValue(new RegExp(expectedCopyJobNameInitial)); -// const primaryBtn = panel.getByRole("button", { name: "Copy", exact: true }); -// await expect(primaryBtn).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); + const primaryBtn = panel.getByRole("button", { name: "Copy", exact: true }); + await expect(primaryBtn).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); -// // Test invalid job name validation (spaces not allowed) -// await jobNameInput.fill("test job name"); -// await expect(primaryBtn).toHaveClass(/(^|\s)is-disabled(\s|$)/); + // Test invalid job name validation (spaces not allowed) + await jobNameInput.fill("test job name"); + await expect(primaryBtn).toHaveClass(/(^|\s)is-disabled(\s|$)/); -// // Test duplicate job name error handling -// const duplicateJobName = "test-job-name-1"; -// await jobNameInput.fill(duplicateJobName); + // Test duplicate job name error handling + const duplicateJobName = "test-job-name-1"; + await jobNameInput.fill(duplicateJobName); -// const copyButton = panel.getByRole("button", { name: "Copy", exact: true }); -// const expectedErrorMessage = `Duplicate job name '${duplicateJobName}'`; + const copyButton = panel.getByRole("button", { name: "Copy", exact: true }); + const expectedErrorMessage = `Duplicate job name '${duplicateJobName}'`; -// await interceptAndInspectApiRequest( -// page, -// `${expectedAccountName}/dataTransferJobs/${duplicateJobName}`, -// "PUT", -// new Error(expectedErrorMessage), -// (url?: string) => url?.includes(duplicateJobName) ?? false, -// ); + await interceptAndInspectApiRequest( + page, + `${expectedAccountName}/dataTransferJobs/${duplicateJobName}`, + "PUT", + new Error(expectedErrorMessage), + (url?: string) => url?.includes(duplicateJobName) ?? false, + ); -// let errorThrown = false; -// try { -// await copyButton.click(); -// await page.waitForTimeout(2000); -// } catch (error: any) { -// errorThrown = true; -// expect(error.message).toContain("not allowed"); -// } + let errorThrown = false; + try { + await copyButton.click(); + await page.waitForTimeout(2000); + } catch (error: any) { + errorThrown = true; + expect(error.message).toContain("not allowed"); + } -// if (!errorThrown) { -// const errorContainer = panel.getByTestId("Panel:ErrorContainer"); -// await expect(errorContainer).toBeVisible(); -// await expect(errorContainer).toHaveText(new RegExp(expectedErrorMessage, "i")); -// } + if (!errorThrown) { + const errorContainer = panel.getByTestId("Panel:ErrorContainer"); + await expect(errorContainer).toBeVisible(); + await expect(errorContainer).toHaveText(new RegExp(expectedErrorMessage, "i")); + } -// await expect(panel).toBeVisible(); + await expect(panel).toBeVisible(); -// // Test successful job creation with valid job name -// const validJobName = expectedJobName; + // Test successful job creation with valid job name + const validJobName = expectedJobName; -// const copyJobCreationPromise = waitForApiResponse( -// page, -// `${expectedAccountName}/dataTransferJobs/${validJobName}`, -// "PUT", -// ); + const copyJobCreationPromise = waitForApiResponse( + page, + `${expectedAccountName}/dataTransferJobs/${validJobName}`, + "PUT", + ); -// await jobNameInput.fill(validJobName); -// await expect(copyButton).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); + await jobNameInput.fill(validJobName); + await expect(copyButton).not.toHaveClass(/(^|\s)is-disabled(\s|$)/); -// await copyButton.click(); + await copyButton.click(); -// const response = await copyJobCreationPromise; -// expect(response.ok()).toBe(true); + const response = await copyJobCreationPromise; + expect(response.ok()).toBe(true); -// // Verify panel closes and job appears in the list -// await expect(panel).not.toBeVisible(); + // Verify panel closes and job appears in the list + await expect(panel).not.toBeVisible(); -// const filterTextField = wrapper.getByTestId("CopyJobsList/FilterTextField"); -// await filterTextField.waitFor({ state: "visible" }); -// await filterTextField.fill(validJobName); + const filterTextField = wrapper.getByTestId("CopyJobsList/FilterTextField"); + await filterTextField.waitFor({ state: "visible" }); + await filterTextField.fill(validJobName); -// const jobsListContainer = wrapper.locator(".CopyJobListContainer .ms-DetailsList-contentWrapper .ms-List-page"); -// await jobsListContainer.waitFor({ state: "visible" }); + const jobsListContainer = wrapper.locator(".CopyJobListContainer .ms-DetailsList-contentWrapper .ms-List-page"); + await jobsListContainer.waitFor({ state: "visible" }); -// const jobItem = jobsListContainer.getByText(validJobName); -// await jobItem.waitFor({ state: "visible" }); -// await expect(jobItem).toBeVisible(); -// }); -// }); + const jobItem = jobsListContainer.getByText(validJobName); + await jobItem.waitFor({ state: "visible" }); + await expect(jobItem).toBeVisible(); + }); +}); diff --git a/test/sql/containercopy/onlineMigration.spec.ts b/test/sql/containercopy/onlineMigration.spec.ts index 6570799b9..e11b3decd 100644 --- a/test/sql/containercopy/onlineMigration.spec.ts +++ b/test/sql/containercopy/onlineMigration.spec.ts @@ -1,189 +1,189 @@ -// /* eslint-disable @typescript-eslint/no-explicit-any */ -// import { expect, Frame, Locator, Page, test } from "@playwright/test"; -// import { -// ContainerCopy, -// getAccountName, -// getDropdownItemByNameOrPosition, -// TestAccount, -// waitForApiResponse, -// } from "../../fx"; -// import { createMultipleTestContainers } from "../../testData"; +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { expect, Frame, Locator, Page, test } from "@playwright/test"; +import { + ContainerCopy, + getAccountName, + getDropdownItemByNameOrPosition, + TestAccount, + waitForApiResponse, +} from "../../fx"; +import { createMultipleTestContainers } from "../../testData"; -// test.describe("Container Copy - Online Migration", () => { -// let page: Page; -// let wrapper: Locator; -// let panel: Locator; -// let frame: Frame; -// let targetAccountName: string; +test.describe("Container Copy - Online Migration", () => { + let page: Page; + let wrapper: Locator; + let panel: Locator; + let frame: Frame; + let targetAccountName: string; -// test.beforeEach("Setup for online migration test", async ({ browser }) => { -// await createMultipleTestContainers({ accountType: TestAccount.SQLContainerCopyOnly, containerCount: 2 }); + test.beforeEach("Setup for online migration test", async ({ browser }) => { + await createMultipleTestContainers({ accountType: TestAccount.SQLContainerCopyOnly, containerCount: 2 }); -// page = await browser.newPage(); -// ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); -// targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); -// }); + page = await browser.newPage(); + ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); + targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); + }); -// test.afterEach("Cleanup after online migration test", async () => { -// await page.unroute(/.*/, (route) => route.continue()); -// await page.close(); -// }); + test.afterEach("Cleanup after online migration test", async () => { + await page.unroute(/.*/, (route) => route.continue()); + await page.close(); + }); -// test("Successfully create and manage online migration copy job", async () => { -// expect(wrapper).not.toBeNull(); -// await wrapper.locator(".commandBarContainer").waitFor({ state: "visible" }); + test("Successfully create and manage online migration copy job", async () => { + expect(wrapper).not.toBeNull(); + await wrapper.locator(".commandBarContainer").waitFor({ state: "visible" }); -// // Open Create Copy Job panel -// const createCopyJobButton = wrapper.getByTestId("CommandBar/Button:Create Copy Job"); -// await expect(createCopyJobButton).toBeVisible(); -// await createCopyJobButton.click(); -// panel = frame.getByTestId("Panel:Create copy job"); -// await expect(panel).toBeVisible(); + // Open Create Copy Job panel + const createCopyJobButton = wrapper.getByTestId("CommandBar/Button:Create Copy Job"); + await expect(createCopyJobButton).toBeVisible(); + await createCopyJobButton.click(); + panel = frame.getByTestId("Panel:Create copy job"); + await expect(panel).toBeVisible(); -// // Reduced wait time for better performance -// await page.waitForTimeout(1000); + // Reduced wait time for better performance + await page.waitForTimeout(1000); -// // Enable online migration mode -// const migrationTypeContainer = panel.getByTestId("migration-type"); -// const onlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Online mode/i }); -// await onlineCopyRadioButton.click({ force: true }); + // Enable online migration mode + const migrationTypeContainer = panel.getByTestId("migration-type"); + const onlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Online mode/i }); + await onlineCopyRadioButton.click({ force: true }); -// await expect(migrationTypeContainer.getByTestId("migration-type-description-online")).toBeVisible(); + await expect(migrationTypeContainer.getByTestId("migration-type-description-online")).toBeVisible(); -// await panel.getByRole("button", { name: "Next" }).click(); + await panel.getByRole("button", { name: "Next" }).click(); -// // Verify permissions screen is shown for online migration -// const permissionScreen = panel.getByTestId("Panel:AssignPermissionsContainer"); -// await expect(permissionScreen).toBeVisible(); -// await expect(permissionScreen.getByText("Online container copy", { exact: true })).toBeVisible(); + // Verify permissions screen is shown for online migration + const permissionScreen = panel.getByTestId("Panel:AssignPermissionsContainer"); + await expect(permissionScreen).toBeVisible(); + await expect(permissionScreen.getByText("Online container copy", { exact: true })).toBeVisible(); -// // Skip permissions setup and proceed to container selection -// await panel.getByRole("button", { name: "Next" }).click(); + // Skip permissions setup and proceed to container selection + await panel.getByRole("button", { name: "Next" }).click(); -// // Configure source and target containers for online migration -// const sourceDatabaseDropdown = panel.getByTestId("source-databaseDropdown"); -// await sourceDatabaseDropdown.click(); -// const sourceDbDropdownItem = await getDropdownItemByNameOrPosition( -// frame, -// { position: 0 }, -// { ariaLabel: "Database" }, -// ); -// await sourceDbDropdownItem.click(); + // Configure source and target containers for online migration + const sourceDatabaseDropdown = panel.getByTestId("source-databaseDropdown"); + await sourceDatabaseDropdown.click(); + const sourceDbDropdownItem = await getDropdownItemByNameOrPosition( + frame, + { position: 0 }, + { ariaLabel: "Database" }, + ); + await sourceDbDropdownItem.click(); -// const sourceContainerDropdown = panel.getByTestId("source-containerDropdown"); -// await sourceContainerDropdown.click(); -// const sourceContainerDropdownItem = await getDropdownItemByNameOrPosition( -// frame, -// { position: 0 }, -// { ariaLabel: "Container" }, -// ); -// await sourceContainerDropdownItem.click(); + const sourceContainerDropdown = panel.getByTestId("source-containerDropdown"); + await sourceContainerDropdown.click(); + const sourceContainerDropdownItem = await getDropdownItemByNameOrPosition( + frame, + { position: 0 }, + { ariaLabel: "Container" }, + ); + await sourceContainerDropdownItem.click(); -// const targetDatabaseDropdown = panel.getByTestId("target-databaseDropdown"); -// await targetDatabaseDropdown.click(); -// const targetDbDropdownItem = await getDropdownItemByNameOrPosition( -// frame, -// { position: 0 }, -// { ariaLabel: "Database" }, -// ); -// await targetDbDropdownItem.click(); + const targetDatabaseDropdown = panel.getByTestId("target-databaseDropdown"); + await targetDatabaseDropdown.click(); + const targetDbDropdownItem = await getDropdownItemByNameOrPosition( + frame, + { position: 0 }, + { ariaLabel: "Database" }, + ); + await targetDbDropdownItem.click(); -// const targetContainerDropdown = panel.getByTestId("target-containerDropdown"); -// await targetContainerDropdown.click(); -// const targetContainerDropdownItem = await getDropdownItemByNameOrPosition( -// frame, -// { position: 1 }, -// { ariaLabel: "Container" }, -// ); -// await targetContainerDropdownItem.click(); + const targetContainerDropdown = panel.getByTestId("target-containerDropdown"); + await targetContainerDropdown.click(); + const targetContainerDropdownItem = await getDropdownItemByNameOrPosition( + frame, + { position: 1 }, + { ariaLabel: "Container" }, + ); + await targetContainerDropdownItem.click(); -// await panel.getByRole("button", { name: "Next" }).click(); + await panel.getByRole("button", { name: "Next" }).click(); -// // Verify job preview and create the online migration job -// const previewContainer = panel.getByTestId("Panel:PreviewCopyJob"); -// await expect(previewContainer.getByTestId("source-account-name")).toHaveText(targetAccountName); + // Verify job preview and create the online migration job + const previewContainer = panel.getByTestId("Panel:PreviewCopyJob"); + await expect(previewContainer.getByTestId("source-account-name")).toHaveText(targetAccountName); -// const jobNameInput = previewContainer.getByTestId("job-name-textfield"); -// const onlineMigrationJobName = await jobNameInput.inputValue(); + const jobNameInput = previewContainer.getByTestId("job-name-textfield"); + const onlineMigrationJobName = await jobNameInput.inputValue(); -// const copyButton = panel.getByRole("button", { name: "Copy", exact: true }); + const copyButton = panel.getByRole("button", { name: "Copy", exact: true }); -// const copyJobCreationPromise = waitForApiResponse( -// page, -// `${targetAccountName}/dataTransferJobs/${onlineMigrationJobName}`, -// "PUT", -// ); -// await copyButton.click(); -// await page.waitForTimeout(1000); // Reduced wait time + const copyJobCreationPromise = waitForApiResponse( + page, + `${targetAccountName}/dataTransferJobs/${onlineMigrationJobName}`, + "PUT", + ); + await copyButton.click(); + await page.waitForTimeout(1000); // Reduced wait time -// const response = await copyJobCreationPromise; -// expect(response.ok()).toBe(true); + const response = await copyJobCreationPromise; + expect(response.ok()).toBe(true); -// // Verify panel closes and job appears in the list -// await expect(panel).not.toBeVisible(); + // Verify panel closes and job appears in the list + await expect(panel).not.toBeVisible(); -// const filterTextField = wrapper.getByTestId("CopyJobsList/FilterTextField"); -// await filterTextField.waitFor({ state: "visible" }); -// await filterTextField.fill(onlineMigrationJobName); + const filterTextField = wrapper.getByTestId("CopyJobsList/FilterTextField"); + await filterTextField.waitFor({ state: "visible" }); + await filterTextField.fill(onlineMigrationJobName); -// const jobsListContainer = wrapper.locator(".CopyJobListContainer .ms-DetailsList-contentWrapper .ms-List-page"); -// await jobsListContainer.waitFor({ state: "visible" }); + const jobsListContainer = wrapper.locator(".CopyJobListContainer .ms-DetailsList-contentWrapper .ms-List-page"); + await jobsListContainer.waitFor({ state: "visible" }); -// let jobRow, statusCell, actionMenuButton; -// jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); -// statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); -// await jobRow.waitFor({ state: "visible" }); + let jobRow, statusCell, actionMenuButton; + jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); + statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); + await jobRow.waitFor({ state: "visible" }); -// // Verify job status changes to queued state -// await expect(statusCell).toContainText(/running|queued|pending/i); + // Verify job status changes to queued state + await expect(statusCell).toContainText(/running|queued|pending/i); -// // Test job lifecycle management through action menu -// actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); -// await actionMenuButton.click(); + // Test job lifecycle management through action menu + actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); + await actionMenuButton.click(); -// // Test pause functionality -// const pauseAction = frame.locator(".ms-ContextualMenu-list button:has-text('Pause')"); -// await pauseAction.click(); + // Test pause functionality + const pauseAction = frame.locator(".ms-ContextualMenu-list button:has-text('Pause')"); + await pauseAction.click(); -// const pauseResponse = await waitForApiResponse( -// page, -// `${targetAccountName}/dataTransferJobs/${onlineMigrationJobName}/pause`, -// "POST", -// ); -// expect(pauseResponse.ok()).toBe(true); + const pauseResponse = await waitForApiResponse( + page, + `${targetAccountName}/dataTransferJobs/${onlineMigrationJobName}/pause`, + "POST", + ); + expect(pauseResponse.ok()).toBe(true); -// // Verify job status changes to paused -// jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); -// await jobRow.waitFor({ state: "visible", timeout: 5000 }); -// statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); -// await expect(statusCell).toContainText(/paused/i, { timeout: 5000 }); -// await page.waitForTimeout(1000); + // Verify job status changes to paused + jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); + await jobRow.waitFor({ state: "visible", timeout: 5000 }); + statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); + await expect(statusCell).toContainText(/paused/i, { timeout: 5000 }); + await page.waitForTimeout(1000); -// // Test cancel job functionality -// actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); -// await actionMenuButton.click(); -// await frame.locator(".ms-ContextualMenu-list button:has-text('Cancel')").click(); + // Test cancel job functionality + actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); + await actionMenuButton.click(); + await frame.locator(".ms-ContextualMenu-list button:has-text('Cancel')").click(); -// // Verify cancellation confirmation dialog -// await expect(frame.locator(".ms-Dialog-main")).toBeVisible({ timeout: 2000 }); -// await expect(frame.locator(".ms-Dialog-main")).toContainText(onlineMigrationJobName); + // Verify cancellation confirmation dialog + await expect(frame.locator(".ms-Dialog-main")).toBeVisible({ timeout: 2000 }); + await expect(frame.locator(".ms-Dialog-main")).toContainText(onlineMigrationJobName); -// const cancelDialogButton = frame.locator(".ms-Dialog-main").getByTestId("DialogButton:Cancel"); -// await expect(cancelDialogButton).toBeVisible(); -// await cancelDialogButton.click(); -// await expect(frame.locator(".ms-Dialog-main")).not.toBeVisible(); + const cancelDialogButton = frame.locator(".ms-Dialog-main").getByTestId("DialogButton:Cancel"); + await expect(cancelDialogButton).toBeVisible(); + await cancelDialogButton.click(); + await expect(frame.locator(".ms-Dialog-main")).not.toBeVisible(); -// actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); -// await actionMenuButton.click(); -// await frame.locator(".ms-ContextualMenu-list button:has-text('Cancel')").click(); + actionMenuButton = wrapper.getByTestId(`CopyJobActionMenu/Button:${onlineMigrationJobName}`); + await actionMenuButton.click(); + await frame.locator(".ms-ContextualMenu-list button:has-text('Cancel')").click(); -// const confirmDialogButton = frame.locator(".ms-Dialog-main").getByTestId("DialogButton:Confirm"); -// await expect(confirmDialogButton).toBeVisible(); -// await confirmDialogButton.click(); + const confirmDialogButton = frame.locator(".ms-Dialog-main").getByTestId("DialogButton:Confirm"); + await expect(confirmDialogButton).toBeVisible(); + await confirmDialogButton.click(); -// // Verify final job status is cancelled -// jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); -// statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); -// await expect(statusCell).toContainText(/cancelled/i, { timeout: 5000 }); -// }); -// }); + // Verify final job status is cancelled + jobRow = jobsListContainer.locator(".ms-DetailsRow", { hasText: onlineMigrationJobName }); + statusCell = jobRow.locator("[data-automationid='DetailsRowCell'][data-automation-key='CopyJobStatus']"); + await expect(statusCell).toContainText(/cancelled/i, { timeout: 5000 }); + }); +}); From 27d85a450beb44fe13e938b4e92e87339d9a07c8 Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Fri, 23 Jan 2026 14:20:50 -0800 Subject: [PATCH 18/19] run test account cleanup every 12 hours --- .github/workflows/cleanup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cleanup.yml b/.github/workflows/cleanup.yml index ece8c8dba..9a2e99c99 100644 --- a/.github/workflows/cleanup.yml +++ b/.github/workflows/cleanup.yml @@ -6,8 +6,8 @@ on: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: schedule: - # Once every two hours - - cron: "0 */2 * * *" + # Once every twelve hours + - cron: "0 */12 * * *" permissions: id-token: write From 3552cd3e9d4d97ac48800acc676ab2403e8b38bf Mon Sep 17 00:00:00 2001 From: Asier Isayas Date: Mon, 26 Jan 2026 06:36:47 -0800 Subject: [PATCH 19/19] change cleanup frequency to once a day --- .github/workflows/cleanup.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cleanup.yml b/.github/workflows/cleanup.yml index 9a2e99c99..80991db2a 100644 --- a/.github/workflows/cleanup.yml +++ b/.github/workflows/cleanup.yml @@ -6,8 +6,8 @@ on: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: schedule: - # Once every twelve hours - - cron: "0 */12 * * *" + # Once every day at 7 AM PST + - cron: "0 13 * * *" permissions: id-token: write