Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions .github/workflows/linuxUI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install -y libxkbfile-dev pkg-config libsecret-1-dev libxss1 dbus xvfb libgtk-3-0 libgbm1
sudo /usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
sudo /usr/bin/Xvfb :99 -screen 0 1920x1080x24 > /dev/null 2>&1 &
sleep 3

- name: Set up JDK 21
Expand Down Expand Up @@ -75,4 +75,16 @@ jobs:

- name: Print language server Log
if: ${{ failure() }}
run: find ./test-resources/settings/User/workspaceStorage/*/redhat.java/jdt_ws/.metadata/.log -print -exec cat '{}' \;;
run: |
find ./test-resources/settings/User/workspaceStorage \
-path "*/redhat.java/jdt_ws/.metadata/.log" \
-print -exec cat '{}' \; \
|| echo "No language server log found"

- name: Upload test screenshots
if: ${{ failure() }}
uses: actions/upload-artifact@v4
with:
name: test-screenshots
path: test-resources/screenshots/
if-no-files-found: ignore
17 changes: 16 additions & 1 deletion .github/workflows/windowsUI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,19 @@ jobs:

- name: Print language server Log if job failed
if: ${{ failure() }}
run: Get-ChildItem -Path ./test-resources/settings/User/workspaceStorage/*/redhat.java/jdt_ws/.metadata/.log | cat
run: |
$logFiles = Get-ChildItem -Path ./test-resources/settings/User/workspaceStorage -Recurse -Filter ".log" -ErrorAction SilentlyContinue |
Where-Object { $_.FullName -match 'redhat\.java.*jdt_ws.*\.metadata.*\.log$' }
if ($logFiles) {
$logFiles | ForEach-Object { Write-Host $_.FullName; Get-Content $_ }
} else {
Write-Host "No language server log found"
}

- name: Upload test screenshots
if: ${{ failure() }}
uses: actions/upload-artifact@v4
with:
name: test-screenshots
path: test-resources/screenshots/
if-no-files-found: ignore
66 changes: 66 additions & 0 deletions test/ui/command.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ describe("Command Tests", function() {
fse.copySync(projectPath, projectFolder);
await VSBrowser.instance.openResources(projectFolder);
currentProjectPath = projectFolder;
// openResources() sends the CLI IPC command and returns immediately, before VS Code
// has actually reloaded the window with the new folder. On Linux the IPC + reload
// cycle is slower; calling openFile() right after can race with or even abort the
// folder load. Poll the window title until it contains the folder name so we know
// VS Code has finished the workspace transition before we proceed.
await waitForWorkspaceOpen(path.basename(projectFolder));
await dismissModalDialogIfPresent();
await ensureExplorerIsOpen();
}

Expand Down Expand Up @@ -77,12 +84,25 @@ describe("Command Tests", function() {
await sleep(1000);
}
}
// The check above leaves the language status hover popup open. Close it by clicking
// the same element again (toggle behavior) so it does not overlay sidebar tree items
// on Linux, where ESC alone is not always reliable.
try {
const languageStatus = await statusBar.findElement(By.xpath('//*[@id="status.languageStatus"]'));
await languageStatus.click();
await sleep(300);
} catch (_e) {
// popup may have already been dismissed — ignore
}
}

before(async function() {
await openProject(mavenProjectPath);
await openFile(mavenJavaFilePath);
await waitForLanguageServerReady();
// Extra safety: send ESC in case any residual overlay is still present
await VSBrowser.instance.driver.actions().sendKeys(seleniumWebdriver.Key.ESCAPE).perform();
await clearNotificationsIfPresent();
});

after(async function() {
Expand All @@ -96,6 +116,16 @@ describe("Command Tests", function() {
}
});

afterEach(async function() {
if (this.currentTest?.state === 'failed') {
const safeName = this.currentTest.title.replace(/[^a-zA-Z0-9_-]/g, '_');
try {
await VSBrowser.instance.takeScreenshot(safeName);
} catch (e) {
console.warn(`Failed to take screenshot for ${safeName}: ${e}`);
}
}
});

it("Test javaProjectExplorer.focus", async function() {
await new Workbench().executeCommand("javaProjectExplorer.focus");
Expand Down Expand Up @@ -175,6 +205,8 @@ describe("Command Tests", function() {
});

(platform() === "darwin" ? it.skip : it)("Test java.view.package.revealInProjectExplorer", async function() {
await dismissModalDialogIfPresent();
await clearNotificationsIfPresent();
// Make sure App.java is not currently revealed in Java Projects
const section = await new SideBarView().getContent().getSection("Java Projects");
const item = await section.findItem("my-app") as TreeItem;
Expand Down Expand Up @@ -334,6 +366,8 @@ async function collapseFileSection() {
}

async function expandMainCodeInJavaProjects() {
await dismissModalDialogIfPresent();
await clearNotificationsIfPresent();
const section = await new SideBarView().getContent().getSection("Java Projects");
await section.click();
const appNode = await section.findItem("my-app") as TreeItem;
Expand All @@ -348,6 +382,8 @@ async function expandMainCodeInJavaProjects() {
async function expandInJavaProjects(label: string, ...otherLabels: string[]): Promise<[TreeItem, ViewSection]> {
// Dismiss any lingering modal dialog that could block sidebar clicks
await dismissModalDialogIfPresent();
// Clear notification toasts that could overlay sidebar elements
await clearNotificationsIfPresent();
// Collapse file section to make sure that the AppToRename tree item fits in the current viewport.
// .findItem will only find tree items in the current viewport.
await collapseFileSection();
Expand Down Expand Up @@ -427,6 +463,16 @@ async function dismissModalDialogIfPresent() {
}
}

async function clearNotificationsIfPresent() {
try {
const center = await new Workbench().openNotificationsCenter();
await center.clearAllNotifications();
await center.close();
} catch (_e) {
// No notifications or center not available — nothing to clear
}
}

async function waitForTreeItem(section: ViewSection, label: string, timeoutMs = 15000): Promise<TreeItem | undefined> {
const start = Date.now();
while (Date.now() - start < timeoutMs) {
Expand Down Expand Up @@ -511,3 +557,23 @@ async function ensureExplorerIsOpen() {
await control.openView();
}

/**
* Poll the VS Code window title until it contains {@link folderName}, which signals that
* VS Code has finished the workspace-reload triggered by openResources(). Falls back
* silently after {@link timeoutMs} so tests can still run and produce useful error messages.
*/
async function waitForWorkspaceOpen(folderName: string, timeoutMs: number = 30000): Promise<void> {
const start = Date.now();
while (Date.now() - start < timeoutMs) {
try {
const title = await VSBrowser.instance.driver.getTitle();
if (title.toLowerCase().includes(folderName.toLowerCase())) {
return;
}
} catch (_e) {
// VS Code is mid-reload; its window title is temporarily unavailable.
}
await sleep(1000);
}
}

7 changes: 5 additions & 2 deletions test/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ async function main(): Promise<void> {
try {
// Run UI command tests
const testPath = path.join(__dirname, "command.test.js");
const exTester = new ExTester();
const exTester = new ExTester("./test-resources");
await exTester.downloadCode();
await exTester.installVsix();
await exTester.installFromMarketplace("redhat.java");
await exTester.downloadChromeDriver();
await exTester.setupRequirements();
process.exit(await exTester.runTests(testPath, {resources: []}));
// Disable workspace trust via settings to prevent the trust dialog from
// blocking project load on Linux (equivalent to --disable-workspace-trust).
const testSettings = path.join(__dirname, "..", "..", "..", "test", "ui", "test-settings.json");
process.exit(await exTester.runTests(testPath, {resources: [], settings: testSettings}));
} catch (err) {
console.log(err);
process.exit(1);
Expand Down
3 changes: 3 additions & 0 deletions test/ui/test-settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"security.workspace.trust.enabled": false
}
Loading