diff --git a/packages/databricks-vscode/package.json b/packages/databricks-vscode/package.json index 52b6166a3..7185ab8fe 100644 --- a/packages/databricks-vscode/package.json +++ b/packages/databricks-vscode/package.json @@ -6,7 +6,7 @@ "license": "LicenseRef-LICENSE", "version": "2.10.5", "engines": { - "vscode": "^1.101.0", + "vscode": "^1.86.0", "node": ">=22.0" }, "categories": [ diff --git a/packages/databricks-vscode/src/test/e2e/auth.e2e.ts b/packages/databricks-vscode/src/test/e2e/auth.e2e.ts index 4ada3295c..ae2fbe47e 100644 --- a/packages/databricks-vscode/src/test/e2e/auth.e2e.ts +++ b/packages/databricks-vscode/src/test/e2e/auth.e2e.ts @@ -1,7 +1,6 @@ import assert from "node:assert"; import { dismissNotifications, - getActionButton, waitForInput, getViewSection, waitForLogin, @@ -71,12 +70,8 @@ describe("Configure Databricks Extension", async function () { const items = await section.getVisibleItems(); for (const item of items) { const label = await item.getLabel(); - console.log( - "Looking for signin button, got item:", - await (await item.elem).getHTML() - ); if (label.toLowerCase().includes("auth type")) { - return getActionButton(item, "Sign in"); + return item.getActionButton("Sign in"); } } }, diff --git a/packages/databricks-vscode/src/test/e2e/deploy_and_run_job.e2e.ts b/packages/databricks-vscode/src/test/e2e/deploy_and_run_job.e2e.ts index c5d335c63..e4d9399d8 100644 --- a/packages/databricks-vscode/src/test/e2e/deploy_and_run_job.e2e.ts +++ b/packages/databricks-vscode/src/test/e2e/deploy_and_run_job.e2e.ts @@ -1,10 +1,8 @@ import assert from "node:assert"; import { dismissNotifications, - getActionButton, getUniqueResourceName, getViewSection, - selectOutputChannel, waitForDeployment, waitForLogin, waitForTreeItems, @@ -67,7 +65,7 @@ describe("Deploy and run job", async function () { it("should deploy and run the current job", async () => { const outputView = await workbench.getBottomBar().openOutputView(); - await selectOutputChannel(outputView, "Databricks Bundle Logs"); + await outputView.selectChannel("Databricks Bundle Logs"); await outputView.clearText(); const jobItem = await getResourceViewItem( @@ -77,8 +75,7 @@ describe("Deploy and run job", async function () { ); assert(jobItem, `Job ${jobName} not found in resource explorer`); - const deployAndRunButton = await getActionButton( - jobItem, + const deployAndRunButton = await jobItem.getActionButton( "Deploy the bundle and run the job" ); assert(deployAndRunButton, "Deploy and run button not found"); diff --git a/packages/databricks-vscode/src/test/e2e/deploy_and_run_pipeline.e2e.ts b/packages/databricks-vscode/src/test/e2e/deploy_and_run_pipeline.e2e.ts index 8e9750279..5920d5d71 100644 --- a/packages/databricks-vscode/src/test/e2e/deploy_and_run_pipeline.e2e.ts +++ b/packages/databricks-vscode/src/test/e2e/deploy_and_run_pipeline.e2e.ts @@ -1,9 +1,7 @@ import assert from "node:assert"; import { dismissNotifications, - getActionButton, getViewSection, - selectOutputChannel, waitForDeployment, waitForLogin, waitForTreeItems, @@ -64,7 +62,7 @@ describe("Deploy and run pipeline", async function () { it("should deploy and run the current pipeline", async () => { const outputView = await workbench.getBottomBar().openOutputView(); - await selectOutputChannel(outputView, "Databricks Bundle Logs"); + await outputView.selectChannel("Databricks Bundle Logs"); await outputView.clearText(); const pipelineItem = await getResourceViewItem( @@ -77,14 +75,13 @@ describe("Deploy and run pipeline", async function () { `Pipeline ${pipelineName} not found in resource explorer` ); - const deployAndRunButton = await getActionButton( - pipelineItem, + const deployAndRunButton = await pipelineItem.getActionButton( "Deploy the bundle and run the pipeline" ); assert(deployAndRunButton, "Deploy and run button not found"); await deployAndRunButton.elem.click(); - await waitForDeployment(outputView); + await waitForDeployment(); await waitForRunStatus( resourceExplorerView, @@ -120,7 +117,7 @@ describe("Deploy and run pipeline", async function () { "Dataset 'test_table' defined as MATERIALIZED_VIEW." ) || labels.includes( - "Dataset `test_table` defined as MATERIALIZED_VIEW." + "Dataset `vscode_integration_test`.`test_table` defined as MATERIALIZED_VIEW." ), "test_table item not found" ); @@ -146,11 +143,15 @@ describe("Deploy and run pipeline", async function () { datasets.push({label, description, item}); } datasets.sort((a, b) => (a.label > b.label ? 1 : -1)); + assert.strictEqual(datasets.length, 2); - assert.strictEqual(datasets[0].label, "test_table"); - assert.strictEqual(datasets[0].description, "materialized view"); - assert.strictEqual(datasets[1].label, "test_view"); - assert.strictEqual(datasets[1].description, "view"); + assert.strictEqual(datasets[0].label, "test_view"); + assert.strictEqual(datasets[0].description, "view"); + assert.strictEqual( + datasets[1].label, + "vscode_integration_test.test_table" + ); + assert.strictEqual(datasets[1].description, ""); }); it("should show expected schema definitions for a dataset", async () => { @@ -159,7 +160,7 @@ describe("Deploy and run pipeline", async function () { "Pipelines", pipelineName, "Datasets", - "test_table" + "vscode_integration_test.test_table" ); assert.strictEqual(schemaItems.length, 1); assert.strictEqual(await schemaItems[0].getLabel(), "1"); diff --git a/packages/databricks-vscode/src/test/e2e/destroy.e2e.ts b/packages/databricks-vscode/src/test/e2e/destroy.e2e.ts index e26245e42..a6452b35e 100644 --- a/packages/databricks-vscode/src/test/e2e/destroy.e2e.ts +++ b/packages/databricks-vscode/src/test/e2e/destroy.e2e.ts @@ -3,7 +3,6 @@ import { dismissNotifications, getUniqueResourceName, getViewSection, - selectOutputChannel, waitForLogin, waitForTreeItems, } from "./utils/commonUtils.ts"; @@ -72,25 +71,35 @@ describe("Deploy and destroy", async function () { .replaceAll(/[^a-zA-Z0-9]/g, "_")}]`; const outputView = await workbench.getBottomBar().openOutputView(); - await selectOutputChannel(outputView, "Databricks Bundle Logs"); + await outputView.selectChannel("Databricks Bundle Logs"); await outputView.clearText(); await browser.executeWorkbench(async (vscode) => { await vscode.commands.executeCommand("databricks.bundle.deploy"); }); - - await browser.executeWorkbench(async (vscode) => { - await vscode.commands.executeCommand( - "workbench.panel.output.focus" - ); - }); - - await selectOutputChannel(outputView, "Databricks Bundle Logs"); - console.log("Waiting for deployment to finish"); + // Wait for the deployment to finish await browser.waitUntil( async () => { try { + await browser.executeWorkbench(async (vscode) => { + await vscode.commands.executeCommand( + "workbench.panel.output.focus" + ); + }); + const outputView = await workbench + .getBottomBar() + .openOutputView(); + + if ( + (await outputView.getCurrentChannel()) !== + "Databricks Bundle Logs" + ) { + await outputView.selectChannel( + "Databricks Bundle Logs" + ); + } + const logs = (await outputView.getText()).join(""); console.log(logs); return ( @@ -98,7 +107,6 @@ describe("Deploy and destroy", async function () { logs.includes("Bundle configuration refreshed") ); } catch (e) { - console.log("Error waiting for deployment to finish:", e); return false; } }, @@ -127,19 +135,29 @@ describe("Deploy and destroy", async function () { ); }); - await browser.executeWorkbench(async (vscode) => { - await vscode.commands.executeCommand( - "workbench.panel.output.focus" - ); - }); - - await selectOutputChannel(outputView, "Databricks Bundle Logs"); - console.log("Waiting for bundle to destroy"); // Wait for status to reach success await browser.waitUntil( async () => { try { + await browser.executeWorkbench(async (vscode) => { + await vscode.commands.executeCommand( + "workbench.panel.output.focus" + ); + }); + const outputView = await workbench + .getBottomBar() + .openOutputView(); + + if ( + (await outputView.getCurrentChannel()) !== + "Databricks Bundle Logs" + ) { + await outputView.selectChannel( + "Databricks Bundle Logs" + ); + } + const logs = (await outputView.getText()).join(""); console.log(logs); return ( diff --git a/packages/databricks-vscode/src/test/e2e/refresh_resource_explorer_on_yml_change.e2e.ts b/packages/databricks-vscode/src/test/e2e/refresh_resource_explorer_on_yml_change.e2e.ts index 6898df2fd..553570fcd 100644 --- a/packages/databricks-vscode/src/test/e2e/refresh_resource_explorer_on_yml_change.e2e.ts +++ b/packages/databricks-vscode/src/test/e2e/refresh_resource_explorer_on_yml_change.e2e.ts @@ -3,7 +3,6 @@ import {CustomTreeSection} from "wdio-vscode-service"; import { dismissNotifications, getViewSection, - selectOutputChannel, waitForLogin, } from "./utils/commonUtils.ts"; import { @@ -79,8 +78,7 @@ describe("Automatically refresh resource explorer", async function () { const outputView = await (await browser.getWorkbench()) .getBottomBar() .openOutputView(); - - await selectOutputChannel(outputView, "Databricks Bundle Logs"); + await outputView.selectChannel("Databricks Bundle Logs"); const jobDef = await createProjectWithJob( projectName, diff --git a/packages/databricks-vscode/src/test/e2e/run_dbconnect.ucws.e2e.ts b/packages/databricks-vscode/src/test/e2e/run_dbconnect.ucws.e2e.ts index 6b78d3d8a..9ab8e503c 100644 --- a/packages/databricks-vscode/src/test/e2e/run_dbconnect.ucws.e2e.ts +++ b/packages/databricks-vscode/src/test/e2e/run_dbconnect.ucws.e2e.ts @@ -23,7 +23,7 @@ async function checkOutputFile(path: string, expectedContent: string) { return fileContent.includes(expectedContent); }, { - timeout: 60_000, + timeout: 120_000, interval: 2000, timeoutMsg: `Output file "${path}" did not contain "${expectedContent}"`, } @@ -33,7 +33,7 @@ async function checkOutputFile(path: string, expectedContent: string) { describe("Run files on serverless compute", async function () { let projectDir: string; - this.timeout(3 * 60 * 1000); + this.timeout(6 * 60 * 1000); before(async () => { assert(process.env.WORKSPACE_PATH, "WORKSPACE_PATH doesn't exist"); @@ -109,6 +109,7 @@ describe("Run files on serverless compute", async function () { "# MAGIC select 1 + 1;", "# MAGIC select 'hello run;'", "# COMMAND ----------", + `import os`, `df = _sqldf.toPandas()`, `df.to_json(os.path.join(os.getcwd(), "databricks-run-notebook-output.json"))`, ].join("\n") @@ -118,6 +119,7 @@ describe("Run files on serverless compute", async function () { path.join(nestedDir, "databricks-notebook.py"), [ "# Databricks notebook source", + `import os`, `spark.sql('SELECT "hello world"').show()`, "# COMMAND ----------", "# DBTITLE 1,My cell title", @@ -207,6 +209,7 @@ describe("Run files on serverless compute", async function () { ); } await dependenciesInput.confirm(); + await waitForNotification("The following environment is selected"); await waitForNotification("Databricks Connect", "Install"); diff --git a/packages/databricks-vscode/src/test/e2e/run_files.e2e.ts b/packages/databricks-vscode/src/test/e2e/run_files.e2e.ts index eb1d1dced..b88a13c35 100644 --- a/packages/databricks-vscode/src/test/e2e/run_files.e2e.ts +++ b/packages/databricks-vscode/src/test/e2e/run_files.e2e.ts @@ -16,7 +16,7 @@ import { describe("Run files", async function () { let projectDir: string; - this.timeout(3 * 60 * 1000); + this.timeout(6 * 60 * 1000); before(async () => { assert(process.env.WORKSPACE_PATH, "WORKSPACE_PATH doesn't exist"); @@ -56,17 +56,7 @@ describe("Run files", async function () { const message = await notification.getMessage(); console.log("Message:", message); if (message.includes("Uploading bundle assets")) { - const elements = await notification.actions$.$$( - notification.locators.action - ); - console.log("Elements:", elements.length); - for (const element of elements) { - const text = await element.getText(); - if (text === "Cancel") { - await element.click(); - break; - } - } + await notification.takeAction("Cancel"); return true; } } diff --git a/packages/databricks-vscode/src/test/e2e/utils/commonUtils.ts b/packages/databricks-vscode/src/test/e2e/utils/commonUtils.ts index 3620a68df..752e90edc 100644 --- a/packages/databricks-vscode/src/test/e2e/utils/commonUtils.ts +++ b/packages/databricks-vscode/src/test/e2e/utils/commonUtils.ts @@ -6,8 +6,6 @@ import { ViewControl, ViewSection, InputBox, - OutputView, - TreeItem, } from "wdio-vscode-service"; // eslint-disable-next-line @typescript-eslint/naming-convention @@ -21,17 +19,6 @@ const ViewSectionTypes = [ ] as const; export type ViewSectionType = (typeof ViewSectionTypes)[number]; -export async function selectOutputChannel( - outputView: OutputView, - channelName: string -) { - if ((await outputView.getCurrentChannel()) === channelName) { - return; - } - outputView.locatorMap.BottomBarViews.outputChannels = `ul[aria-label="Output actions"] select`; - await outputView.selectChannel(channelName); -} - export async function findViewSection(name: ViewSectionType) { const workbench = await browser.getWorkbench(); @@ -54,9 +41,8 @@ export async function findViewSection(name: ViewSectionType) { ); const views = (await (await control?.openView())?.getContent()?.getSections()) ?? []; - console.log("Views:", views.length); for (const v of views) { - const title = await v.elem.getText(); + const title = await v.getTitle(); console.log("View title:", title); if (title === null) { continue; @@ -350,15 +336,28 @@ export async function waitForNotification(message: string, action?: string) { ); } -export async function waitForDeployment(outputView: OutputView) { +export async function waitForDeployment() { console.log("Waiting for deployment to finish"); - await browser.executeWorkbench(async (vscode) => { - await vscode.commands.executeCommand("workbench.panel.output.focus"); - }); - await selectOutputChannel(outputView, "Databricks Bundle Logs"); + const workbench = await driver.getWorkbench(); await browser.waitUntil( async () => { try { + await browser.executeWorkbench(async (vscode) => { + await vscode.commands.executeCommand( + "workbench.panel.output.focus" + ); + }); + const outputView = await workbench + .getBottomBar() + .openOutputView(); + + if ( + (await outputView.getCurrentChannel()) !== + "Databricks Bundle Logs" + ) { + await outputView.selectChannel("Databricks Bundle Logs"); + } + const logs = (await outputView.getText()).join(""); console.log("------------ Bundle Output ------------"); console.log(logs); @@ -378,22 +377,3 @@ export async function waitForDeployment(outputView: OutputView) { } ); } - -export async function getActionButton(item: TreeItem, label: string) { - const actions = await item.getActionButtons(); - if (actions.length > 0) { - for (const item of actions) { - console.log("Checking action button:", item.getLabel()); - console.log( - "Action button element:", - await (await item.elem).getHTML() - ); - const itemLabel = - item.getLabel() ?? (await item.elem.getAttribute("aria-label")); - if (itemLabel.indexOf(label) > -1) { - return item; - } - } - } - return undefined; -} diff --git a/packages/databricks-vscode/src/test/e2e/wdio.conf.ts b/packages/databricks-vscode/src/test/e2e/wdio.conf.ts index 8d3365e49..0c87aee19 100644 --- a/packages/databricks-vscode/src/test/e2e/wdio.conf.ts +++ b/packages/databricks-vscode/src/test/e2e/wdio.conf.ts @@ -169,7 +169,7 @@ export const config: Options.Testrunner = { return [ { "browserName": "vscode", - "browserVersion": engines.vscode.replace(/\^/, ""), + "browserVersion": engines.vscode.replace("^", ""), "wdio:vscodeOptions": { extensionPath: path.resolve( __dirname,