Skip to content

Commit fe1b167

Browse files
authored
Merge branch 'main' into experiment/lsp-tool-contract-tuning
2 parents 4d7d167 + 0dc2467 commit fe1b167

1 file changed

Lines changed: 195 additions & 0 deletions

File tree

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# Test Plan: Java Dependency — Copy File / Relative Paths
2+
#
3+
# Covers two clipboard commands contributed against the Java Projects view:
4+
# - java.view.package.copyFilePath (Copy Path)
5+
# - java.view.package.copyRelativeFilePath (Copy Relative Path)
6+
#
7+
# Why a dedicated plan
8+
# ────────────────────
9+
# These two commands have **no on-screen side effect at all** — they don't
10+
# open a dialog, write a file, change the tree, or post a notification.
11+
# The only observable consequence is what ends up on the OS clipboard.
12+
# Verifying them therefore requires an autotest clipboard primitive
13+
# (writeClipboard / readClipboard / verifyClipboard) added in 0.7.15.
14+
#
15+
# Both handlers (dependencyExplorer.ts:159 and :165) are thin wrappers
16+
# around VS Code's built-in `copyFilePath` / `copyRelativeFilePath`:
17+
#
18+
# instrumentOperationAsVsCodeCommand(Commands.VIEW_PACKAGE_COPY_FILE_PATH,
19+
# (node?: DataNode) => {
20+
# const cmdNode = getCmdNode(this._dependencyViewer.selection, node);
21+
# if (cmdNode?.uri) {
22+
# commands.executeCommand("copyFilePath", Uri.parse(cmdNode.uri));
23+
# }
24+
# })
25+
#
26+
# So the values landing on the clipboard are whatever VS Code's built-ins
27+
# write — i.e. the URI's fsPath (absolute, OS-native separators) and the
28+
# workspace-relative path (no leading slash).
29+
#
30+
# Invocation pattern (same as delete-permanent.yaml)
31+
# ──────────────────────────────────────────────────
32+
# Both commands accept a `node?: DataNode` parameter and fall back to
33+
# the current tree selection via getCmdNode (explorerCommands/utility.ts:38).
34+
# DataNode is a class instance, not a POJO, so passing a synthetic node
35+
# from YAML would crash. Selection fallback is the only viable smoke-test
36+
# path: open a file via link-with-editor (auto-selects in the tree) →
37+
# click the tree row to re-assert selection after focus changes →
38+
# invoke the command by id.
39+
#
40+
# Cross-OS path separator handling
41+
# ────────────────────────────────
42+
# Windows fsPaths use `\` and POSIX uses `/`. The assertions therefore
43+
# combine three orthogonal checks per command:
44+
# - `contains: "App.java"` — leaf filename, identical on every OS
45+
# - `matches: regex` — accepts both separators between segments
46+
# - `notContains: <sentinel>` — proves the clipboard was overwritten
47+
# (we seed a sentinel before each command)
48+
#
49+
# A pure `exact:` match would force a per-OS conditional plan; the regex
50+
# approach keeps a single plan that's portable Linux ↔ Windows ↔ macOS.
51+
#
52+
# Usage:
53+
# npx autotest run test/e2e-plans/java-dep-copy-paths.yaml --vsix <path-to-vsix>
54+
55+
name: "Java Dependency — Copy File / Relative Paths"
56+
description: |
57+
Exercises java.view.package.copyFilePath and java.view.package.copyRelativeFilePath
58+
on a Maven-project source file. Seeds a clipboard sentinel before each command,
59+
invokes the command by id (using the current tree selection), and verifies the
60+
resulting clipboard text via path-shape regex + filename containment +
61+
sentinel-overwritten check.
62+
63+
setup:
64+
extension: "redhat.java"
65+
vscodeVersion: "stable"
66+
workspace: "../maven"
67+
timeout: 180
68+
settings:
69+
java.configuration.checkProjectSettingsExclusions: false
70+
workbench.startupEditor: "none"
71+
72+
steps:
73+
# ── Setup: wait for LS, free sidebar space, focus Java Projects ──
74+
- id: "ls-ready"
75+
action: "waitForLanguageServer"
76+
# No `verify:` — `waitForLanguageServer` is itself the deterministic
77+
# readiness check. The AFTER screenshot may transiently show
78+
# "Java: Building - 0%" which a strict LLM mis-reads as a failure.
79+
timeout: 180
80+
81+
- id: "close-aux-bar"
82+
action: "executeVSCodeCommand workbench.action.closeAuxiliaryBar"
83+
84+
- id: "collapse-outline"
85+
action: "collapseSidebarSection OUTLINE"
86+
87+
- id: "collapse-timeline"
88+
action: "collapseSidebarSection TIMELINE"
89+
90+
- id: "collapse-workspace-root"
91+
action: "collapseWorkspaceRoot"
92+
93+
- id: "focus-java-projects"
94+
action: "executeVSCodeCommand javaProjectExplorer.focus"
95+
96+
- id: "wait-tree-load"
97+
action: "wait 3 seconds"
98+
99+
# ── Reveal & select App.java via link-with-editor ──
100+
# Same pattern as java-dep-delete-permanent.yaml: opening the file
101+
# makes link-with-editor reveal+select the tree node deterministically,
102+
# which is more reliable than chained expandTreeItem on the virtualised
103+
# tree on 1024x768 CI displays.
104+
- id: "open-target-file"
105+
action: "open file App.java"
106+
waitBefore: 2
107+
108+
- id: "collapse-workspace-root-2"
109+
action: "collapseWorkspaceRoot"
110+
111+
- id: "focus-java-projects-2"
112+
action: "executeVSCodeCommand javaProjectExplorer.focus"
113+
waitBefore: 2
114+
115+
# Click the App tree row to assert it as the active selection. The Java
116+
# Projects view labels source files by class name (no `.java` suffix —
117+
# the leaf row reads "App"), and a default substring `click App tree
118+
# item` would also match the project node "my-app" first (case-insensitive
119+
# substring), silently selecting the project — whose URI is the workspace
120+
# root, not the file. We use the `exact` modifier (autotest ≥ 0.7.16) so
121+
# only the leaf row labeled exactly "App" matches.
122+
- id: "select-app"
123+
action: "click App tree item exact"
124+
waitBefore: 1
125+
126+
# ── Cycle 1: java.view.package.copyFilePath (absolute path) ──
127+
# Sentinel proves the clipboard was actually written — without it, a
128+
# silently-no-op command would pass if the OS clipboard happened to
129+
# already contain "App.java" from any earlier action on the host.
130+
- id: "seed-clipboard-absolute"
131+
action: "writeClipboard __SENTINEL_BEFORE_COPY_FILE_PATH__"
132+
133+
- id: "invoke-copy-file-path"
134+
action: "executeVSCodeCommand java.view.package.copyFilePath"
135+
waitBefore: 1
136+
137+
# Verify the clipboard contents post-action.
138+
#
139+
# • `contains: "App.java"` — the leaf filename is identical on every OS
140+
# • `matches: ...` — accepts either `\` (Windows) or `/` (POSIX) between
141+
# path segments, and asserts the URL-decoded fsPath structure
142+
# `maven/src/main/java/com/mycompany/app/App.java`. The `[\\\\/]`
143+
# escapes to a literal `[\/]` character class in the compiled regex.
144+
# • `notContains: <sentinel>` — proves the seed was overwritten and the
145+
# command isn't silently no-op'ing into a stale clipboard.
146+
- id: "verify-absolute-path"
147+
action: "wait 1 seconds"
148+
verifyClipboard:
149+
contains: "App.java"
150+
matches: "maven[\\\\/]src[\\\\/]main[\\\\/]java[\\\\/]com[\\\\/]mycompany[\\\\/]app[\\\\/]App\\.java$"
151+
notContains: "__SENTINEL_BEFORE_COPY_FILE_PATH__"
152+
timeout: 10
153+
154+
# ── Cycle 2: java.view.package.copyRelativeFilePath ──
155+
# The selection persists across the previous command, so no re-click.
156+
# A fresh sentinel is still needed — the cycle-1 clipboard now contains
157+
# the absolute path, which would trivially satisfy any leaf-only check.
158+
#
159+
# Cross-platform note: VS Code's built-in `copyRelativeFilePath` computes
160+
# `path.relative(workspaceFolderUri, fileUri)` and falls back to the
161+
# absolute fsPath when the file URI isn't a member of any workspace
162+
# folder. On Windows the URI we pass — `Uri.parse(cmdNode.uri)` from
163+
# JDT.LS — can differ from VS Code's registered workspace folder URI
164+
# in drive-letter case or percent-encoding, so the membership test
165+
# fails and we get the absolute path back. On POSIX the URIs match and
166+
# the relative form is produced. The assertions below tolerate both:
167+
# they prove the command fired and overwrote the sentinel with a
168+
# well-formed path ending in the expected package + class layout, but
169+
# do not require the leading-`src` shape that only POSIX produces.
170+
- id: "seed-clipboard-relative"
171+
action: "writeClipboard __SENTINEL_BEFORE_COPY_RELATIVE_FILE_PATH__"
172+
173+
- id: "invoke-copy-relative-file-path"
174+
action: "executeVSCodeCommand java.view.package.copyRelativeFilePath"
175+
waitBefore: 1
176+
177+
# Verify the clipboard after copyRelativeFilePath.
178+
#
179+
# • `contains: "App.java"` — leaf filename appears (OS-independent)
180+
# • `matches: ...` — same path-suffix shape as the absolute assertion
181+
# above. Anchored to `$` so it matches whether the path is the
182+
# POSIX relative form `src/main/java/.../App.java` (single match
183+
# of the suffix) or the Windows absolute fallback
184+
# `C:\...\maven\src\main\java\.../App.java` (suffix at end).
185+
# • `notContains: <sentinel>` — proves the seed was overwritten,
186+
# which is the strongest signal that the wrapper command actually
187+
# forwarded to the built-in (rather than silently no-op'ing on a
188+
# missing selection).
189+
- id: "verify-relative-path"
190+
action: "wait 1 seconds"
191+
verifyClipboard:
192+
contains: "App.java"
193+
matches: "src[\\\\/]main[\\\\/]java[\\\\/]com[\\\\/]mycompany[\\\\/]app[\\\\/]App\\.java$"
194+
notContains: "__SENTINEL_BEFORE_COPY_RELATIVE_FILE_PATH__"
195+
timeout: 10

0 commit comments

Comments
 (0)