diff --git a/src/test/GradleSingleModLCLSTest.ts b/src/test/GradleSingleModLCLSTest.ts new file mode 100755 index 00000000..f9dcd865 --- /dev/null +++ b/src/test/GradleSingleModLCLSTest.ts @@ -0,0 +1,261 @@ +/** + * Copyright (c) 2025 IBM Corporation. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +import { By, EditorView, SideBarView, TextEditor, VSBrowser } from "vscode-extension-tester"; +import * as utils from './utils/testUtils'; +import * as constants from './definitions/constants'; + +const path = require('path'); +const assert = require('assert'); + +describe('LCLS tests for Gradle Project', function () { + let editor: TextEditor; + let actualSeverXMLContent: string; + + before(() => { + utils.copyConfig(path.join(utils.getGradleProjectPath(), 'src', 'main', 'liberty', 'config'), path.join(utils.getGradleProjectPath(), 'src', 'main', 'liberty', 'config2')); + }); + + it('Should copy content of server.xml', async () => { + const section = await new SideBarView().getContent().getSection(constants.GRADLE_PROJECT); + section.expand(); + await VSBrowser.instance.openResources(path.join(utils.getGradleProjectPath(), 'src', 'main', 'liberty', 'config2', 'server.xml')); + + editor = await new EditorView().openEditor('server.xml') as TextEditor; + actualSeverXMLContent = await editor.getText(); + + assert(actualSeverXMLContent.length !== 0, 'Content of server.xml is not in copied.'); + console.log('Sever.xml content:', actualSeverXMLContent); + + }).timeout(10000); + + it('Should show diagnostic for server.xml invalid value', async () => { + + await VSBrowser.instance.openResources(path.join(utils.getGradleProjectPath(), 'src', 'main', 'liberty', 'config2', 'server.xml')); + editor = await new EditorView().openEditor('server.xml') as TextEditor; + + const hverExpectdOutcome = `'wrong' is not a valid value of union type 'booleanType'.`; + const testHverTarget = ''; + + await editor.typeTextAt(17, 5, testHverTarget); + const focusTargtElemnt = editor.findElement(By.xpath("//*[contains(text(), 'wrong')]")); + await utils.delay(3000); + focusTargtElemnt.click(); + await editor.click(); + + const actns = VSBrowser.instance.driver.actions(); + await actns.move({ origin: focusTargtElemnt }).perform(); + await utils.delay(5000); + + const hverContent = editor.findElement(By.className('hover-contents')); + const hverValue = await hverContent.getText(); + console.log("Hover text:" + hverValue); + + assert(hverValue.includes(hverExpectdOutcome), 'Did not get expected diagnostic in server.xml'); + + editor.clearText(); + editor.setText(actualSeverXMLContent); + console.log("Content restored"); + + }).timeout(35000); + + it('Should apply quick fix for invalid value in server.xml', async () => { + const section = await new SideBarView().getContent().getSection(constants.GRADLE_PROJECT); + section.expand(); + await VSBrowser.instance.openResources(path.join(utils.getGradleProjectPath(), 'src', 'main', 'liberty', 'config2', 'server.xml')); + + editor = await new EditorView().openEditor('server.xml') as TextEditor; + const stanzaSnipet = ""; + const expectedHoverData = ""; + await editor.typeTextAt(17, 5, stanzaSnipet); + await utils.delay(2000); + const flagedString = await editor.findElement(By.xpath("//*[contains(text(), '\"wrong\"')]")); + await utils.delay(7000); + + const actions = VSBrowser.instance.driver.actions(); + await actions.move({ origin: flagedString }).perform(); + await utils.delay(3000); + + const driver = VSBrowser.instance.driver; + const hoverTxt = await editor.findElement(By.className('hover-row status-bar')); + await utils.delay(2000); + + const qckFixPopupLink = await hoverTxt.findElement(By.xpath("//*[contains(text(), 'Quick Fix')]")); + await qckFixPopupLink.click(); + + const hoverTaskBar = await editor.findElement(By.className('context-view monaco-component bottom left fixed')); + await hoverTaskBar.findElement(By.className('actionList')); + await utils.delay(2000); + + const pointerBlockedElement = await driver.findElement(By.css('.context-view-pointerBlock')); + // Setting pointer block element display value as none to choose option from Quickfix menu + if (pointerBlockedElement) { + await driver.executeScript("arguments[0].style.display = 'none';", pointerBlockedElement); + } else { + console.log('pointerBlockElementt not found!'); + } + const qckfixOption = await editor.findElement(By.xpath("//*[contains(text(), \"Replace with 'true'\")]")); + await qckfixOption.click(); + + const updatedSeverXMLContent = await editor.getText(); + await utils.delay(3000); + console.log("Content after Quick fix : ", updatedSeverXMLContent); + assert(updatedSeverXMLContent.includes(expectedHoverData), 'Quick fix not applied correctly for the invalid value in server.xml.'); + + editor.clearText(); + editor.setText(actualSeverXMLContent); + console.log("Content restored"); + + }).timeout(38000); + + it('Should show hover support for server.xml Liberty Server Attribute', async () => { + + await VSBrowser.instance.openResources(path.join(utils.getGradleProjectPath(), 'src', 'main', 'liberty', 'config2', 'server.xml')); + editor = await new EditorView().openEditor('server.xml') as TextEditor; + + const hovrExpctdOutcome = `Configuration properties for an HTTP endpoint.`; + + console.log(hovrExpctdOutcome); + const focusTargtElemnt = editor.findElement(By.xpath("//*[contains(text(), 'httpEndpoint')]")); + await utils.delay(3000); + focusTargtElemnt.click(); + await editor.click(); + + const actns = VSBrowser.instance.driver.actions(); + await actns.move({ origin: focusTargtElemnt }).perform(); + await utils.delay(5000); + + const hverContent = editor.findElement(By.className('hover-contents')); + const hoveredText = await hverContent.getText(); + console.log("Hover text:" + hoveredText); + + assert(hoveredText.includes(hovrExpctdOutcome), 'Did not get expected hover data Liberty Server Attribute.'); + + editor.clearText(); + editor.setText(actualSeverXMLContent); + console.log("Content restored"); + + }).timeout(35000); + + it('Should show hover support for server.xml Liberty Server Feature', async () => { + + await VSBrowser.instance.openResources(path.join(utils.getGradleProjectPath(), 'src', 'main', 'liberty', 'config2', 'server.xml')); + editor = await new EditorView().openEditor('server.xml') as TextEditor; + + const hverExpectdOutcome = `Description: This feature provides support for the MicroProfile Health specification.`; + const testHverTarget = 'mpHealth-4.0'; + + await editor.typeTextAt(15, 35, '\n'); + await utils.delay(1000); + await editor.typeTextAt(16, 9, testHverTarget); + const focusTargtElemnt = editor.findElement(By.xpath("//*[contains(text(), 'mpHealth')]")); + await utils.delay(3000); + focusTargtElemnt.click(); + await editor.click(); + + const actns = VSBrowser.instance.driver.actions(); + await actns.move({ origin: focusTargtElemnt }).perform(); + await utils.delay(5000); + + const hverContent = editor.findElement(By.className('hover-contents')); + const hverValue = await hverContent.getText(); + console.log("Hover text:" + hverValue); + + assert(hverValue.includes(hverExpectdOutcome), 'Did not get expected hover data Liberty Server Feature.'); + + editor.clearText(); + editor.setText(actualSeverXMLContent); + console.log("Content restored"); + + }).timeout(33000); + + it('Should show type ahead support in server.xml Liberty Server Feature', async () => { + const section = await new SideBarView().getContent().getSection(constants.GRADLE_PROJECT); + section.expand(); + await VSBrowser.instance.openResources(path.join(utils.getGradleProjectPath(), 'src', 'main', 'liberty', 'config2', 'server.xml')); + + editor = await new EditorView().openEditor('server.xml') as TextEditor; + const featureTag = " { + const section = await new SideBarView().getContent().getSection(constants.GRADLE_PROJECT); + section.expand(); + await VSBrowser.instance.openResources(path.join(utils.getGradleProjectPath(), 'src', 'main', 'liberty', 'config2', 'server.xml')); + + editor = await new EditorView().openEditor('server.xml') as TextEditor; + const stanzaSnipet = "log"; + + const insertedConfig = ""; + await editor.typeTextAt(17, 5, stanzaSnipet); + await utils.delay(5000); + //open the assistant + let asist = await editor.toggleContentAssist(true); + // toggle can return void, so we need to make sure the object is present + if (asist) { + // to select an item use + await asist.select('logging') + } + // close the assistant + await editor.toggleContentAssist(false); + + // close the assistant + await editor.toggleContentAssist(false); + + const updatedServerxmlContent = await editor.getText(); + await utils.delay(3000); + console.log("Updated content in Sever.xml : ", updatedServerxmlContent); + assert(updatedServerxmlContent.includes(insertedConfig), 'Type ahead support is not worked as expected in server.xml Liberty Server Configuration Stanza'); + + editor.clearText(); + editor.setText(actualSeverXMLContent); + console.log("Content restored"); + + }).timeout(25000); + + after(() => { + utils.removeConfigDir(path.join(utils.getGradleProjectPath(), 'src', 'main', 'liberty', 'config2')); + console.log("Removed new config folder:"); + }); + +}); \ No newline at end of file diff --git a/src/test/utils/testUtils.ts b/src/test/utils/testUtils.ts index a2a0135b..ddbd7a34 100755 --- a/src/test/utils/testUtils.ts +++ b/src/test/utils/testUtils.ts @@ -5,6 +5,7 @@ import { MAVEN_PROJECT, STOP_DASHBOARD_MAC_ACTION } from '../definitions/consta import { MapContextMenuforMac } from './macUtils'; import clipboard = require('clipboardy'); import { expect } from 'chai'; +import * as fse from 'fs-extra'; export function delay(millisec: number) { return new Promise( resolve => setTimeout(resolve, millisec) ); @@ -192,4 +193,36 @@ export async function clearCommandPalette() { expect(buttons.length).equals(2); await dialog.pushButton('Clear'); } - \ No newline at end of file + +/** + * Remove newly created Project folder with content + */ +export async function removeConfigDir(projectPath: string): Promise { + try { + fs.accessSync(projectPath); + const projectContent = fs.readdirSync(projectPath); + await Promise.all( + projectContent.map(async (projectFiles) => { + const projectContentPath = path.join(projectPath, projectFiles); + const stats = fs.lstatSync(projectContentPath); + if (stats.isDirectory()) { + await removeConfigDir(projectContentPath); + } else { + fs.unlinkSync(projectContentPath); + } + }) + ); + fs.rmdirSync(projectPath); + } catch (error) { + console.error(`Error removing new project: ${error}`); + } +} + +/** + * Copy config directory and create new config + */ +export async function copyConfig(existingConfigPath: string, copyConfigPath: string): Promise { + fse.copy(existingConfigPath, copyConfigPath) + .then(() => console.log("New config folder created :" + copyConfigPath)) + .catch(err => console.log("Error creating config folder")); +} \ No newline at end of file