diff --git a/test/e2e-plans/java-dep-build-lifecycle.yaml b/test/e2e-plans/java-dep-build-lifecycle.yaml new file mode 100644 index 00000000..ab650c0a --- /dev/null +++ b/test/e2e-plans/java-dep-build-lifecycle.yaml @@ -0,0 +1,167 @@ +# Test Plan: Java Dependency — Build Lifecycle +# +# Covers the project build / rebuild / reload commands contributed by +# vscode-java-dependency. Each command is invoked through the documented +# entry point (view title-bar action, overflow menu, project context menu, +# or editor title-bar action) and verified by waiting for the Java Language +# Server to return to the Ready state. +# +# Commands exercised: +# - java.project.build.workspace (Build All — title-bar tools icon) +# - java.project.rebuild.workspace (Rebuild All — overflow menu) +# - java.project.build.project (Build Project — project context menu) +# - java.project.rebuild (Rebuild Project — project context menu) +# - java.project.reloadProjectFromActiveFile (Reload Project — pom.xml editor title) +# +# Note: java.project.clean.workspace is intentionally omitted from this plan +# because the JDT.LS clean command triggers a VS Code window reload, which +# tears down the autotest browser session. +# +# Verification strategy +# ───────────────────── +# Build commands have no visible editor side-effect — they trigger a +# background compilation whose progress is reflected only in the status bar +# (and briefly in the Java Language Server progress notifications). For each +# build / rebuild, we run the command and then call `waitForLanguageServer`, +# which polls the status bar until it returns to "Java: Ready" and the +# post-Ready "Building - X%" phase has settled. A non-fatal command is +# enough for the step to pass — the test asserts that the command does not +# leave the LS hung or in an error state. +# +# Usage: +# npx autotest run test/e2e-plans/java-dep-build-lifecycle.yaml --vsix + +name: "Java Dependency — Build Lifecycle" +description: | + Tests the build / rebuild / reload commands contributed by the Java + Project Manager. Each command is verified by waiting for the Java + Language Server to return to the Ready state after the command runs. + +setup: + extension: "redhat.java" + vscodeVersion: "stable" + workspace: "../maven" + timeout: 240 + settings: + java.configuration.checkProjectSettingsExclusions: false + workbench.startupEditor: "none" + +steps: + # ── Setup ── + - id: "ls-ready" + action: "waitForLanguageServer" + timeout: 180 + + - id: "close-aux-bar" + action: "executeVSCodeCommand workbench.action.closeAuxiliaryBar" + verify: "Auxiliary bar (Chat) closed" + + # Collapse the MAVEN workspace-folder pane so JAVA PROJECTS gets the full + # vertical space. OUTLINE and TIMELINE are collapsed by default in fresh + # sessions, so no explicit step is needed. + - id: "collapse-maven-pane" + action: "collapseSidebarSection maven" + + - id: "focus-java-projects" + action: "executeVSCodeCommand javaProjectExplorer.focus" + verify: "Java Projects view is focused" + + - id: "wait-tree-load" + action: "wait 3 seconds" + + # ── Test 1: Build All (incremental) — Java Projects view title-bar button ── + # The "Build All" toolbar action ($(tools) icon) is contributed under + # view/title group navigation@30 in package.json. Clicking it through the + # UI exercises the full button-rendering + when-clause + command-dispatch + # chain — unlike executeVSCodeCommand, which would only hit the command + # bus directly. + - id: "trigger-build-all" + action: 'clickViewTitleAction "Java Projects" "Build All"' + + - id: "wait-build-all" + action: "waitForLanguageServer" + timeout: 120 + + # ── Test 2: Rebuild All (full compile) — Java Projects overflow menu ── + # "Rebuild All" lives in view/title group overflow_20@5, so it is reached + # via the "Views and More Actions..." (...) overflow menu. The + # clickViewTitleAction helper automatically falls through from the direct + # button path to the overflow menu when the action is not present in the + # toolbar's navigation group. + - id: "trigger-rebuild-all" + action: 'clickViewTitleAction "Java Projects" "Rebuild All"' + + - id: "wait-rebuild-all" + action: "waitForLanguageServer" + timeout: 180 + + # ── Test 3: Build Project (per-project, via context menu) ── + # The `java.project.build.project` command requires a project URI, so it + # is gated behind the project context-menu in package.json (8_execution@5 + # when viewItem matches /java:project.*\+java.*\+uri/). Invoke it via the + # project node context menu — the menu surface that real users hit. + - id: "click-project-build" + action: "click my-app tree item" + waitBefore: 1 + + - id: "context-build-project" + action: "contextMenu my-app Build Project" + # No `verify:` — context-menu click has no immediate visible effect + # beyond closing the menu; waitForLanguageServer below is the ground + # truth that the build executed and the LS settled. + + - id: "wait-build-project" + action: "waitForLanguageServer" + timeout: 120 + + # ── Test 4: Rebuild Project (per-project, via context menu) ── + - id: "click-project-rebuild" + action: "click my-app tree item" + waitBefore: 1 + + - id: "context-rebuild-project" + action: "contextMenu my-app Rebuild Project" + + - id: "wait-rebuild-project" + action: "waitForLanguageServer" + timeout: 180 + + # ── Test 5: Reload Project (editor title-bar action on pom.xml) ── + # `java.project.reloadProjectFromActiveFile` is contributed in editor/title + # group navigation when both `java:reloadProjectActive` and `javaLSReady` + # are true. The `java:reloadProjectActive` key is only set after the + # project file (pom.xml / build.gradle) has been modified — opening an + # unchanged pom.xml is NOT enough to make the $(sync) button appear. + # + # To exercise the real UI flow: + # 1. Open pom.xml. + # 2. Type a space at the cursor → file becomes dirty. + # 3. Save → JDT.LS detects the build file change and sets + # `java:reloadProjectActive`, which renders the $(sync) "Reload + # Java Project" button in the editor title bar. + # 4. Click the title-bar button → reload kicks off. + # 5. waitForLanguageServer confirms the reload completed. + # 6. Undo + save restores pom.xml to its original content so the + # fixture is left clean for subsequent runs. + # ── Test 5: Reload Project From Active File ── + # `java.project.reloadProjectFromActiveFile` is contributed to editor/title + # group navigation only when `java:reloadProjectActive && javaLSReady` are + # both true. The `java:reloadProjectActive` key is set by redhat.java when + # JDT.LS detects an out-of-date project descriptor — but that signal is + # racy and inconsistent for synthetic changes (trivial whitespace edits + # often get absorbed without flipping the key, and a substantive edit + # would risk corrupting the fixture pom.xml). For deterministic CI + # behaviour this step therefore invokes the command id directly through + # the keybinding-bridge path. The fact that the command exists and runs + # without breaking the language server is still meaningful coverage, + # complementing the UI-driven tests above. + - id: "open-pom" + action: "open file pom.xml" + waitBefore: 3 + + - id: "trigger-reload-project" + action: "executeVSCodeCommand java.project.reloadProjectFromActiveFile" + + - id: "wait-reload-project" + action: "waitForLanguageServer" + timeout: 180 diff --git a/test/e2e-plans/java-dep-new-types.yaml b/test/e2e-plans/java-dep-new-types.yaml new file mode 100644 index 00000000..1477737c --- /dev/null +++ b/test/e2e-plans/java-dep-new-types.yaml @@ -0,0 +1,294 @@ +# Test Plan: Java Dependency — New File Types +# +# Covers the "New..." quick-pick options from the Java Projects view that are +# NOT already covered by java-dep-file-operations.yaml (which only tests +# `New Class` and `New Package`). +# +# Commands exercised (each invoked through the New... quick-pick on a node): +# - java.view.package.newJavaInterface (Interface) +# - java.view.package.newJavaEnum (Enum) +# - java.view.package.newJavaAnnotation (Annotation) +# - java.view.package.newJavaAbstractClass (Abstract Class) +# - java.view.package.newFile ("File" option) +# - java.view.package.newFolder ("Folder" option) +# +# Pattern for each type (same as the existing New Class flow): +# 1. click `my-app` in the JAVA PROJECTS view +# 2. clickTreeItemAction my-app New... (triggers java.view.package.new) +# 3. select option in the quick pick +# 4. select src/main/java source-folder option (where applicable) +# 5. fillQuickInput +# 6. verifyEditorTab — confirms the new file was created and opened +# +# Between each cycle the previously-created file is saved + all editors are +# closed and the JAVA PROJECTS tree is collapsed, mirroring the technique +# used in java-dep-file-operations.yaml. +# +# Usage: +# npx autotest run test/e2e-plans/java-dep-new-types.yaml --vsix + +name: "Java Dependency — New File Types" +description: | + Tests all the "New ..." quick-pick options in the Java Projects view that + are not already covered by java-dep-file-operations.yaml: + Interface / Enum / Annotation / Abstract Class / File / Folder. + +setup: + extension: "redhat.java" + vscodeVersion: "stable" + workspace: "../maven" + timeout: 240 + settings: + java.configuration.checkProjectSettingsExclusions: false + workbench.startupEditor: "none" + +steps: + # ── Setup ── + - id: "ls-ready" + action: "waitForLanguageServer" + # No `verify:` — waitForLanguageServer is itself the deterministic + # readiness check; see java-dep-file-operations.yaml for rationale. + timeout: 180 + + - id: "close-aux-bar" + action: "executeVSCodeCommand workbench.action.closeAuxiliaryBar" + verify: "Auxiliary bar (Chat) closed" + + # Collapse the MAVEN workspace-folder pane so JAVA PROJECTS gets the full + # vertical space. OUTLINE and TIMELINE are collapsed by default in fresh + # sessions, so no explicit step is needed. + - id: "collapse-maven-pane" + action: "collapseSidebarSection maven" + + - id: "focus-java-projects" + action: "executeVSCodeCommand javaProjectExplorer.focus" + verify: "Java Projects view is focused" + + - id: "wait-tree-load" + action: "wait 3 seconds" + + # ── Test 1: New Interface ── + - id: "click-project-1" + action: "click my-app tree item" + + - id: "trigger-new-1" + action: "clickTreeItemAction my-app New..." + verify: "New resource quick pick opened" + + - id: "select-interface" + action: "select Interface option" + verify: "Interface selected" + + - id: "select-source-folder-1" + action: "select src/main/java option" + + - id: "enter-interface-name" + action: "fillQuickInput MyInterface" + # No `verify:` — fillQuickInput submits and closes the quick input. The + # deterministic `verifyEditorTab` below is the ground truth. + + - id: "verify-interface-tab" + action: "wait 2 seconds" + # No `verify:` — BEFORE/AFTER screenshots are identical once the editor + # tab is open; verifyEditorTab is authoritative. + verifyEditorTab: + title: "MyInterface.java" + timeout: 20 + + # Reset between cycles: save the dirty buffer, close editors, refocus. + - id: "save-1" + action: "executeVSCodeCommand workbench.action.files.saveAll" + + - id: "close-editors-1" + action: "run command View: Close All Editors" + + - id: "collapse-tree-1" + action: 'clickViewTitleAction "Java Projects" "Collapse All"' + + - id: "collapse-workspace-root-2" + action: "collapseWorkspaceRoot" + + - id: "focus-java-projects-2" + action: "executeVSCodeCommand javaProjectExplorer.focus" + waitBefore: 1 + + # ── Test 2: New Enum ── + - id: "click-project-2" + action: "click my-app tree item" + waitBefore: 1 + + - id: "trigger-new-2" + action: "clickTreeItemAction my-app New..." + + - id: "select-enum" + action: "select Enum option" + + - id: "select-source-folder-2" + action: "select src/main/java option" + + - id: "enter-enum-name" + action: "fillQuickInput MyEnum" + + - id: "verify-enum-tab" + action: "wait 2 seconds" + verifyEditorTab: + title: "MyEnum.java" + timeout: 20 + + - id: "save-2" + action: "executeVSCodeCommand workbench.action.files.saveAll" + + - id: "close-editors-2" + action: "run command View: Close All Editors" + + - id: "collapse-tree-2" + action: 'clickViewTitleAction "Java Projects" "Collapse All"' + + - id: "collapse-workspace-root-3" + action: "collapseWorkspaceRoot" + + - id: "focus-java-projects-3" + action: "executeVSCodeCommand javaProjectExplorer.focus" + waitBefore: 1 + + # ── Test 3: New Annotation ── + - id: "click-project-3" + action: "click my-app tree item" + waitBefore: 1 + + - id: "trigger-new-3" + action: "clickTreeItemAction my-app New..." + + - id: "select-annotation" + action: "select Annotation option" + + - id: "select-source-folder-3" + action: "select src/main/java option" + + - id: "enter-annotation-name" + action: "fillQuickInput MyAnnotation" + + - id: "verify-annotation-tab" + action: "wait 2 seconds" + verifyEditorTab: + title: "MyAnnotation.java" + timeout: 20 + + - id: "save-3" + action: "executeVSCodeCommand workbench.action.files.saveAll" + + - id: "close-editors-3" + action: "run command View: Close All Editors" + + - id: "collapse-tree-3" + action: 'clickViewTitleAction "Java Projects" "Collapse All"' + + - id: "collapse-workspace-root-4" + action: "collapseWorkspaceRoot" + + - id: "focus-java-projects-4" + action: "executeVSCodeCommand javaProjectExplorer.focus" + waitBefore: 1 + + # ── Test 4: New Abstract Class ── + - id: "click-project-4" + action: "click my-app tree item" + waitBefore: 1 + + - id: "trigger-new-4" + action: "clickTreeItemAction my-app New..." + + - id: "select-abstract-class" + action: "select Abstract Class option" + + - id: "select-source-folder-4" + action: "select src/main/java option" + + - id: "enter-abstract-name" + action: "fillQuickInput MyAbstract" + + - id: "verify-abstract-tab" + action: "wait 2 seconds" + verifyEditorTab: + title: "MyAbstract.java" + timeout: 20 + + - id: "save-4" + action: "executeVSCodeCommand workbench.action.files.saveAll" + + - id: "close-editors-4" + action: "run command View: Close All Editors" + + - id: "collapse-tree-4" + action: 'clickViewTitleAction "Java Projects" "Collapse All"' + + - id: "collapse-workspace-root-5" + action: "collapseWorkspaceRoot" + + - id: "focus-java-projects-5" + action: "executeVSCodeCommand javaProjectExplorer.focus" + waitBefore: 1 + + # ── Test 5: New File (plain non-Java file via "File" option) ── + # The "File" entry routes to `java.view.package.newFile` and writes the + # file under the project root (the node we triggered from). + - id: "click-project-5" + action: "click my-app tree item" + waitBefore: 1 + + - id: "trigger-new-5" + action: "clickTreeItemAction my-app New..." + + - id: "select-file" + action: "select File option" + + - id: "enter-file-name" + action: "fillQuickInput notes.txt" + + - id: "verify-file-tab" + action: "wait 2 seconds" + verifyEditorTab: + title: "notes.txt" + timeout: 20 + + - id: "save-5" + action: "executeVSCodeCommand workbench.action.files.saveAll" + + - id: "close-editors-5" + action: "run command View: Close All Editors" + + - id: "collapse-tree-5" + action: 'clickViewTitleAction "Java Projects" "Collapse All"' + + - id: "collapse-workspace-root-6" + action: "collapseWorkspaceRoot" + + - id: "focus-java-projects-6" + action: "executeVSCodeCommand javaProjectExplorer.focus" + waitBefore: 1 + + # ── Test 6: New Folder ── + # Folder creation has no editor side-effect — verify by checking the new + # folder exists on disk under the workspace root. + - id: "click-project-6" + action: "click my-app tree item" + waitBefore: 1 + + - id: "trigger-new-6" + action: "clickTreeItemAction my-app New..." + + - id: "select-folder" + action: "select Folder option" + + - id: "enter-folder-name" + action: "fillQuickInput my-new-folder" + + - id: "wait-folder-create" + action: "wait 2 seconds" + # No `verify:` — folder creation has no editor side-effect, so the + # BEFORE/AFTER screenshots are nearly identical and a screenshot LLM + # would downgrade. The deterministic verifyFile below is authoritative. + verifyFile: + path: "~/my-new-folder" + exists: true + timeout: 15 diff --git a/test/e2e-plans/java-dep-view-modes.yaml b/test/e2e-plans/java-dep-view-modes.yaml new file mode 100644 index 00000000..51f4f258 --- /dev/null +++ b/test/e2e-plans/java-dep-view-modes.yaml @@ -0,0 +1,224 @@ +# Test Plan: Java Dependency — View Modes & Refresh +# +# Covers Java Projects view title-bar / overflow commands: +# - java.view.package.changeToHierarchicalPackageView (Hierarchical View) +# - java.view.package.changeToFlatPackageView (Flat View) +# - java.view.package.refresh (Refresh) +# - java.project.explorer.hideNonJavaResources (Hide Non-Java Resources) +# - java.project.explorer.showNonJavaResources (Show Non-Java Resources) +# +# Usage: +# npx autotest run test/e2e-plans/java-dep-view-modes.yaml --vsix + +name: "Java Dependency — View Modes & Refresh" +description: | + Tests Java Projects explorer title-bar commands: switching between flat / + hierarchical package presentation, refreshing the tree, and toggling + visibility of non-Java resources (pom.xml, .vscode, .classpath, .project). + +setup: + extension: "redhat.java" + vscodeVersion: "stable" + workspace: "../maven" + timeout: 180 + settings: + java.configuration.checkProjectSettingsExclusions: false + workbench.startupEditor: "none" + +steps: + # ── Wait for LS ── + - id: "ls-ready" + action: "waitForLanguageServer" + # No `verify:` — waitForLanguageServer is the deterministic readiness + # check. The AFTER screenshot may transiently show "Java: Building - 0%" + # right after Ready, which a strict LLM mis-reads as a failure. + timeout: 180 + + # Free horizontal & vertical space so JAVA PROJECTS gets enough room. + - id: "close-aux-bar" + action: "executeVSCodeCommand workbench.action.closeAuxiliaryBar" + verify: "Auxiliary bar (Chat) closed" + + # Collapse the entire MAVEN workspace-folder pane so JAVA PROJECTS gets the + # full vertical space — its tree is virtualized and rows below the viewport + # are not rendered, which masks items like pom.xml that live below + # src/main/java in a Maven project. OUTLINE and TIMELINE panes are + # collapsed by default in a fresh session, so no explicit step needed. + - id: "collapse-maven-pane" + action: "collapseSidebarSection maven" + + - id: "focus-java-projects" + action: "executeVSCodeCommand javaProjectExplorer.focus" + verify: "Java Projects view is focused" + + - id: "wait-tree-load" + action: "wait 3 seconds" + + # Expand my-app → src/main/java so subsequent verifyTreeItem can observe + # package nodes at this layer. + - id: "expand-project" + action: "expandTreeItem my-app" + + - id: "expand-src-main" + action: "expandTreeItem src/main/java" + waitBefore: 2 + + # ── Baseline: flat mode shows "com.mycompany.app" as a single node ── + - id: "verify-flat-baseline" + action: "wait 1 seconds" + # No `verify:` — verifyTreeItem is authoritative. + verifyTreeItem: + name: "com.mycompany.app" + exact: true + inView: "Java Projects" + timeout: 15 + + # ── Test 1: switch to hierarchical view ── + # In hierarchical (compressed) mode the JLS collapses single-child chains, + # so "com.mycompany.app" is split into a parent "com.mycompany" node with + # children "app" and "app1". This is the same behavior covered by + # test/maven-suite/projectView.test.ts ("primarySubPackage.name should be + # 'com.mycompany'"). Verify deterministically through the appearance of + # the "com.mycompany" node. + - id: "switch-to-hierarchical" + action: 'clickViewTitleAction "Java Projects" "Hierarchical View"' + # Real UI path: opens the Java Projects view overflow menu and clicks + # "Hierarchical View". sub-screenshots capture overflow-open (button + # tooltip visible) and menuitem (Hierarchical View highlighted) so + # the LLM/human reviewer can verify the click landed correctly. + # deterministic verifyTreeItem below is still authoritative. + + - id: "wait-hierarchical" + action: "wait 4 seconds" + + - id: "verify-hierarchical-node" + action: "wait 1 seconds" + verifyTreeItem: + name: "com.mycompany" + exact: true + inView: "Java Projects" + timeout: 15 + + # ── Test 2: switch back to flat view ── + - id: "switch-to-flat" + action: 'clickViewTitleAction "Java Projects" "Flat View"' + # Real UI path through view-title overflow menu — see + # switch-to-hierarchical. verifyTreeItem below is authoritative. + + - id: "wait-flat" + action: "wait 4 seconds" + + - id: "verify-flat-restored" + action: "wait 1 seconds" + verifyTreeItem: + name: "com.mycompany.app" + exact: true + inView: "Java Projects" + timeout: 15 + + - id: "verify-hierarchical-gone" + action: "wait 1 seconds" + verifyTreeItem: + name: "com.mycompany" + exact: true + visible: false + inView: "Java Projects" + timeout: 15 + + # ── Test 3: refresh ── + # Smoke check: the command runs without throwing and the tree remains stable. + - id: "refresh-tree" + action: "executeVSCodeCommand java.view.package.refresh" + # No `verify:` — refresh has no visible effect at steady state, so the + # BEFORE/AFTER screenshots are identical and a strict LLM downgrades. + # The deterministic verifyTreeItem on verify-refresh-stable confirms the + # tree did not get corrupted by the refresh. + + - id: "wait-after-refresh" + action: "wait 3 seconds" + + - id: "verify-refresh-stable" + action: "wait 1 seconds" + verifyTreeItem: + name: "com.mycompany.app" + exact: true + inView: "Java Projects" + timeout: 15 + + # ── Test 4: hide non-Java resources ── + # In flat mode the project shows non-Java resources such as pom.xml, + # .vscode, .classpath, .project. Hide should remove them from the tree. + # `inView: "Java Projects"` scopes the search to the Java Projects pane + # only — without it the EXPLORER pane (which also shows pom.xml at the + # workspace root) would mask any Java-Projects-side change. + # + # The virtualized Java Projects tree only renders rows in the viewport, + # so we first collapse src/main/java to bring pom.xml (a sibling) into + # view. Click selects the node, then ArrowLeft collapses it. + - id: "select-src-main" + action: "click src/main/java" + + - id: "collapse-src-main" + action: "pressKey ArrowLeft" + + # After collapsing src/main/java, press End to scroll the (virtualized) + # JAVA PROJECTS tree to its last row, which makes pom.xml — a child of + # my-app rendered below other source folders / libraries — render in + # the DOM. Playwright's `waitFor("visible")` does not auto-scroll + # virtualized lists, so this is necessary. + - id: "scroll-tree-end" + action: "pressKey End" + + - id: "wait-collapse" + action: "wait 1 seconds" + + - id: "verify-pom-visible-baseline" + action: "wait 1 seconds" + verifyTreeItem: + name: "pom.xml" + exact: true + inView: "Java Projects" + timeout: 15 + + - id: "hide-non-java" + action: 'clickViewTitleAction "Java Projects" "Hide Non-Java Resources"' + # Real UI path through view-title overflow menu. The menu item label + # toggles based on `config.java.project.explorer.showNonJavaResources` + # (Show vs Hide), and the current state at this point is "showing" + # so the menu surfaces "Hide Non-Java Resources". verifyTreeItem + # checks below are authoritative. + + - id: "wait-hide" + action: "wait 5 seconds" + + - id: "verify-pom-hidden" + action: "wait 1 seconds" + verifyTreeItem: + name: "pom.xml" + exact: true + visible: false + inView: "Java Projects" + timeout: 30 + + # ── Test 5: show non-Java resources ── + - id: "show-non-java" + action: 'clickViewTitleAction "Java Projects" "Show Non-Java Resources"' + # Real UI path through view-title overflow menu. After hide-non-java + # the toggle now surfaces "Show Non-Java Resources". verifyTreeItem + # below is authoritative. + + - id: "wait-show" + action: "wait 5 seconds" + + # After the tree refresh, the scroll position may have reset to the top + # of the JAVA PROJECTS pane, so scroll back to the end to render pom.xml. + - id: "scroll-tree-end-2" + action: "pressKey End" + + - id: "verify-pom-restored" + action: "wait 1 seconds" + verifyTreeItem: + name: "pom.xml" + exact: true + inView: "Java Projects" + timeout: 30