diff --git a/.github/workflows/cleanup.yml b/.github/workflows/cleanup.yml index ece8c8dba..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 two hours - - cron: "0 */2 * * *" + # Once every day at 7 AM PST + - cron: "0 13 * * *" permissions: id-token: write diff --git a/test/fx.ts b/test/fx.ts index fdd566dca..9c8c382a3 100644 --- a/test/fx.ts +++ b/test/fx.ts @@ -380,9 +380,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 */ @@ -480,7 +482,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; @@ -517,15 +519,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 b6703c49a..cf98ebcc7 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"; @@ -48,19 +48,20 @@ 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(); + 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; 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(); - await expect(documentsTab.resultsEditor.locator).toBeAttached({ timeout: 60 * 1000 }); newDocumentId = `${Date.now().toString()}-delete`; @@ -71,8 +72,9 @@ for (const { name, databaseId, containerId, documents } of documentTestCases) { }; await documentsTab.resultsEditor.setText(JSON.stringify(newDocument)); - const saveButton = await explorer.waitForCommandBarButton("Save", 5000); + const saveButton = await explorer.waitForCommandBarButton(CommandBarButton.Save, 5000); await saveButton.click({ timeout: 5000 }); + await expect(saveButton).toBeHidden({ timeout: 5000 }); }, 3); @@ -84,7 +86,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); 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/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(); 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