Skip to content

Commit cc33968

Browse files
authored
Cover most of the configuration flow in an E2E test (#33)
1 parent 5757182 commit cc33968

File tree

8 files changed

+403
-84
lines changed

8 files changed

+403
-84
lines changed

.github/workflows/push.yml

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ jobs:
8080

8181
env:
8282
VSCODE_TEST_VERSION: ${{ matrix.vscode-version }}
83+
DATABRICKS_HOST: ${{ secrets.DATABRICKS_HOST }}
84+
DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }}
85+
DATABRICKS_CLUSTER_ID: ${{ secrets.DATABRICKS_CLUSTER_ID }}
8386

8487
steps:
8588
- uses: actions/checkout@v3
@@ -114,7 +117,7 @@ jobs:
114117
run: yarn run test:unit
115118
working-directory: packages/databricks-vscode
116119

117-
- name: Prepare Integration Tests
120+
- name: Integration Tests
118121
uses: nick-fields/retry@v2
119122
with:
120123
max_attempts: 3
@@ -124,14 +127,7 @@ jobs:
124127
command: |
125128
cd packages/databricks-vscode
126129
yarn run test:integ:prepare
127-
128-
- name: Integration Tests
129-
run: yarn run test:integ:run
130-
working-directory: packages/databricks-vscode
131-
env:
132-
DATABRICKS_HOST: ${{ secrets.DATABRICKS_HOST }}
133-
DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }}
134-
DATABRICKS_CLUSTER_ID: ${{ secrets.DATABRICKS_CLUSTER_ID }}
130+
yarn run test:integ:run
135131
136132
package:
137133
name: Package VSIX

packages/databricks-vscode/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@
195195
"test:watch": "tsc -p . -w --outDir out",
196196
"test:unit": "node ./out/test/runTest.js",
197197
"test:integ:prepare": "yarn run vscode:package && extest get-vscode --type ${VSCODE_TEST_VERSION:-stable} --storage /tmp/vscode-test-databricks && extest get-chromedriver --storage /tmp/vscode-test-databricks && extest install-vsix -f databricks-0.0.1.vsix --storage /tmp/vscode-test-databricks",
198-
"test:integ:run": "yarn run test:compile && extest run-tests --storage /tmp/vscode-test-databricks --code_settings src/test/e2e/settings.json out/test/e2e/*.e2e.js",
198+
"test:integ:run": "yarn run test:compile && ts-node src/test/e2e/scripts/e2e.ts --storage /tmp/vscode-test-databricks --code_settings src/test/e2e/settings.json out/test/e2e/*.e2e.js",
199199
"test:integ": "yarn run test:integ:prepare && yarn run test:integ:run",
200200
"test": "yarn run test:compile && yarn run compile && yarn run test:lint && yarn run test:unit",
201201
"build": "yarn run vscode:prepublish",
@@ -220,6 +220,7 @@
220220
"tmp-promise": "^3.0.3",
221221
"ts-loader": "^9.3.1",
222222
"ts-mockito": "^2.6.1",
223+
"ts-node": "^10.9.1",
223224
"typescript": "^4.7.4",
224225
"vsce": "^2.10.0",
225226
"vscode-extension-tester": "^4.3.0",
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import assert = require("node:assert");
2+
import path = require("node:path");
3+
import * as fs from "fs/promises";
4+
import {
5+
VSBrowser,
6+
WebDriver,
7+
ActivityBar,
8+
InputBox,
9+
Workbench,
10+
TreeItem,
11+
ContextMenu,
12+
CustomTreeSection,
13+
} from "vscode-extension-tester";
14+
import {getViewSection, openCommandPrompt, waitForTreeItems} from "./utils";
15+
16+
describe("Configure Databricks Extension", function () {
17+
// these will be populated by the before() function
18+
let browser: VSBrowser;
19+
let driver: WebDriver;
20+
let projectDir: string;
21+
22+
// this will be populated by the tests
23+
let clusterId: string;
24+
25+
this.timeout(20_000);
26+
27+
before(async () => {
28+
browser = VSBrowser.instance;
29+
driver = browser.driver;
30+
31+
assert(process.env["PROJECT_DIR"]);
32+
projectDir = process.env["PROJECT_DIR"];
33+
});
34+
35+
it("should open VSCode", async () => {
36+
const title = await driver.getTitle();
37+
assert(title.indexOf("Get Started") >= 0);
38+
});
39+
40+
it("should open project folder", async () => {
41+
await fs.writeFile(path.join(projectDir, "test.txt"), "test");
42+
(await new ActivityBar().getViewControl("Explorer"))?.openView();
43+
44+
const workbench = new Workbench();
45+
const prompt = await openCommandPrompt(workbench);
46+
await prompt.setText(">File: Open Folder");
47+
await prompt.confirm();
48+
49+
const input = await InputBox.create();
50+
await input.setText(projectDir);
51+
await input.confirm();
52+
53+
// wait for reload to complete
54+
await new Promise((resolve) => setTimeout(resolve, 3000));
55+
});
56+
57+
it("should open databricks panel and login", async () => {
58+
const section = await getViewSection("Configuration");
59+
assert(section);
60+
const welcome = await section.findWelcomeContent();
61+
assert(welcome);
62+
const buttons = await welcome.getButtons();
63+
assert(buttons);
64+
assert(buttons.length > 0);
65+
await buttons[0].click();
66+
67+
const input = await InputBox.create();
68+
await input.selectQuickPick(1);
69+
70+
assert(await waitForTreeItems(section));
71+
});
72+
73+
it("should dismiss notifications", async () => {
74+
const notifications = await new Workbench().getNotifications();
75+
for (const n of notifications) {
76+
await n.dismiss();
77+
}
78+
});
79+
80+
it("shoult list clusters", async () => {
81+
const section = await getViewSection("Clusters");
82+
assert(section);
83+
const tree = section as CustomTreeSection;
84+
85+
assert(await waitForTreeItems(tree));
86+
87+
const items = await tree.getVisibleItems();
88+
const labels = await Promise.all(items.map((item) => item.getLabel()));
89+
assert(labels.length > 0);
90+
});
91+
92+
it.skip("should filter clusters", async () => {
93+
// test is skipped because context menus currently don't work in vscode-extension-tester
94+
// https://github.com/redhat-developer/vscode-extension-tester/issues/444
95+
96+
const section = await getViewSection("Clusters");
97+
assert(section);
98+
const action = await section!.getAction("Filter clusters ...");
99+
assert(action);
100+
101+
await action.click();
102+
const menu = new ContextMenu(new Workbench());
103+
let item = await menu.getItem("Created by me");
104+
await item?.click();
105+
106+
const items = await section.getVisibleItems();
107+
assert(items.length > 0);
108+
});
109+
110+
it("should attach cluster", async () => {
111+
const section = await getViewSection("Clusters");
112+
assert(section);
113+
114+
const items = await section.getVisibleItems();
115+
assert(items.length > 0);
116+
117+
// find top level cluster tree item
118+
let item: TreeItem | undefined;
119+
for (const i of items) {
120+
if (await (i as TreeItem).hasChildren()) {
121+
item = i as TreeItem;
122+
break;
123+
}
124+
}
125+
assert(item);
126+
127+
const buttons = await (item as TreeItem).getActionButtons();
128+
await buttons[0].click();
129+
130+
// check if cluster is attached
131+
const config = await getViewSection("Configuration");
132+
assert(config);
133+
const configTree = config as CustomTreeSection;
134+
135+
assert(await waitForTreeItems(configTree));
136+
137+
const configItems = await configTree.getVisibleItems();
138+
139+
let clusterConfigItem: TreeItem | undefined;
140+
const itemLabel = await item.getLabel();
141+
for (const i of configItems) {
142+
const label = await i.getLabel();
143+
if (label === `Cluster: ${itemLabel}`) {
144+
clusterConfigItem = i;
145+
break;
146+
}
147+
}
148+
assert(clusterConfigItem);
149+
150+
// get cluster ID
151+
const clusterPropsItems = await clusterConfigItem.getChildren();
152+
const clusterProps: Record<string, string> = {};
153+
for (const i of clusterPropsItems) {
154+
clusterProps[await i.getLabel()] = (await i.getDescription()) || "";
155+
}
156+
157+
// store cluster ID in test suite scope
158+
clusterId = clusterProps["Cluster ID:"];
159+
assert(clusterId);
160+
});
161+
162+
it("should write the project config file", async () => {
163+
let projectConfig = JSON.parse(
164+
await fs.readFile(
165+
path.join(projectDir, ".databricks", "project.json"),
166+
"utf-8"
167+
)
168+
);
169+
170+
assert.deepEqual(projectConfig, {
171+
clusterId,
172+
profile: "DEFAULT",
173+
});
174+
});
175+
});

packages/databricks-vscode/src/test/e2e/happy_path.e2e.ts

Lines changed: 0 additions & 72 deletions
This file was deleted.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* eslint-disable @typescript-eslint/naming-convention */
2+
import {spawn} from "child_process";
3+
import * as assert from "assert";
4+
import * as fs from "fs/promises";
5+
import * as path from "path";
6+
import * as tmp from "tmp-promise";
7+
8+
/**
9+
* Create a temporary directory for the test and populate the Databricks config file
10+
* with values taken from environment variables
11+
*/
12+
async function main(args: string[]) {
13+
assert(
14+
process.env["DATABRICKS_HOST"],
15+
"Environment variable DATABRICKS_HOST must be set"
16+
);
17+
assert(
18+
process.env["DATABRICKS_TOKEN"],
19+
"Environment variable DATABRICKS_TOKEN must be set"
20+
);
21+
assert(
22+
process.env["DATABRICKS_CLUSTER_ID"],
23+
"Environment variable DATABRICKS_CLUSTER_ID must be set"
24+
);
25+
26+
const {path: projectDir, cleanup} = await tmp.dir();
27+
try {
28+
await fs.writeFile(
29+
path.join(projectDir, ".databrickscfg"),
30+
`[DEFAULT]
31+
host = ${process.env["DATABRICKS_HOST"]}
32+
token = ${process.env["DATABRICKS_TOKEN"]}`
33+
);
34+
35+
const child = spawn("extest", ["run-tests", ...args], {
36+
env: {
37+
DATABRICKS_CLUSTER_ID: process.env["DATABRICKS_CLUSTER_ID"],
38+
PROJECT_DIR: projectDir,
39+
DATABRICKS_CONFIG_FILE: path.join(projectDir, ".databrickscfg"),
40+
PATH: process.env["PATH"],
41+
},
42+
stdio: "inherit",
43+
shell: true,
44+
});
45+
46+
const code: number = await new Promise((resolve) =>
47+
child.on("exit", resolve)
48+
);
49+
50+
process.exit(code);
51+
} finally {
52+
cleanup();
53+
}
54+
}
55+
56+
main(process.argv.slice(2));

packages/databricks-vscode/src/test/e2e/settings.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,5 @@
22
"typescript.updateImportsOnFileMove.enabled": "always",
33
"files.simpleDialog.enable": true,
44
"workbench.editor.enablePreview": true,
5-
"workbench.colorTheme": "Default Light+",
65
"window.newWindowDimensions": "default"
76
}

0 commit comments

Comments
 (0)