Update Playwright, improve E2E test reliability, add scripts to deploy test resources (#1857)

This commit is contained in:
Ashley Stanton-Nurse
2024-06-05 12:46:32 -07:00
committed by GitHub
parent 736731474f
commit 417ef899f0
56 changed files with 1176 additions and 2117 deletions

View File

@@ -1,55 +1,40 @@
import { jest } from "@jest/globals";
import "expect-playwright";
import {
AccountType,
generateUniqueName,
getPanelSelector,
getTestExplorerUrl,
getTreeMenuItemSelector,
getTreeNodeSelector,
openContextMenu,
} from "../utils/shared";
import { waitForExplorer } from "../utils/waitForExplorer";
jest.setTimeout(120000);
import { expect, test } from "@playwright/test";
test("SQL CRUD", async () => {
const databaseId = generateUniqueName("db");
import { DataExplorer, TestAccount, generateDatabaseNameWithTimestamp, generateUniqueName } from "../fx";
test("SQL database and container CRUD", async ({ page }) => {
const databaseId = generateDatabaseNameWithTimestamp();
const containerId = generateUniqueName("container");
page.setDefaultTimeout(50000);
const explorer = await DataExplorer.open(page, TestAccount.SQL);
const url = await getTestExplorerUrl(AccountType.SQL);
await page.goto(url);
const explorer = await waitForExplorer();
await explorer.commandBarButton("New Container").click();
await explorer.whilePanelOpen("New Container", async (panel, okButton) => {
await panel.getByPlaceholder("Type a new database id").fill(databaseId);
await panel.getByRole("textbox", { name: "Container id, Example Container1" }).fill(containerId);
await panel.getByRole("textbox", { name: "Partition key" }).fill("/pk");
await panel.getByLabel("Database max RU/s").fill("1000");
await okButton.click();
});
await explorer.click('[data-test="New Container"]');
const databaseNode = explorer.treeNode(`DATA/${databaseId}`);
await databaseNode.expand();
const containerNode = explorer.treeNode(`DATA/${databaseId}/${containerId}`);
await explorer.waitForSelector(getPanelSelector("New Container"));
await explorer.fill('[aria-label="New database id, Type a new database id"]', databaseId);
await explorer.fill('[aria-label="Container id, Example Container1"]', containerId);
await explorer.fill('[aria-label="Partition key"]', "/pk");
await explorer.click("#sidePanelOkButton");
await explorer.waitForSelector(getPanelSelector("New Container"), { state: "detached" });
await containerNode.openContextMenu();
await containerNode.contextMenuItem("Delete Container").click();
await explorer.whilePanelOpen("Delete Container", async (panel, okButton) => {
await panel.getByRole("textbox", { name: "Confirm by typing the container id" }).fill(containerId);
await okButton.click();
});
await expect(containerNode.element).not.toBeAttached();
await explorer.click(getTreeNodeSelector(`DATA/${databaseId}`));
await explorer.hover(getTreeNodeSelector(`DATA/${databaseId}/${containerId}`));
await openContextMenu(explorer, `DATA/${databaseId}/${containerId}`);
await explorer.click(getTreeMenuItemSelector(`DATA/${databaseId}/${containerId}`, "Delete Container"));
await databaseNode.openContextMenu();
await databaseNode.contextMenuItem("Delete Database").click();
await explorer.whilePanelOpen("Delete Database", async (panel, okButton) => {
await panel.getByRole("textbox", { name: "Confirm by typing the database id" }).fill(databaseId);
await okButton.click();
});
await explorer.waitForSelector(getPanelSelector("Delete Container"));
await explorer.fill('text=* Confirm by typing the container id >> input[type="text"]', containerId);
await explorer.click('[aria-label="OK"]');
await explorer.waitForSelector(getPanelSelector("Delete Container"), { state: "detached" });
await openContextMenu(explorer, `DATA/${databaseId}`);
await explorer.click(getTreeMenuItemSelector(`DATA/${databaseId}`, "Delete Database"));
await explorer.waitForSelector(getPanelSelector("Delete Database"));
await explorer.click('text=* Confirm by typing the database id >> input[type="text"]');
await explorer.fill('text=* Confirm by typing the database id >> input[type="text"]', databaseId);
await explorer.click("#sidePanelOkButton");
await explorer.waitForSelector(getPanelSelector("Delete Database"), { state: "detached" });
await expect(explorer).not.toHaveText(".dataResourceTree", databaseId);
await expect(explorer).not.toHaveText(".dataResourceTree", containerId);
await expect(databaseNode.element).not.toBeAttached();
});

View File

@@ -1,19 +1,23 @@
import { expect, test } from "@playwright/test";
import { CosmosDBManagementClient } from "@azure/arm-cosmosdb";
import { CosmosClient, PermissionMode } from "@azure/cosmos";
import { jest } from "@jest/globals";
import "expect-playwright";
import { generateUniqueName, getAzureCLICredentials, getTreeNodeSelector } from "../utils/shared";
import { waitForExplorer } from "../utils/waitForExplorer";
jest.setTimeout(120000);
import {
DataExplorer,
TestAccount,
generateUniqueName,
getAccountName,
getAzureCLICredentials,
resourceGroupName,
subscriptionId,
} from "../fx";
const subscriptionId = process.env["AZURE_SUBSCRIPTION_ID"] ?? "";
const resourceGroupName = "runners";
test("Resource token", async () => {
test("SQL account using Resource token", async ({ page }) => {
const credentials = await getAzureCLICredentials();
const armClient = new CosmosDBManagementClient(credentials, subscriptionId);
const account = await armClient.databaseAccounts.get(resourceGroupName, "portal-sql-runner-west-us");
const keys = await armClient.databaseAccounts.listKeys(resourceGroupName, "portal-sql-runner-west-us");
const accountName = getAccountName(TestAccount.SQL);
const account = await armClient.databaseAccounts.get(resourceGroupName, accountName);
const keys = await armClient.databaseAccounts.listKeys(resourceGroupName, accountName);
const dbId = generateUniqueName("db");
const collectionId = generateUniqueName("col");
const client = new CosmosClient({
@@ -28,15 +32,24 @@ test("Resource token", async () => {
permissionMode: PermissionMode.All,
resource: container.url,
});
const resourceTokenConnectionString = `AccountEndpoint=${account.documentEndpoint};DatabaseId=${database.id};CollectionId=${container.id};${containerPermission._token}`;
await expect(containerPermission).toBeDefined();
const resourceTokenConnectionString = `AccountEndpoint=${account.documentEndpoint};DatabaseId=${
database.id
};CollectionId=${container.id};${containerPermission!._token}`;
await page.goto("https://localhost:1234/hostedExplorer.html");
await page.waitForSelector("div > p.switchConnectTypeText");
await page.click("div > p.switchConnectTypeText");
await page.fill("input[class='inputToken']", resourceTokenConnectionString);
await page.click("input[value='Connect']");
const explorer = await waitForExplorer();
const switchConnectionLink = page.getByTestId("Link:SwitchConnectionType");
await switchConnectionLink.waitFor();
await switchConnectionLink.click();
await page.getByPlaceholder("Please enter a connection string").fill(resourceTokenConnectionString);
await page.getByRole("button", { name: "Connect" }).click();
const collectionNodeLabel = await explorer.textContent(getTreeNodeSelector(`DATA/${collectionId}`));
expect(collectionNodeLabel).toBe(collectionId);
const explorer = await DataExplorer.waitForExplorer(page);
const collectionNode = explorer.treeNode(`DATA/${collectionId}`);
await collectionNode.element.waitFor();
await expect(collectionNode.element).toBeAttached();
await database.delete();
});

View File

@@ -0,0 +1,23 @@
import { expect, test } from "@playwright/test";
import { DataExplorer, TestAccount } from "../fx";
test("Self Serve", async ({ page }) => {
const explorer = await DataExplorer.open(page, TestAccount.SQL, "selfServe.html");
const loggingToggle = explorer.frame.locator("#enableLogging-toggle-input");
await expect(loggingToggle).toBeEnabled();
const regionDropdown = explorer.frame.getByText("Select a region");
await regionDropdown.click();
await explorer.frame.getByRole("option").first().click();
const currentRegionLabel = explorer.frame.getByLabel("Current Region");
await currentRegionLabel.waitFor();
await expect(currentRegionLabel).toHaveText(/current region selected is .*/);
await expect(loggingToggle).toBeDisabled();
await explorer.frame.locator("#enableDbLevelThroughput-toggle-input").click();
const slider = explorer.frame.getByLabel("Database Throughput");
await slider.waitFor();
await expect(slider).toBeAttached();
});