Skip to content

Commit e3735f3

Browse files
committed
fix: update
1 parent 27368c8 commit e3735f3

File tree

5 files changed

+84
-40
lines changed

5 files changed

+84
-40
lines changed

AGENTS.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# vscode-java-dependency (Project Manager for Java)
2+
3+
VS Code Java 项目管理器,提供项目结构浏览和依赖管理。
4+
5+
## 项目定位
6+
7+
- **仓库**: https://github.com/microsoft/vscode-java-dependency
8+
- **Extension ID**: vscjava.vscode-java-dependency
9+
- **构建工具**: npm + Webpack
10+
- **入口**: `main.js`
11+
12+
## 目录结构
13+
14+
```
15+
src/
16+
├── controllers/ # 命令和上下文管理
17+
├── views/ # 项目浏览器树视图
18+
├── tasks/ # 项目任务
19+
├── java/ # JDT LS 集成
20+
└── utility/ # 工具函数
21+
22+
server/
23+
└── com.microsoft.jdtls.ext.core-*.jar # JDT LS 扩展插件
24+
```
25+
26+
## 关键功能
27+
28+
- Java Projects 树视图 (层级结构浏览)
29+
- 创建/脚手架 Java 项目
30+
- 管理引用库 (JAR 文件)
31+
- 导出 JAR 功能
32+
- 包和类成员浏览
33+
- Copilot/AI 辅助探索支持
34+
35+
## 依赖关系
36+
37+
**依赖**: vscode-java (redhat.java)
38+
**被依赖**: vscode-java-pack

test/e2e/tests/fileOperations.test.ts

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,27 @@ test.describe("File Operations", () => {
6969
// Expand to AppToRename
7070
await JavaOperator.expandTreePath(page, "my-app", "src/main/java", "com.mycompany.app");
7171

72-
// Click AppToRename and open context menu
72+
// Select AppToRename and trigger rename via F2
7373
const appToRename = page.getByRole(VSCode.TREE_ITEM_ROLE, { name: "AppToRename" }).first();
7474
await appToRename.click();
75-
await appToRename.click({ button: "right" });
7675
await page.waitForTimeout(Timeout.CLICK);
77-
78-
// Click Rename in context menu
79-
const renameItem = page.locator(".context-view .action-item a.action-label", { hasText: "Rename" });
80-
await renameItem.click();
76+
await page.keyboard.press("F2");
8177
await page.waitForTimeout(Timeout.CLICK);
8278

83-
// Fill in new name
84-
await VscodeOperator.fillQuickInput(page, "AppRenamed");
79+
// VS Code may show either a quick-input dialog or an inline rename editor.
80+
// Try the inline rename input first (common in modern VS Code).
81+
const inlineInput = page.locator(".monaco-inputbox input.rename-input");
82+
const quickInput = page.locator(".quick-input-widget input.input");
83+
84+
if (await inlineInput.isVisible({ timeout: 3_000 }).catch(() => false)) {
85+
await inlineInput.fill("AppRenamed");
86+
await inlineInput.press(VSCode.ENTER);
87+
} else if (await quickInput.isVisible({ timeout: 3_000 }).catch(() => false)) {
88+
await quickInput.fill("AppRenamed");
89+
await quickInput.press(VSCode.ENTER);
90+
}
91+
92+
await page.waitForTimeout(Timeout.CLICK);
8593

8694
// Handle confirmation dialog if it appears
8795
try {
@@ -93,33 +101,25 @@ test.describe("File Operations", () => {
93101
// Editor should open with renamed file
94102
const tabFound = await VscodeOperator.waitForEditorTab(page, "AppRenamed.java");
95103
expect(tabFound).toBeTruthy();
96-
97-
// Save via command to avoid focus issues
98-
await VscodeOperator.saveActiveEditor(page);
99104
});
100105

101106
test("delete Java file", async ({ page }) => {
102107
await JavaOperator.collapseFileExplorer(page);
103108
await JavaOperator.expandTreePath(page, "my-app", "src/main/java", "com.mycompany.app");
104109

110+
// Select AppToDelete and press Delete key
105111
const appToDelete = page.getByRole(VSCode.TREE_ITEM_ROLE, { name: "AppToDelete" }).first();
106112
await appToDelete.click();
107-
await appToDelete.click({ button: "right" });
108113
await page.waitForTimeout(Timeout.CLICK);
109-
110-
// Click Delete or "Delete Permanently"
111-
const deleteItem = page.locator(".context-view .action-item a.action-label")
112-
.filter({ hasText: /^Delete/ });
113-
await deleteItem.first().click();
114+
await page.keyboard.press("Delete");
114115
await page.waitForTimeout(Timeout.CLICK);
115116

116117
// Confirm deletion in dialog
117118
try {
118-
// Try common button labels
119119
const dialog = page.locator(".monaco-dialog-box");
120120
await dialog.waitFor({ state: "visible", timeout: 5_000 });
121121
const confirmBtn = dialog.getByRole(VSCode.BUTTON_ROLE)
122-
.filter({ hasText: /Move to Recycle Bin|Delete|OK/ });
122+
.filter({ hasText: /Move to Trash|Move to Recycle Bin|Delete|OK/ });
123123
await confirmBtn.first().click();
124124
} catch {
125125
// Dialog may not appear

test/e2e/tests/libraries.test.ts

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,21 @@ test.describe("Libraries & Project Creation", () => {
3232
});
3333

3434
test("add and remove JAR library", async ({ page }) => {
35-
// Expand to Referenced Libraries
36-
await JavaOperator.expandTreePath(page, "invisible", "Referenced Libraries");
37-
38-
// Click the add button on Referenced Libraries
39-
await VscodeOperator.clickTreeItemAction(
40-
page,
41-
"Referenced Libraries",
42-
"Add Jar Libraries to Project Classpath"
43-
);
44-
45-
// Type the jar path in the input
35+
// Use command palette to add a JAR — the "Referenced Libraries" node
36+
// only appears in the tree after a library has been added.
4637
const testRoot = path.join(__dirname, "..", "..", "..");
4738
const jarPath = path.join(testRoot, "test", "invisible", "libSource", "simple.jar");
39+
40+
await VscodeOperator.executeCommand(page, "Java: Add Jar Libraries to Project Classpath");
41+
await page.waitForTimeout(Timeout.CLICK);
4842
await VscodeOperator.fillQuickInput(page, jarPath);
4943

5044
// Wait for tree to update and verify the jar appears
45+
await JavaOperator.focusJavaProjects(page);
5146
const added = await VscodeOperator.waitForTreeItem(page, "simple.jar", 15_000);
5247
expect(added).toBeTruthy();
5348

54-
// Now remove it
49+
// Now remove it via tree action
5550
await VscodeOperator.clickTreeItem(page, "simple.jar");
5651
await VscodeOperator.clickTreeItemAction(page, "simple.jar", "Remove from Project Classpath");
5752

@@ -73,15 +68,14 @@ test.describe("Libraries & Project Creation", () => {
7368
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "java-new-project-"));
7469

7570
await VscodeOperator.executeCommand(page, "Java: Create Java Project");
76-
await page.waitForTimeout(Timeout.CLICK);
71+
// The build-tool quick pick may take a moment to appear
72+
await page.waitForTimeout(Timeout.TREE_EXPAND);
7773

7874
// Select "No build tools"
7975
await VscodeOperator.selectQuickPickItem(page, "No build tools");
8076

81-
// Enter the project location
82-
await VscodeOperator.fillQuickInput(page, tmpDir);
83-
84-
// Enter the project name
77+
// The project location dialog uses a native file picker on some platforms.
78+
// Enter the project name when prompted.
8579
await VscodeOperator.fillQuickInput(page, "helloworld");
8680

8781
// Wait for project files to be created

test/e2e/tests/projectExplorer.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ test.describe("Project Explorer", () => {
4141
const packageVisible = await VscodeOperator.waitForTreeItem(page, "com.mycompany.app", 15_000);
4242
expect(packageVisible).toBeTruthy();
4343

44-
const classVisible = await VscodeOperator.isTreeItemVisible(page, "App");
44+
// Use exact match to avoid matching "app", "App.java", "AppToDelete" etc.
45+
const classVisible = await page.getByRole(VSCode.TREE_ITEM_ROLE, { name: "App", exact: true })
46+
.isVisible().catch(() => false);
4547
expect(classVisible).toBeTruthy();
4648
});
4749

test/e2e/utils/javaOperator.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,28 @@ export default class JavaOperator {
7070
/**
7171
* Expands tree items along a path (e.g. "my-app" → "src/main/java" → "com.mycompany.app").
7272
*
73-
* Checks `aria-expanded` before clicking so that an already-expanded node
74-
* is not accidentally collapsed (VS Code auto-expands single-child trees).
73+
* Waits for each item's `aria-expanded` attribute to appear before clicking,
74+
* because VS Code only sets it after the tree data provider's `getChildren()`
75+
* has returned — until then the node is treated as a leaf.
7576
*/
7677
static async expandTreePath(page: Page, ...labels: string[]): Promise<void> {
7778
for (const label of labels) {
7879
const item = page.getByRole(VSCode.TREE_ITEM_ROLE, { name: label }).first();
7980
await item.waitFor({ state: "visible", timeout: 15_000 });
81+
82+
// Wait for the node to become expandable (aria-expanded present).
83+
await expect.poll(async () => {
84+
return await item.getAttribute("aria-expanded");
85+
}, {
86+
message: `Tree item "${label}" did not become expandable`,
87+
timeout: 15_000,
88+
}).toBeTruthy();
89+
8090
const expanded = await item.getAttribute("aria-expanded");
8191
if (expanded !== "true") {
8292
await item.click();
93+
await page.waitForTimeout(Timeout.TREE_EXPAND);
8394
}
84-
await page.waitForTimeout(Timeout.TREE_EXPAND);
8595
}
8696
}
8797

0 commit comments

Comments
 (0)