mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-19 08:51:24 +00:00
Error rendering improvements (#1887)
This commit is contained in:
committed by
GitHub
parent
cc89691da3
commit
805a4ae168
@@ -1,40 +1,51 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
|
||||
import { DataExplorer, TestAccount, generateDatabaseNameWithTimestamp, generateUniqueName } from "../fx";
|
||||
import { DataExplorer, TestAccount, generateUniqueName } from "../fx";
|
||||
|
||||
test("SQL database and container CRUD", async ({ page }) => {
|
||||
const databaseId = generateDatabaseNameWithTimestamp();
|
||||
const containerId = generateUniqueName("container");
|
||||
const databaseId = generateUniqueName("db");
|
||||
const containerId = "testcontainer"; // A unique container name isn't needed because the database is unique
|
||||
|
||||
const explorer = await DataExplorer.open(page, TestAccount.SQL);
|
||||
|
||||
await explorer.globalCommandButton("New Container").click();
|
||||
await explorer.whilePanelOpen("New Container", async (panel, okButton) => {
|
||||
await panel.getByPlaceholder("Type a new database id").fill(databaseId);
|
||||
await panel.getByRole("textbox", { name: "Container id, Example Container1" }).fill(containerId);
|
||||
await panel.getByRole("textbox", { name: "Partition key" }).fill("/pk");
|
||||
await panel.getByLabel("Database max RU/s").fill("1000");
|
||||
await okButton.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();
|
||||
},
|
||||
{ closeTimeout: 5 * 60 * 1000 },
|
||||
);
|
||||
|
||||
const databaseNode = explorer.treeNode(databaseId);
|
||||
await databaseNode.expand();
|
||||
const containerNode = explorer.treeNode(`${databaseId}/${containerId}`);
|
||||
const databaseNode = await explorer.waitForNode(databaseId);
|
||||
const containerNode = await explorer.waitForContainerNode(databaseId, containerId);
|
||||
|
||||
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 explorer.whilePanelOpen(
|
||||
"Delete Container",
|
||||
async (panel, okButton) => {
|
||||
await panel.getByRole("textbox", { name: "Confirm by typing the container id" }).fill(containerId);
|
||||
await okButton.click();
|
||||
},
|
||||
{ closeTimeout: 5 * 60 * 1000 },
|
||||
);
|
||||
await expect(containerNode.element).not.toBeAttached();
|
||||
|
||||
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.whilePanelOpen(
|
||||
"Delete Database",
|
||||
async (panel, okButton) => {
|
||||
await panel.getByRole("textbox", { name: "Confirm by typing the database id" }).fill(databaseId);
|
||||
await okButton.click();
|
||||
},
|
||||
{ closeTimeout: 5 * 60 * 1000 },
|
||||
);
|
||||
|
||||
await expect(databaseNode.element).not.toBeAttached();
|
||||
});
|
||||
|
||||
91
test/sql/query.spec.ts
Normal file
91
test/sql/query.spec.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
|
||||
import { DataExplorer, Editor, QueryTab, TestAccount } from "../fx";
|
||||
import { TestContainerContext, TestItem, createTestSQLContainer } from "../testData";
|
||||
|
||||
let context: TestContainerContext = null!;
|
||||
let explorer: DataExplorer = null!;
|
||||
let queryTab: QueryTab = null!;
|
||||
let queryEditor: Editor = null!;
|
||||
|
||||
test.beforeAll("Create Test Database", async () => {
|
||||
context = await createTestSQLContainer(true);
|
||||
});
|
||||
|
||||
test.beforeEach("Open new query tab", async ({ page }) => {
|
||||
// Open a query tab
|
||||
explorer = await DataExplorer.open(page, TestAccount.SQL);
|
||||
|
||||
// Container nodes should be visible. The explorer auto-expands database nodes when they are first loaded.
|
||||
const containerNode = await explorer.waitForContainerNode(context.database.id, context.container.id);
|
||||
await containerNode.openContextMenu();
|
||||
await containerNode.contextMenuItem("New SQL Query").click();
|
||||
|
||||
// Wait for the editor to load
|
||||
queryTab = explorer.queryTab("tab0");
|
||||
queryEditor = queryTab.editor();
|
||||
await queryEditor.locator.waitFor({ timeout: 30 * 1000 });
|
||||
await queryTab.executeCTA.waitFor();
|
||||
await explorer.frame.getByTestId("NotificationConsole/ExpandCollapseButton").click();
|
||||
await explorer.frame.getByTestId("NotificationConsole/Contents").waitFor();
|
||||
});
|
||||
|
||||
test.afterAll("Delete Test Database", async () => {
|
||||
await context?.dispose();
|
||||
});
|
||||
|
||||
test("Query results", async () => {
|
||||
// Run the query and verify the results
|
||||
await queryEditor.locator.click();
|
||||
const executeQueryButton = explorer.commandBarButton("Execute Query");
|
||||
await executeQueryButton.click();
|
||||
await expect(queryTab.resultsEditor.locator).toBeAttached({ timeout: 60 * 1000 });
|
||||
|
||||
// Read the results
|
||||
const resultText = await queryTab.resultsEditor.text();
|
||||
expect(resultText).not.toBeNull();
|
||||
const resultData: TestItem[] = JSON.parse(resultText!);
|
||||
|
||||
// Pick 3 random documents and assert them
|
||||
const randomDocs = [0, 1, 2].map(() => resultData[Math.floor(Math.random() * resultData.length)]);
|
||||
randomDocs.forEach((doc) => {
|
||||
const matchingDoc = context?.testData.get(doc.id);
|
||||
expect(matchingDoc).not.toBeNull();
|
||||
expect(doc.randomData).toEqual(matchingDoc?.randomData);
|
||||
expect(doc.partitionKey).toEqual(matchingDoc?.partitionKey);
|
||||
});
|
||||
});
|
||||
|
||||
test("Query stats", async () => {
|
||||
// Run the query and verify the results
|
||||
await queryEditor.locator.click();
|
||||
const executeQueryButton = explorer.commandBarButton("Execute Query");
|
||||
await executeQueryButton.click();
|
||||
await expect(queryTab.resultsEditor.locator).toBeAttached({ timeout: 60 * 1000 });
|
||||
|
||||
// Open the query stats tab and validate some data there
|
||||
queryTab.queryStatsTab.click();
|
||||
await expect(queryTab.queryStatsList).toBeAttached();
|
||||
const showingResultsCell = queryTab.queryStatsList.getByTestId("Row:Showing Results/Column:value");
|
||||
await expect(showingResultsCell).toContainText(/\d+ - \d+/);
|
||||
});
|
||||
|
||||
test("Query errors", async () => {
|
||||
await queryEditor.locator.click();
|
||||
await queryEditor.setText("SELECT\n glarb(c.id),\n blarg(c.id)\nFROM c");
|
||||
|
||||
// Run the query and verify the results
|
||||
const executeQueryButton = explorer.commandBarButton("Execute Query");
|
||||
await executeQueryButton.click();
|
||||
|
||||
await expect(queryTab.errorList).toBeAttached({ timeout: 60 * 1000 });
|
||||
|
||||
// Validating the squiggles requires a lot of digging through the Monaco model, OR a screenshot comparison.
|
||||
// The screenshot ended up being fairly flaky, and a pain to maintain, so I decided not to include validation for the squiggles.
|
||||
|
||||
// Validate the errors are in the list
|
||||
await expect(queryTab.errorList.getByTestId("Row:0/Column:code")).toHaveText("SC2005");
|
||||
await expect(queryTab.errorList.getByTestId("Row:0/Column:location")).toHaveText("Line 2");
|
||||
await expect(queryTab.errorList.getByTestId("Row:1/Column:code")).toHaveText("SC2005");
|
||||
await expect(queryTab.errorList.getByTestId("Row:1/Column:location")).toHaveText("Line 3");
|
||||
});
|
||||
@@ -19,7 +19,7 @@ test("SQL account using Resource token", async ({ page }) => {
|
||||
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 collectionId = "testcollection";
|
||||
const client = new CosmosClient({
|
||||
endpoint: account.documentEndpoint!,
|
||||
key: keys.primaryMasterKey,
|
||||
|
||||
Reference in New Issue
Block a user