diff --git a/test/fx.ts b/test/fx.ts index 5c19658ff..2f4d6a301 100644 --- a/test/fx.ts +++ b/test/fx.ts @@ -118,6 +118,9 @@ export async function getTestExplorerUrl(accountType: TestAccount, options?: Tes params.set("nosqlRbacToken", nosqlRbacToken); params.set("enableaaddataplane", "true"); } + if (enablecontainercopy) { + params.set("enablecontainercopy", "true"); + } break; case TestAccount.SQLContainerCopyOnly: diff --git a/test/sql/containercopy/offlineMigration.spec.ts b/test/sql/containercopy/offlineMigration.spec.ts index d7e5e75a3..75eb3e243 100644 --- a/test/sql/containercopy/offlineMigration.spec.ts +++ b/test/sql/containercopy/offlineMigration.spec.ts @@ -18,7 +18,7 @@ test.describe("Container Copy - Offline Migration", () => { let panel: Locator; let frame: Frame; let expectedJobName: string; - let targetAccountName: string; + let sourceAccountName: string; let expectedSubscriptionName: string; let expectedCopyJobNameInitial: string; @@ -28,7 +28,7 @@ test.describe("Container Copy - Offline Migration", () => { page = await browser.newPage(); ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); expectedJobName = `offline_test_job_${Date.now()}`; - targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); + sourceAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); }); test.afterEach("Cleanup after offline migration test", async () => { @@ -53,7 +53,7 @@ test.describe("Container Copy - Offline Migration", () => { // Setup subscription and account const subscriptionDropdown = panel.getByTestId("subscription-dropdown"); - const expectedAccountName = targetAccountName; + const expectedAccountName = sourceAccountName; expectedSubscriptionName = await subscriptionDropdown.locator("span.ms-Dropdown-title").innerText(); await subscriptionDropdown.click(); @@ -185,8 +185,8 @@ test.describe("Container Copy - Offline Migration", () => { // 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); + await expect(previewContainer.getByTestId("destination-subscription-name")).toHaveText(expectedSubscriptionName); + await expect(previewContainer.getByTestId("destination-account-name")).toHaveText(expectedAccountName); const jobNameInput = previewContainer.getByTestId("job-name-textfield"); await expect(jobNameInput).toHaveValue(new RegExp(expectedCopyJobNameInitial)); diff --git a/test/sql/containercopy/onlineMigration.spec.ts b/test/sql/containercopy/onlineMigration.spec.ts index 1f4b2acb7..4bd59aef8 100644 --- a/test/sql/containercopy/onlineMigration.spec.ts +++ b/test/sql/containercopy/onlineMigration.spec.ts @@ -15,14 +15,14 @@ test.describe("Container Copy - Online Migration", () => { let wrapper: Locator; let panel: Locator; let frame: Frame; - let targetAccountName: string; + let sourceAccountName: string; test.beforeEach("Setup for online migration test", async ({ browser }) => { contexts = await createMultipleTestContainers({ accountType: TestAccount.SQLContainerCopyOnly, containerCount: 2 }); page = await browser.newPage(); ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); - targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); + sourceAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); }); test.afterEach("Cleanup after online migration test", async () => { @@ -103,7 +103,7 @@ test.describe("Container Copy - Online Migration", () => { // Verify job preview and create the online migration job const previewContainer = panel.getByTestId("Panel:PreviewCopyJob"); - await expect(previewContainer.getByTestId("source-account-name")).toHaveText(targetAccountName); + await expect(previewContainer.getByTestId("destination-account-name")).toHaveText(sourceAccountName); const jobNameInput = previewContainer.getByTestId("job-name-textfield"); const onlineMigrationJobName = await jobNameInput.inputValue(); @@ -112,7 +112,7 @@ test.describe("Container Copy - Online Migration", () => { const copyJobCreationPromise = waitForApiResponse( page, - `${targetAccountName}/dataTransferJobs/${onlineMigrationJobName}`, + `${sourceAccountName}/dataTransferJobs/${onlineMigrationJobName}`, "PUT", ); await copyButton.click(); @@ -149,7 +149,7 @@ test.describe("Container Copy - Online Migration", () => { const pauseResponse = await waitForApiResponse( page, - `${targetAccountName}/dataTransferJobs/${onlineMigrationJobName}/pause`, + `${sourceAccountName}/dataTransferJobs/${onlineMigrationJobName}/pause`, "POST", ); expect(pauseResponse.ok()).toBe(true); diff --git a/test/sql/containercopy/permissionsScreen.spec.ts b/test/sql/containercopy/permissionsScreen.spec.ts index f592bf4c7..3a7c762a8 100644 --- a/test/sql/containercopy/permissionsScreen.spec.ts +++ b/test/sql/containercopy/permissionsScreen.spec.ts @@ -10,13 +10,14 @@ test.describe("Container Copy - Permission Screen Verification", () => { let wrapper: Locator; let panel: Locator; let frame: Frame; + let sourceAccountName: string; let targetAccountName: string; - let expectedSourceAccountName: string; test.beforeEach("Setup for each test", async ({ browser }) => { page = await browser.newPage(); - ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQLContainerCopyOnly)); + ({ wrapper, frame } = await ContainerCopy.open(page, TestAccount.SQL)); targetAccountName = getAccountName(TestAccount.SQLContainerCopyOnly); + sourceAccountName = getAccountName(TestAccount.SQL); }); test.afterEach("Cleanup after each test", async () => { @@ -50,22 +51,14 @@ test.describe("Container Copy - Permission Screen Verification", () => { const allDropdownItems = await dropdownItemsWrapper.locator(`button.ms-Dropdown-item[role='option']`).all(); - const filteredItems = []; for (const item of allDropdownItems) { const testContent = (await item.textContent()) ?? ""; - if (testContent.trim() !== targetAccountName.trim()) { - filteredItems.push(item); + if (testContent.trim() === targetAccountName.trim()) { + await item.click(); + break; } } - if (filteredItems.length > 0) { - const firstDropdownItem = filteredItems[0]; - expectedSourceAccountName = (await firstDropdownItem.textContent()) ?? ""; - await firstDropdownItem.click(); - } else { - throw new Error("No dropdown items available after filtering"); - } - // Enable online migration mode const migrationTypeContainer = panel.getByTestId("migration-type"); const onlineCopyRadioButton = migrationTypeContainer.getByRole("radio", { name: /Online mode/i }); @@ -81,7 +74,7 @@ test.describe("Container Copy - Permission Screen Verification", () => { await expect(permissionScreen.getByText("Cross-account container copy", { exact: true })).toBeVisible(); // Setup API mocking for the source account - await page.route(`**/Microsoft.DocumentDB/databaseAccounts/${expectedSourceAccountName}**`, async (route) => { + await page.route(`**/Microsoft.DocumentDB/databaseAccounts/${sourceAccountName}**`, async (route) => { const mockData = { identity: { type: "SystemAssigned", @@ -139,7 +132,7 @@ test.describe("Container Copy - Permission Screen Verification", () => { // Verify new page opens with correct URL pattern page.context().on("page", async (newPage) => { const expectedUrlEndPattern = new RegExp( - `/providers/Microsoft.(DocumentDB|DocumentDb)/databaseAccounts/${expectedSourceAccountName}/backupRestore`, + `/providers/Microsoft.(DocumentDB|DocumentDb)/databaseAccounts/${sourceAccountName}/backupRestore`, ); expect(newPage.url()).toMatch(expectedUrlEndPattern); await newPage.close(); @@ -158,8 +151,10 @@ test.describe("Container Copy - Permission Screen Verification", () => { await expect(pitrBtn).not.toBeVisible(); // Setup additional API mocks for role assignments and permissions + // In the redesigned flow, role assignments are checked on the SOURCE account (current account = sourceAccountName). + // The destination account (selectedAccountName) manages identity; source account holds the role assignments. await page.route( - `**/Microsoft.DocumentDB/databaseAccounts/${expectedSourceAccountName}/sqlRoleAssignments*`, + `**/Microsoft.DocumentDB/databaseAccounts/${sourceAccountName}/sqlRoleAssignments*`, async (route) => { await route.fulfill({ status: 200, @@ -168,7 +163,7 @@ test.describe("Container Copy - Permission Screen Verification", () => { value: [ { principalId: "00-11-22-33", - roleDefinitionId: `Microsoft.DocumentDB/databaseAccounts/${expectedSourceAccountName}/77-88-99`, + roleDefinitionId: `Microsoft.DocumentDB/databaseAccounts/${sourceAccountName}/77-88-99`, }, ], }), @@ -183,14 +178,15 @@ test.describe("Container Copy - Permission Screen Verification", () => { body: JSON.stringify({ value: [ { - name: "00000000-0000-0000-0000-000000000001", + // Built-in Cosmos DB Data Contributor role (read-write), required by checkTargetHasReadWriteRoleOnSource + name: "00000000-0000-0000-0000-000000000002", }, ], }), }); }); - await page.route(`**/Microsoft.DocumentDB/databaseAccounts/${targetAccountName}**`, async (route) => { + await page.route(`**/Microsoft.DocumentDB/databaseAccounts/${sourceAccountName}**`, async (route) => { const mockData = { identity: { type: "SystemAssigned",