Skip to content

Commit 27162b6

Browse files
authored
Merge branch 'main' into haital-microsoft/fix-upgrade-notification-telemetry
2 parents 447c880 + 3858fdd commit 27162b6

5 files changed

Lines changed: 488 additions & 5 deletions
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Test Plan: Java Dependency — Permanent Delete
2+
#
3+
# Covers java.view.package.deleteFilePermanently (the "shift+delete" /
4+
# non-trash branch of file removal). The companion command
5+
# java.view.package.moveFileToTrash is already covered by
6+
# java-dep-file-operations.yaml.
7+
#
8+
# Why this is a separate plan
9+
# ───────────────────────────
10+
# The permanent-delete command has no plain-click UI affordance on regular
11+
# local files: the JAVA PROJECTS context-menu entry (package.json:812-820)
12+
# and the `delete` keybinding (package.json:485-490) are both gated on
13+
# `!explorerResourceMoveableToTrash`, so files in `test/maven` only ever
14+
# see "Delete" (move-to-trash). We therefore invoke the command directly
15+
# via id and rely on tree selection to supply the target node — the same
16+
# pattern the classpath plan uses for `removeLibrary`.
17+
#
18+
# The confirmation dialog also differs from moveFileToTrash: the prompt
19+
# says "permanently delete" instead of "delete", and the action button is
20+
# labelled "Delete" instead of "Move to Recycle Bin" (see
21+
# src/explorerCommands/delete.ts line 17 + getInformationMessage).
22+
#
23+
# Usage:
24+
# npx autotest run test/e2e-plans/java-dep-delete-permanent.yaml --vsix <path-to-vsix>
25+
26+
name: "Java Dependency — Permanent Delete"
27+
description: |
28+
Tests the java.view.package.deleteFilePermanently command on a regular
29+
Maven-project file. Invokes the command by id (no UI affordance on local
30+
files), confirms the "permanently delete" dialog, and verifies the file
31+
is gone from disk and from the Java Projects tree.
32+
33+
setup:
34+
extension: "redhat.java"
35+
vscodeVersion: "stable"
36+
workspace: "../maven"
37+
timeout: 180
38+
settings:
39+
java.configuration.checkProjectSettingsExclusions: false
40+
workbench.startupEditor: "none"
41+
42+
steps:
43+
# ── Setup: wait for LS, free sidebar space, focus Java Projects ──
44+
- id: "ls-ready"
45+
action: "waitForLanguageServer"
46+
# No `verify:` — `waitForLanguageServer` is itself the deterministic
47+
# readiness check. The AFTER screenshot may transiently show
48+
# "Java: Building - 0%" which a strict LLM mis-reads as a failure.
49+
timeout: 180
50+
51+
- id: "close-aux-bar"
52+
action: "executeVSCodeCommand workbench.action.closeAuxiliaryBar"
53+
verify: "Auxiliary bar (Chat) closed"
54+
55+
- id: "collapse-outline"
56+
action: "collapseSidebarSection OUTLINE"
57+
58+
- id: "collapse-timeline"
59+
action: "collapseSidebarSection TIMELINE"
60+
61+
- id: "collapse-workspace-root"
62+
action: "collapseWorkspaceRoot"
63+
64+
- id: "focus-java-projects"
65+
action: "executeVSCodeCommand javaProjectExplorer.focus"
66+
verify: "Java Projects view is focused"
67+
68+
- id: "wait-tree-load"
69+
action: "wait 3 seconds"
70+
71+
# ── Reveal App1.java via link-with-editor, then select it ──
72+
# Opening the file makes link-with-editor expand the tree path and
73+
# reveal+select App1 deterministically — much more reliable than
74+
# manual expandTreeItem chains on the virtualised tree.
75+
- id: "open-target-file"
76+
action: "open file App1.java"
77+
waitBefore: 2
78+
79+
- id: "collapse-workspace-root-2"
80+
action: "collapseWorkspaceRoot"
81+
82+
- id: "focus-java-projects-2"
83+
action: "executeVSCodeCommand javaProjectExplorer.focus"
84+
waitBefore: 2
85+
86+
# Click the tree item to guarantee it's the active selection — getCmdNode
87+
# (explorerCommands/utility.ts:38) falls back to `selectedNodes[0]` when
88+
# the command is invoked without a node argument. Linking-with-editor
89+
# already auto-selected App1 when the file was opened, but clicking
90+
# re-asserts the selection deterministically after the focus-java-projects
91+
# round trip.
92+
#
93+
# We intentionally do NOT verify the App1 tree row here. On 1024x768 CI
94+
# displays the row gets virtualised out of view in the brief window
95+
# between `open file` and the click, and an inView:"Java Projects"
96+
# verifyTreeItem then times out — even though the underlying selection
97+
# is set correctly (proven by the subsequent delete succeeding). The
98+
# post-delete `verify-file-gone` + `verify-tree-item-gone` block is the
99+
# authoritative ground truth for whether the right node was targeted.
100+
- id: "select-app1"
101+
action: "click App1 tree item"
102+
waitBefore: 1
103+
104+
# ── Invoke java.view.package.deleteFilePermanently ──
105+
# The handler at views/dependencyExplorer.ts:177 takes `node?: DataNode`.
106+
# With no node arg, getCmdNode uses the current selection (set by the
107+
# `click App1 tree item` step above). DataNode is a class instance with
108+
# methods (.getChildren()) so passing a POJO would crash — selection
109+
# fallback is the only viable path from a smoke-test.
110+
- id: "invoke-delete-permanently"
111+
action: "executeVSCodeCommand java.view.package.deleteFilePermanently"
112+
113+
# `expectConfirmDialog` waits for the dialog and clicks the first
114+
# recognized confirm button (autotest knows "Delete" is one of them, see
115+
# dialogOperations.ts:16). It's the strict variant — throws if no dialog
116+
# appears, surfacing a silently-failed command invocation immediately
117+
# instead of 15s later when verifyFile times out.
118+
- id: "confirm-delete"
119+
action: "expectConfirmDialog"
120+
121+
- id: "wait-after-delete"
122+
action: "wait 5 seconds"
123+
124+
# ── Verify deletion on disk AND in the tree ──
125+
# The disk check is the strongest signal: useTrash=false routes through
126+
# workspace.fs.delete with the OS-level unlink, so a passing verifyFile
127+
# exists:false proves the permanent-delete path actually fired (rather
128+
# than silently downgrading to a no-op or moving to trash).
129+
- id: "verify-file-gone"
130+
action: "wait 1 seconds"
131+
verifyFile:
132+
path: "${workspaceFolder}/src/main/java/com/mycompany/app1/App1.java"
133+
exists: false
134+
timeout: 15
135+
136+
- id: "verify-tree-item-gone"
137+
action: "wait 1 seconds"
138+
# No `verify:` — verifyTreeItem is authoritative.
139+
verifyTreeItem:
140+
name: "App1"
141+
exact: true
142+
visible: false
143+
inView: "Java Projects"
144+
timeout: 15
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# Test Plan: Java Dependency — Export Jar
2+
#
3+
# Covers java.view.package.exportJar — the multi-step wizard that builds a
4+
# runnable jar from a Java project. The command is contributed both as the
5+
# title-bar `$(export)` icon on the JAVA PROJECTS workspace-root node
6+
# (package.json:858-861, group=inline) and as a context-menu entry, but we
7+
# invoke it directly by id: the inline icon is rendered against the
8+
# `java:workspace` viewItem (not the Maven project node `my-app`), which
9+
# is fragile to locate by name, and ResolveJavaProject auto-resolves when
10+
# there's exactly one project in the workspace — so direct invocation
11+
# bypasses one wizard step that's not the command's responsibility.
12+
#
13+
# Wizard step machine (BuildArtifactTaskProvider.ts:284 `createJarFile`):
14+
# 1. ResolveJavaProject → auto when single-project; quick-pick otherwise
15+
# 2. ResolveMainClass → quick-pick of main classes + "<without main class>"
16+
# 3. GenerateJar
17+
# a. generateClasspaths → multi-select quick-pick if >1 dependency item
18+
# b. showSaveDialog → only if outputPath === "" (skipped when
19+
# java.project.exportJar.targetPath is set
20+
# to a non-empty value; we set it via a
21+
# user-level `settings:` block to keep the
22+
# output filename deterministic — see the
23+
# setup section below for why user-level
24+
# and not workspaceSettings)
25+
# c. Jdtls.exportJar → writes the jar file
26+
#
27+
# Verification strategy
28+
# ─────────────────────
29+
# The jar is written to a known absolute path inside the workspace
30+
# (`output.jar`). We assert with `verifyFile exists: true` — the strongest
31+
# possible signal that the full wizard completed end-to-end, not just that
32+
# the command was dispatched. The Jdtls export runs in a hidden Pseudoterminal
33+
# (BuildArtifactTaskProvider line 91: `presentationOptions.reveal = Never`),
34+
# so there is no terminal text to inspect; the file on disk is the only
35+
# unambiguous post-condition.
36+
#
37+
# Usage:
38+
# npx autotest run test/e2e-plans/java-dep-export-jar.yaml --vsix <path-to-vsix>
39+
40+
name: "Java Dependency — Export Jar"
41+
description: |
42+
Exercises the multi-step Export Jar wizard end-to-end on the maven
43+
fixture: triggers the command, picks the main class, accepts the default
44+
classpath element selection, and verifies that the resulting jar file
45+
exists at the configured target path.
46+
47+
setup:
48+
extension: "redhat.java"
49+
vscodeVersion: "stable"
50+
workspace: "../maven"
51+
# Bumped above the standard 180s — the wizard runs a full workspace build
52+
# (await buildWorkspace() in executeExportJarTask) before the first
53+
# quick-pick appears, which on a cold JDT-LS warmup commonly takes 60-90s.
54+
timeout: 360
55+
settings:
56+
java.configuration.checkProjectSettingsExclusions: false
57+
workbench.startupEditor: "none"
58+
# Pinning java.project.exportJar.targetPath to an absolute deterministic
59+
# path bypasses the showSaveDialog branch in GenerateJarExecutor
60+
# (BuildArtifactTaskProvider lines 240-244 short-circuit only when
61+
# outputPath === ""), and lets the verifyFile assertion target a stable
62+
# location regardless of how the fixture's worktree is named.
63+
#
64+
# We use user-level `settings:` (not `workspaceSettings:`) because
65+
# autotest's workspaceSettings merge uses JSON.parse on the existing
66+
# `.vscode/settings.json`, and the maven fixture's settings.json
67+
# contains JSONC `//` comments which fail JSON.parse. User settings
68+
# are written fresh each run (user-data-dir is wiped on launch) so
69+
# there is no JSONC merge hazard. The Settings.getExportJarTargetPath
70+
# config read is unscoped, so user-level setting takes effect identically.
71+
java.project.exportJar.targetPath: "${workspaceFolder}/output.jar"
72+
73+
steps:
74+
# ── Setup: wait for LS, free sidebar space, focus Java Projects ──
75+
- id: "ls-ready"
76+
action: "waitForLanguageServer"
77+
# No `verify:` — `waitForLanguageServer` is itself the deterministic
78+
# readiness check. The AFTER screenshot may transiently show
79+
# "Java: Building - 0%" which a strict LLM mis-reads as a failure.
80+
timeout: 180
81+
82+
- id: "close-aux-bar"
83+
action: "executeVSCodeCommand workbench.action.closeAuxiliaryBar"
84+
verify: "Auxiliary bar (Chat) closed"
85+
86+
- id: "collapse-outline"
87+
action: "collapseSidebarSection OUTLINE"
88+
89+
- id: "collapse-timeline"
90+
action: "collapseSidebarSection TIMELINE"
91+
92+
- id: "collapse-workspace-root"
93+
action: "collapseWorkspaceRoot"
94+
95+
- id: "focus-java-projects"
96+
action: "executeVSCodeCommand javaProjectExplorer.focus"
97+
verify: "Java Projects view is focused"
98+
99+
- id: "wait-tree-load"
100+
action: "wait 3 seconds"
101+
102+
# ── Trigger the Export Jar wizard ──
103+
# Direct command invocation avoids the brittle inline-icon-on-workspace-
104+
# node click path (the `$(export)` icon is contributed against viewItem
105+
# `java:workspace`, not against the Maven project node `my-app`, and
106+
# locating workspace-level inline icons in autotest is fragile).
107+
# ResolveJavaProject auto-resolves for single-project workspaces.
108+
- id: "invoke-export-jar"
109+
action: "executeVSCodeCommand java.view.package.exportJar"
110+
111+
# The wizard first triggers a full workspace build (await buildWorkspace()
112+
# in executeExportJarTask) before any UI appears. On a cold JDT-LS this
113+
# typically takes 30-60s; the Jdtls.getMainClasses fetch then needs
114+
# another 2-5s before the first quick-pick is shown. Wait generously.
115+
- id: "wait-build-complete"
116+
action: "wait 60 seconds"
117+
118+
# ── Step 2: pick the main class ──
119+
# The maven fixture has a single class with a `public static void main`
120+
# entry point: com.mycompany.app.App. App1 has no main, so the only
121+
# quick-pick options are "App" and "<without main class>". We pick "App"
122+
# explicitly so the resulting jar is runnable.
123+
- id: "pick-main-class"
124+
action: "select App option"
125+
# No `verify:` — selectPaletteOption is the action and verification in
126+
# one. The quick-pick closes on selection; the AFTER screenshot may
127+
# already show the next quick-pick (classpath elements), which a
128+
# strict LLM could mis-read as "App selection was lost".
129+
130+
- id: "wait-after-main-class"
131+
action: "wait 5 seconds"
132+
133+
# ── Step 3a: accept the pre-selected classpath elements ──
134+
# GenerateJarExecutor.generateClasspaths builds a list of runtime / test
135+
# output folders + dependency artifacts, pre-selects everything tagged
136+
# `runtime`, and shows a multi-select QuickPick. For the maven fixture
137+
# this includes target/classes plus any resolved JUnit jars under test
138+
# scope. The pre-selection is the sane default — accepting it gives a
139+
# runnable jar without needing to compute which items to check.
140+
#
141+
# `confirmQuickInput` presses Enter on the open quick-pick widget without
142+
# typing anything, which leaves selections untouched and submits.
143+
- id: "accept-classpath-elements"
144+
action: "confirmQuickInput"
145+
146+
# ── Step 3c: wait for Jdtls to generate the jar ──
147+
# Jdtls.exportJar writes the jar via a JDT LSP request. The custom
148+
# pseudoterminal stays hidden (presentationOptions.reveal=Never), so
149+
# there is no terminal-text signal — we just wait long enough for the
150+
# filesystem write to settle.
151+
- id: "wait-jar-generated"
152+
action: "wait 30 seconds"
153+
154+
# ── Verification: jar file exists at the configured target path ──
155+
# This is the strongest possible end-to-end check: the file appearing
156+
# on disk proves ResolveJavaProject + ResolveMainClass + generateClasspaths
157+
# + Jdtls.exportJar all completed in order. A failure here pinpoints
158+
# the wizard breaking; a pass means the full happy path worked.
159+
- id: "verify-jar-created"
160+
action: "wait 1 seconds"
161+
verifyFile:
162+
path: "${workspaceFolder}/output.jar"
163+
exists: true
164+
timeout: 60

test/e2e-plans/java-dep-new-types.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ steps:
7878

7979
- id: "select-interface"
8080
action: "select Interface option"
81-
verify: "Interface selected"
81+
# No `verify:` — LLM screenshot check is flaky when the quick-pick
82+
# advances immediately after selection (LLM sees the next page and
83+
# mistakes the advance for "selection not visible"). The downstream
84+
# fillQuickInput / file creation provides authoritative verification.
8285

8386
- id: "select-source-folder-1"
8487
action: "select src/main/java option"

0 commit comments

Comments
 (0)