diff --git a/workspaces/common-libs/playwright-vscode-tester/src/browser.ts b/workspaces/common-libs/playwright-vscode-tester/src/browser.ts index 969b6b50717..4df5089d450 100644 --- a/workspaces/common-libs/playwright-vscode-tester/src/browser.ts +++ b/workspaces/common-libs/playwright-vscode-tester/src/browser.ts @@ -94,7 +94,8 @@ export class VSBrowser { "extensions.autoUpdate": false, "chat.disableAIFeatures": true, "github.copilot.enable": false, - "github.copilot.chat.enable": false + "github.copilot.chat.enable": false, + "workbench.secondarySideBar.defaultVisibility": "hidden" }; if (Object.keys(this.customSettings).length > 0) { console.log('Detected user defined code settings'); diff --git a/workspaces/mi/mi-core/src/state-machine-types.ts b/workspaces/mi/mi-core/src/state-machine-types.ts index 4873e81c436..4328f4872b9 100644 --- a/workspaces/mi/mi-core/src/state-machine-types.ts +++ b/workspaces/mi/mi-core/src/state-machine-types.ts @@ -269,6 +269,7 @@ export interface VisualizerLocation { connectorData?: any[]; previousContext?: any; env?: { [key: string]: string | undefined }; + isLoading?: boolean; } export interface PopupVisualizerLocation extends VisualizerLocation { diff --git a/workspaces/mi/mi-extension/package.json b/workspaces/mi/mi-extension/package.json index b75e950fbd1..e436ee7469a 100644 --- a/workspaces/mi/mi-extension/package.json +++ b/workspaces/mi/mi-extension/package.json @@ -162,6 +162,19 @@ "type": "boolean", "default": true, "description": "Update car plugin version automatically" + }, + "MI.logging.loggingLevel": { + "type": "string", + "enum": [ + "off", + "error", + "warn", + "info", + "debug" + ], + "default": "error", + "description": "The verbosity of logging. The Order is off < error < warn < info < debug.", + "scope": "window" } } }, diff --git a/workspaces/mi/mi-extension/src/RPCLayer.ts b/workspaces/mi/mi-extension/src/RPCLayer.ts index 10727240ead..fe9c2c70fca 100644 --- a/workspaces/mi/mi-extension/src/RPCLayer.ts +++ b/workspaces/mi/mi-extension/src/RPCLayer.ts @@ -99,6 +99,7 @@ async function getContext(projectUri: string): Promise { diagnostics: context.diagnostics, dataMapperProps: context.dataMapperProps, errors: context.errors, + isLoading: context.isLoading, env: { MI_AUTH_ORG: process.env.MI_AUTH_ORG || '', MI_AUTH_CLIENT_ID: process.env.MI_AUTH_CLIENT_ID || '', diff --git a/workspaces/mi/mi-extension/src/debugger/debugHelper.ts b/workspaces/mi/mi-extension/src/debugger/debugHelper.ts index 361f686fe4f..8787bb9ffea 100644 --- a/workspaces/mi/mi-extension/src/debugger/debugHelper.ts +++ b/workspaces/mi/mi-extension/src/debugger/debugHelper.ts @@ -29,7 +29,7 @@ import axios from 'axios'; import * as net from 'net'; import { MACHINE_VIEW } from '@wso2/mi-core'; import { getStateMachine } from '../stateMachine'; -import { ERROR_LOG, INFO_LOG, logDebug } from '../util/logger'; +import { logDebug, LogLevel } from '../util/logger'; import * as toml from "@iarna/toml"; import { DebuggerConfig } from './config'; import { ChildProcess } from 'child_process'; @@ -104,7 +104,7 @@ export function checkServerReadiness(): Promise { .then((response: { status: number; data: any; }) => { if (response.status === 200) { if (response.data.status === 'ready') { - logDebug('Server is ready with CApp deployed', INFO_LOG); + logDebug('Server is ready with CApp deployed', LogLevel.INFO); resolve(); } else { reject(response.data.status); @@ -115,7 +115,7 @@ export function checkServerReadiness(): Promise { if (elapsedTime < maxTimeout) { setTimeout(checkReadiness, retryInterval); } else { - logDebug('Timeout reached while checking server readiness', ERROR_LOG); + logDebug('Timeout reached while checking server readiness', LogLevel.ERROR); reject('CApp has encountered deployment issues. Please refer to the output for error logs.'); } } @@ -126,7 +126,7 @@ export function checkServerReadiness(): Promise { setTimeout(checkReadiness, retryInterval); } else { const errorMsg = error?.errors[0]?.message; - logDebug(`Error while checking for Server readiness: ${errorMsg}`, ERROR_LOG); + logDebug(`Error while checking for Server readiness: ${errorMsg}`, LogLevel.ERROR); reject(`CApp has encountered deployment issues. Please refer to the output for error logs.`); } }); @@ -224,7 +224,7 @@ export async function executeBuildTask(projectUri: string, serverPath: string, s const sourceFiles = await getCarFiles(targetDirectory); if (sourceFiles.length === 0) { const errorMessage = "No .car files were found in the target directory. Built without copying to the server's carbonapps directory."; - logDebug(errorMessage, ERROR_LOG); + logDebug(errorMessage, LogLevel.ERROR); reject(errorMessage); } else { const targetPath = path.join(serverPath, 'repository', 'deployment', 'server', 'carbonapps'); @@ -233,7 +233,7 @@ export async function executeBuildTask(projectUri: string, serverPath: string, s fs.copyFileSync(sourceFile.fsPath, destinationFile); DebuggerConfig.setCopiedCapp(destinationFile); }); - logDebug('Build and copy tasks executed successfully', INFO_LOG); + logDebug('Build and copy tasks executed successfully', LogLevel.INFO); resolve(); } } catch (err) { @@ -426,7 +426,7 @@ export async function executeTasks(projectUri: string, serverPath: string, isDeb resolve(); // Proceed with connecting to the port } else { - logDebug('Server is running, but the debugger command port not acitve', ERROR_LOG); + logDebug('Server is running, but the debugger command port not acitve', LogLevel.ERROR); reject(`Server command port isn't actively listening. Stop any running MI servers and restart the debugger.`); } }); @@ -444,7 +444,7 @@ export async function executeTasks(projectUri: string, serverPath: string, isDeb } }).catch((error) => { reject(error); - logDebug(`Error executing BuildTask: ${error}`, ERROR_LOG); + logDebug(`Error executing BuildTask: ${error}`, LogLevel.ERROR); }); }); @@ -457,7 +457,7 @@ export async function executeTasks(projectUri: string, serverPath: string, isDeb resolve(); // Proceed with connecting to the port } else { - logDebug(`The ${DebuggerConfig.getCommandPort()} port is not actively listening or the timeout has been reached.`, ERROR_LOG); + logDebug(`The ${DebuggerConfig.getCommandPort()} port is not actively listening or the timeout has been reached.`, LogLevel.ERROR); reject(`Server command port isn't actively listening. Stop any running MI servers and restart the debugger.`); } }); @@ -519,7 +519,7 @@ export async function deleteCapp(serverPath: string): Promise { resolve(); } } catch (err) { - logDebug(`Error deleting Capp: ${err}`, ERROR_LOG); + logDebug(`Error deleting Capp: ${err}`, LogLevel.ERROR); reject(err); } }); @@ -534,7 +534,7 @@ export async function deleteCopiedCapAndLibs() { await deleteSpecificFiles(copiedLibs); } catch (err) { - logDebug(`Failed to delete Capp and Libs: ${err}`, ERROR_LOG); + logDebug(`Failed to delete Capp and Libs: ${err}`, LogLevel.ERROR); throw err; } } @@ -549,7 +549,7 @@ export async function deleteSpecificFiles(filesToDelete: string[]): Promise { if (err) { - logDebug(`Error reading the micro-integrator-debug.bat file: ${err}`, ERROR_LOG); + logDebug(`Error reading the micro-integrator-debug.bat file: ${err}`, LogLevel.ERROR); reject(`Error while reading the micro-integrator-debug.bat file: ${err}`); return; } @@ -590,7 +590,7 @@ export function createTempDebugBatchFile(batchFilePath: string, binPath: string) fs.writeFile(destFilePath, updatedContent, 'utf8', (err) => { if (err) { - logDebug(`Error writing the micro-integrator-debug.bat file: ${err}`, ERROR_LOG); + logDebug(`Error writing the micro-integrator-debug.bat file: ${err}`, LogLevel.ERROR); reject(`Error while updating the micro-integrator-debug.bat file: ${err}`); return; } @@ -622,7 +622,7 @@ export async function readPortOffset(serverConfigPath: string): Promise { const workspace = vscode.workspace.getWorkspaceFolder(vscode.Uri.file(filePath)); if (!workspace) { - logDebug(`No workspace found for path: ${filePath}`, ERROR_LOG); + logDebug(`No workspace found for path: ${filePath}`, LogLevel.ERROR); throw new Error(`No workspace found for path: ${filePath}`); } const projectUri = workspace.uri.fsPath; @@ -391,17 +391,17 @@ export class Debugger extends EventEmitter { } resolve(); }).catch((error) => { - logDebug(`Error while sending the resume command: ${error}`, ERROR_LOG); + logDebug(`Error while sending the resume command: ${error}`, LogLevel.ERROR); reject(`Error while resuming the debugger server: ${error}`); }); }).catch((error) => { - logDebug(`Error while checking server readiness: ${error}`, ERROR_LOG); + logDebug(`Error while checking server readiness: ${error}`, LogLevel.ERROR); reject(error); }); }).catch((error) => { - logDebug(`Error while connecting the debugger to the MI server: ${error}`, ERROR_LOG); + logDebug(`Error while connecting the debugger to the MI server: ${error}`, LogLevel.ERROR); reject(`Error while connecting the debugger to the MI server: ${error}`); }); }); @@ -419,7 +419,7 @@ export class Debugger extends EventEmitter { // Error handling for the command client this.commandClient?.on('error', (error) => { - logDebug(`Command client error: ${error}`, ERROR_LOG); + logDebug(`Command client error: ${error}`, LogLevel.ERROR); reject(error); // Reject the promise if there's an error }); @@ -430,7 +430,7 @@ export class Debugger extends EventEmitter { // Error handling for the event client this.eventClient?.on('error', (error) => { - logDebug(`Event client error: ${error}`, ERROR_LOG); + logDebug(`Event client error: ${error}`, LogLevel.ERROR); reject(error); }); @@ -450,7 +450,7 @@ export class Debugger extends EventEmitter { const message = incompleteMessage.slice(0, newlineIndex); // Call a function with the received message - logDebug(`Event received: ${message}`, INFO_LOG); + logDebug(`Event received: ${message}`, LogLevel.INFO); // convert to eventData to json const eventDataJson = JSON.parse(message); @@ -591,7 +591,7 @@ export class Debugger extends EventEmitter { let incompleteMessage = ''; // Send request on the command port - logDebug(`Command: ${request}`, INFO_LOG); + logDebug(`Command: ${request}`, LogLevel.INFO); this.commandClient?.write(request); // Listen for response from the command port @@ -609,7 +609,7 @@ export class Debugger extends EventEmitter { const message = incompleteMessage.slice(0, newlineIndex); // Call a function with the received message - logDebug(`Command response: ${message}`, INFO_LOG); + logDebug(`Command response: ${message}`, LogLevel.INFO); resolve(message); // Resolve the promise with the message // Remove the processed message from incompleteMessage @@ -644,7 +644,7 @@ export class Debugger extends EventEmitter { variables.push(jsonResponse); } catch (error) { - logDebug(`Error sending properties-command for ${context}: ${error}`, ERROR_LOG); + logDebug(`Error sending properties-command for ${context}: ${error}`, LogLevel.ERROR); } } return variables; diff --git a/workspaces/mi/mi-extension/src/debugger/tasks.ts b/workspaces/mi/mi-extension/src/debugger/tasks.ts index a412060b0b5..3ea0770875a 100644 --- a/workspaces/mi/mi-extension/src/debugger/tasks.ts +++ b/workspaces/mi/mi-extension/src/debugger/tasks.ts @@ -20,7 +20,7 @@ import * as path from 'path'; import * as vscode from 'vscode'; import * as fs from 'fs'; import { createTempDebugBatchFile, setJavaHomeInEnvironmentAndPath } from './debugHelper'; -import { ERROR_LOG, logDebug } from '../util/logger'; +import { LogLevel, logDebug } from '../util/logger'; import { Uri, workspace } from "vscode"; import { MVN_COMMANDS } from "../constants"; @@ -151,7 +151,7 @@ export function getStopTask(serverPath: string): vscode.Task | undefined { const command = `${binPath} stop`; if (!fs.existsSync(binPath)) { - logDebug(`${binPath} does not exist`, ERROR_LOG); + logDebug(`${binPath} does not exist`, LogLevel.ERROR); return; } @@ -177,7 +177,7 @@ export function getStopCommand(serverPath: string): string | undefined { const command = `"${binPath}" stop`; if (!fs.existsSync(binPath)) { - logDebug(`${binPath} does not exist`, ERROR_LOG); + logDebug(`${binPath} does not exist`, LogLevel.ERROR); return; } diff --git a/workspaces/mi/mi-extension/src/stateMachine.ts b/workspaces/mi/mi-extension/src/stateMachine.ts index 765a408a093..94e29008ffd 100644 --- a/workspaces/mi/mi-extension/src/stateMachine.ts +++ b/workspaces/mi/mi-extension/src/stateMachine.ts @@ -21,7 +21,7 @@ import { history } from './history/activator'; import { COMMANDS } from './constants'; import { activateProjectExplorer } from './project-explorer/activate'; import { MockService, STNode, UnitTest, Task, InboundEndpoint } from '../../syntax-tree/lib/src'; -import { log } from './util/logger'; +import { logDebug } from './util/logger'; import { deriveConfigName, getSources } from './util/dataMapper'; import { fileURLToPath } from 'url'; import path = require('path'); @@ -52,10 +52,10 @@ const stateMachine = createMachine({ }, states: { initialize: { - entry: () => log("State Machine: Entering 'initialize' state"), + entry: () => logDebug("State Machine: Entering 'initialize' state"), invoke: { id: 'checkProject', - src: (context) => checkIfMiProject(context.projectUri!), + src: (context) => checkIfMiProject(context.projectUri!, context.view ?? undefined), onDone: [ { target: 'environmentSetup', @@ -119,7 +119,7 @@ const stateMachine = createMachine({ } }, projectDetected: { - entry: () => log("State Machine: Entering 'projectDetected' state"), + entry: () => logDebug("State Machine: Entering 'projectDetected' state"), invoke: { src: 'openWebPanel', onDone: { @@ -128,7 +128,7 @@ const stateMachine = createMachine({ } }, oldProjectDetected: { - entry: () => log("State Machine: Entering 'oldProjectDetected' state"), + entry: () => logDebug("State Machine: Entering 'oldProjectDetected' state"), invoke: { src: 'openWebPanel', onDone: { @@ -137,11 +137,11 @@ const stateMachine = createMachine({ } }, oldWorkspaceDetected: { - entry: () => log("State Machine: Entering 'oldWorkspaceDetected' state"), + entry: () => logDebug("State Machine: Entering 'oldWorkspaceDetected' state"), initial: "viewLoading", states: { viewLoading: { - entry: () => log("State Machine: Entering 'oldWorkspaceDetected.viewLoading' state"), + entry: () => logDebug("State Machine: Entering 'oldWorkspaceDetected.viewLoading' state"), invoke: [ { src: 'openWebPanel', @@ -152,7 +152,7 @@ const stateMachine = createMachine({ ] }, viewReady: { - entry: () => log("State Machine: Entering 'oldWorkspaceDetected.viewReady' state"), + entry: () => logDebug("State Machine: Entering 'oldWorkspaceDetected.viewReady' state"), on: { REFRESH_ENVIRONMENT: { target: '#mi.initialize' @@ -162,7 +162,7 @@ const stateMachine = createMachine({ } }, lsInit: { - entry: () => log("State Machine: Entering 'lsInit' state"), + entry: () => logDebug("State Machine: Entering 'lsInit' state"), invoke: { src: 'waitForLS', onDone: [ @@ -177,7 +177,8 @@ const stateMachine = createMachine({ target: 'ready.viewReady', cond: (context, event) => context.displayOverview === false, actions: assign({ - langClient: (context, event) => event.data + langClient: (context, event) => event.data, + isLoading: (context, event) => false }) } ], @@ -191,11 +192,11 @@ const stateMachine = createMachine({ } }, ready: { - entry: () => log("State Machine: Entering 'ready' state"), + entry: () => logDebug("State Machine: Entering 'ready' state"), initial: 'activateOtherFeatures', states: { activateOtherFeatures: { - entry: () => log("State Machine: Entering 'ready.activateOtherFeatures' state"), + entry: () => logDebug("State Machine: Entering 'ready.activateOtherFeatures' state"), invoke: { src: 'activateOtherFeatures', onDone: { @@ -204,7 +205,7 @@ const stateMachine = createMachine({ } }, viewLoading: { - entry: () => log("State Machine: Entering 'ready.viewLoading' state"), + entry: () => logDebug("State Machine: Entering 'ready.viewLoading' state"), invoke: { src: 'openWebPanel', onDone: [ @@ -220,7 +221,7 @@ const stateMachine = createMachine({ } }, resolveMissingDependencies: { - entry: () => log("State Machine: Entering 'ready.resolveMissingDependencies' state"), + entry: () => logDebug("State Machine: Entering 'ready.resolveMissingDependencies' state"), invoke: { src: 'resolveMissingDependencies', onDone: { @@ -232,31 +233,23 @@ const stateMachine = createMachine({ } }, viewFinding: { - entry: () => log("State Machine: Entering 'ready.viewFinding' state"), + entry: () => logDebug("State Machine: Entering 'ready.viewFinding' state"), invoke: { src: 'findView', onDone: { - target: 'viewStacking', + target: 'viewReady', actions: assign({ view: (context, event) => event.data.view, stNode: (context, event) => event.data.stNode, diagnostics: (context, event) => event.data.diagnostics, - dataMapperProps: (context, event) => event.data?.dataMapperProps + dataMapperProps: (context, event) => event.data?.dataMapperProps, + isLoading: (context, event) => false }) } } }, - viewStacking: { - entry: () => log("State Machine: Entering 'ready.viewStacking' state"), - invoke: { - src: 'updateStack', - onDone: { - target: "viewReady" - } - } - }, viewUpdated: { - entry: () => log("State Machine: Entering 'ready.viewUpdated' state"), + entry: () => logDebug("State Machine: Entering 'ready.viewUpdated' state"), invoke: { src: 'findView', onDone: { @@ -264,13 +257,14 @@ const stateMachine = createMachine({ actions: assign({ stNode: (context, event) => event.data.stNode, diagnostics: (context, event) => event.data.diagnostics, - dataMapperProps: (context, event) => event.data?.dataMapperProps + dataMapperProps: (context, event) => event.data?.dataMapperProps, + isLoading: (context, event) => false }) } } }, viewReady: { - entry: () => log("State Machine: Entering 'ready.viewReady' state"), + entry: () => logDebug("State Machine: Entering 'ready.viewReady' state"), on: { OPEN_VIEW: { target: "viewLoading", @@ -286,7 +280,8 @@ const stateMachine = createMachine({ stNode: (context, event) => undefined, diagnostics: (context, event) => undefined, type: (context, event) => event.type, - previousContext: (context, event) => context + previousContext: (context, event) => context, + isLoading: (context, event) => true }) }, REPLACE_VIEW: { @@ -322,17 +317,17 @@ const stateMachine = createMachine({ } }, disabled: { - entry: () => log("State Machine: Entering 'disabled' state"), + entry: () => logDebug("State Machine: Entering 'disabled' state"), invoke: { src: 'disableExtension', }, }, newProject: { - entry: () => log("State Machine: Entering 'newProject' state"), + entry: () => logDebug("State Machine: Entering 'newProject' state"), initial: "viewLoading", states: { viewLoading: { - entry: () => log("State Machine: Entering 'newProject.viewLoading' state"), + entry: () => logDebug("State Machine: Entering 'newProject.viewLoading' state"), invoke: { src: 'openWebPanel', data: (context, event) => ({ context, event, setTitle: true }), @@ -342,7 +337,7 @@ const stateMachine = createMachine({ } }, viewReady: { - entry: () => log("State Machine: Entering 'newProject.viewReady' state"), + entry: () => logDebug("State Machine: Entering 'newProject.viewReady' state"), on: { OPEN_VIEW: { target: "viewLoading", @@ -355,11 +350,11 @@ const stateMachine = createMachine({ } }, environmentSetup: { - entry: () => log("State Machine: Entering 'environmentSetup' state"), + entry: () => logDebug("State Machine: Entering 'environmentSetup' state"), initial: "viewLoading", states: { viewLoading: { - entry: () => log("State Machine: Entering 'environmentSetup.viewLoading' state"), + entry: () => logDebug("State Machine: Entering 'environmentSetup.viewLoading' state"), invoke: [ { src: 'openWebPanel', @@ -376,7 +371,7 @@ const stateMachine = createMachine({ ] }, viewReady: { - entry: () => log("State Machine: Entering 'environmentSetup.viewReady' state"), + entry: () => logDebug("State Machine: Entering 'environmentSetup.viewReady' state"), on: { REFRESH_ENVIRONMENT: { target: '#mi.initialize' @@ -394,7 +389,7 @@ const stateMachine = createMachine({ waitForLS: (context, event) => { // replace this with actual promise that waits for LS to be ready return new Promise(async (resolve, reject) => { - log("Waiting for LS to be ready " + new Date().toLocaleTimeString()); + console.log("Waiting for LS to be ready " + new Date().toLocaleTimeString()); try { vscode.commands.executeCommand(COMMANDS.FOCUS_PROJECT_EXPLORER); const instance = await MILanguageClient.getInstance(context.projectUri!); @@ -406,9 +401,9 @@ const stateMachine = createMachine({ vscode.commands.executeCommand('setContext', 'MI.status', 'projectLoaded'); resolve(ls); - log("LS is ready " + new Date().toLocaleTimeString()); + console.log("LS is ready " + new Date().toLocaleTimeString()); } catch (error) { - log("Error occured while waiting for LS to be ready " + new Date().toLocaleTimeString()); + console.log("Error occured while waiting for LS to be ready " + new Date().toLocaleTimeString()); reject(error); } }); @@ -683,7 +678,7 @@ const stateMachine = createMachine({ // Create a service to interpret the machine const stateMachines: Map = new Map(); -export const getStateMachine = (projectUri: string): { +export const getStateMachine = (projectUri: string, context?: VisualizerLocation): { service: () => any; context: () => MachineContext; state: () => MachineStateValue; @@ -700,7 +695,8 @@ export const getStateMachine = (projectUri: string): { projectUri: projectUri, langClient: null, errors: [], - view: MACHINE_VIEW.Welcome + view: MACHINE_VIEW.Overview, + ...context })).start(); stateMachines.set(projectUri, stateService); } @@ -820,17 +816,17 @@ function updateProjectExplorer(location: VisualizerLocation | undefined) { vscode.commands.executeCommand(COMMANDS.REVEAL_TEST_PANE); } else if (projectRoot && !extension.preserveActivity) { location.projectUri = projectRoot; - if (!getStateMachine(projectRoot).context().isOldProject) { + if (!getStateMachine(projectRoot, location).context().isOldProject) { vscode.commands.executeCommand(COMMANDS.REVEAL_ITEM_COMMAND, location); } } } } -async function checkIfMiProject(projectUri: string) { - log(`Detecting project in ${projectUri} - ${new Date().toLocaleTimeString()}`); +async function checkIfMiProject(projectUri: string, view: MACHINE_VIEW = MACHINE_VIEW.Overview) { + console.log(`Detecting project in ${projectUri} - ${new Date().toLocaleTimeString()}`); - let isProject = false, isOldProject = false, isOldWorkspace = false, displayOverview = true, view = MACHINE_VIEW.Overview, isEnvironmentSetUp = false; + let isProject = false, isOldProject = false, isOldWorkspace = false, displayOverview = true, isEnvironmentSetUp = false; const customProps: any = {}; try { // Check for pom.xml files excluding node_modules directory @@ -839,7 +835,7 @@ async function checkIfMiProject(projectUri: string) { const pomContent = await fs.promises.readFile(pomFilePath, 'utf-8'); isProject = pomContent.includes('integration-project'); if (isProject) { - log("MI project detected in " + projectUri); + console.log("MI project detected in " + projectUri); } } @@ -901,11 +897,11 @@ async function checkIfMiProject(projectUri: string) { if (!isEnvironmentSetUp) { vscode.commands.executeCommand('setContext', 'MI.status', 'notSetUp'); } - // Log project path - log(`Current workspace path: ${projectUri}`); + // console.log project path + console.log(`Current workspace path: ${projectUri}`); } - log(`Project detection completed for path: ${projectUri} at ${new Date().toLocaleTimeString()}`); + console.log(`Project detection completed for path: ${projectUri} at ${new Date().toLocaleTimeString()}`); return { isProject, isOldProject, @@ -926,18 +922,18 @@ export async function isOldProjectOrWorkspace(projectUri: any) { if (projectFiles.length > 0) { if (await containsMultiModuleNatureInProjectFile(projectFiles[0].fsPath)) { isOldProject = true; - log("Integration Studio project detected"); + console.log("Integration Studio project detected"); } } else if (fs.existsSync(pomFilePath)) { if (await containsMultiModuleNatureInPomFile(pomFilePath)) { isOldProject = true; - log("Integration Studio project detected"); + console.log("Integration Studio project detected"); } } else if (fs.existsSync(projectUri)) { const foundOldProjects = await findMultiModuleProjectsInWorkspaceDir(projectUri); if (foundOldProjects.length > 0) { isOldWorkspace = true; - log("Integration Studio workspace detected"); + console.log("Integration Studio workspace detected"); } } return isOldProject || isOldWorkspace ? { isOldProject, isOldWorkspace } : false; diff --git a/workspaces/mi/mi-extension/src/stateMachinePopup.ts b/workspaces/mi/mi-extension/src/stateMachinePopup.ts index 3d0311adc10..40df56a396c 100644 --- a/workspaces/mi/mi-extension/src/stateMachinePopup.ts +++ b/workspaces/mi/mi-extension/src/stateMachinePopup.ts @@ -23,6 +23,7 @@ import { POPUP_EVENT_TYPE, PopupVisualizerLocation, PopupMachineStateValue, onPa import { VisualizerWebview } from './visualizer/webview'; import { RPCLayer } from './RPCLayer'; import { getStateMachine } from './stateMachine'; +import { logDebug } from './util/logger'; interface PopupMachineContext extends PopupVisualizerLocation { errorCode: string | null; @@ -41,6 +42,7 @@ const stateMachinePopup = createMachine({ }, states: { initialize: { + entry: () => logDebug('Popup State Machine: Entering initialize state'), invoke: { src: 'initializeData', onDone: { @@ -58,6 +60,7 @@ const stateMachinePopup = createMachine({ } }, ready: { + entry: () => logDebug('Popup State Machine: Entering ready state'), on: { OPEN_VIEW: { target: "open", @@ -74,6 +77,7 @@ const stateMachinePopup = createMachine({ initial: "active", states: { active: { + entry: () => logDebug('Popup State Machine: Entering active state'), on: { OPEN_VIEW: { target: "reopen", @@ -94,6 +98,7 @@ const stateMachinePopup = createMachine({ } }, reopen: { + entry: () => logDebug('Popup State Machine: Entering reopen state'), invoke: { src: 'initializeData', onDone: { @@ -105,6 +110,7 @@ const stateMachinePopup = createMachine({ } }, notify: { + entry: () => logDebug('Popup State Machine: Entering notify state'), invoke: { src: 'notifyChange', onDone: { @@ -115,6 +121,7 @@ const stateMachinePopup = createMachine({ }, }, disabled: { + entry: () => logDebug('Popup State Machine: Entering disabled state'), invoke: { src: 'disableExtension' }, @@ -214,5 +221,17 @@ export const deletePopupStateMachine = (projectUri: string) => { }; export function openPopupView(projectUri: string, type: POPUP_EVENT_TYPE, viewLocation?: PopupVisualizerLocation) { - getPopupStateMachine(projectUri).service().send({ type: type, viewLocation: viewLocation }); + const stateMachine = getPopupStateMachine(projectUri); + const state = stateMachine.state(); + if (state === 'initialize') { + const listener = (state: { value: string; }) => { + if (state?.value === "ready") { + stateMachine.service().send({ type: type, viewLocation: viewLocation }); + stateMachine.service().off(listener); + } + }; + stateMachine.service().onTransition(listener); + } else { + stateMachine.service().send({ type: type, viewLocation: viewLocation }); + } } diff --git a/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/artifactTests/artifact.spec.ts b/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/artifactTests/artifact.spec.ts index 460ff17400e..79f66c110d2 100644 --- a/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/artifactTests/artifact.spec.ts +++ b/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/artifactTests/artifact.spec.ts @@ -36,7 +36,7 @@ import { EventIntegration } from '../components/ArtifactTest/EventIntegration'; import { ImportArtifact } from '../components/ImportArtifact'; import path from 'path'; import { ProjectExplorer } from '../components/ProjectExplorer'; -const filePath = path.join( __dirname, '..', 'components', 'ArtifactTest', 'data', 'importApi_v1.0.0.xml'); +const filePath = path.join(__dirname, '..', 'components', 'ArtifactTest', 'data', 'importApi_v1.0.0.xml'); export default function createTests() { test.describe('Artifact Tests', { @@ -128,7 +128,14 @@ export default function createTests() { await test.step('Open Diagram View for API', async () => { console.log('Opening Diagram View for API'); await api.openDiagramView("NewOpenAPI" + testAttempt + ":v1.0.27-SNAPSHOT", "/pet/findByStatus"); - // Collapese APIs section + + await page.page.waitForTimeout(2000); + await page.executePaletteCommand('View: Close All Editors'); + console.log("Closed editor groups"); + console.log('Opening Diagram View for API again without existing webview'); + await api.openDiagramView("NewOpenAPI" + testAttempt + ":v1.0.27-SNAPSHOT", "/pet/findByStatus"); + + // Collapse APIs section const projectExplorer = new ProjectExplorer(page.page); await projectExplorer.findItem(['Project testProject', 'APIs', "NewOpenAPI" + testAttempt + ":v1.0.27-SNAPSHOT"], true); await projectExplorer.findItem(['Project testProject', 'APIs'], true); @@ -364,9 +371,9 @@ export default function createTests() { await ms.createMessageStoreFromProjectExplorer(msName); // Close Message Stores const projectExplorer = new ProjectExplorer(page.page); - await projectExplorer.findItem(['Project testProject', 'Other Artifacts', 'Message Stores'], true); + await projectExplorer.findItem(['Project testProject', 'Other Artifacts', 'Message Stores'], true); }); - + }); test('Message Processor Tests', async () => { @@ -612,7 +619,7 @@ export default function createTests() { await projectExplorer.findItem(['Project testProject', 'Other Artifacts', 'Proxy Services'], true); }); - test ('Import Artifact', async () => { + test('Import Artifact', async () => { await test.step('Import API Artifact', async () => { const importArtifact = new ImportArtifact(page.page); await importArtifact.init(); diff --git a/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/APITests.ts b/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/APITests.ts index 84b2f61efbc..50c31504b8e 100644 --- a/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/APITests.ts +++ b/workspaces/mi/mi-extension/src/test/e2e-playwright-tests/components/ArtifactTest/APITests.ts @@ -401,12 +401,11 @@ export class API { public async openDiagramView(name: string, resourcePath : string) { const projectExplorer = new ProjectExplorer(this._page); - await projectExplorer.goToOverview("testProject"); await projectExplorer.findItem(['Project testProject', 'APIs', name, resourcePath], true); const webView = await switchToIFrame('Resource View', this._page); if (!webView) { throw new Error("Failed to switch to Resource View iframe"); } - await webView.getByText('Start').click(); + await webView.getByText('Start').waitFor(); } } diff --git a/workspaces/mi/mi-extension/src/util/logger.ts b/workspaces/mi/mi-extension/src/util/logger.ts index ffa428f97ad..387f88dc5ef 100644 --- a/workspaces/mi/mi-extension/src/util/logger.ts +++ b/workspaces/mi/mi-extension/src/util/logger.ts @@ -19,8 +19,13 @@ import * as vscode from 'vscode'; export const outputChannel = vscode.window.createOutputChannel("WSO2 Integrator: MI"); -export const ERROR_LOG = 'ERROR'; -export const INFO_LOG = 'INFO'; + +export enum LogLevel { + ERROR = 'error', + WARN = 'warn', + INFO = 'info', + DEBUG = 'debug' +} function withNewLine(value: string) { if (typeof value === 'string' && !value.endsWith('\n')) { @@ -41,8 +46,18 @@ export function logWithDebugLevel(message: string, debugLabel: string, logLevel: outputChannel.append(output); } -export function logDebug(message: string, logLevel: string): void { - logWithDebugLevel(message, 'MI Debug', logLevel); +export function logDebug(message: string, logLevel: LogLevel = LogLevel.DEBUG): void { + const config = vscode.workspace.getConfiguration('MI'); + const configuredLevel = config.get('logging.loggingLevel'); + + if (configuredLevel === 'off') { + return; + } + // Only log if the message's level is >= configured level + const levels = [LogLevel.ERROR, LogLevel.WARN, LogLevel.INFO, LogLevel.DEBUG]; + if (levels.indexOf(logLevel) <= levels.indexOf(configuredLevel as LogLevel)) { + logWithDebugLevel(message, 'MI Debug', logLevel); + } } export function getOutputChannel() { diff --git a/workspaces/mi/mi-extension/tsconfig.json b/workspaces/mi/mi-extension/tsconfig.json index af0b1cb1cb8..fb41a722496 100644 --- a/workspaces/mi/mi-extension/tsconfig.json +++ b/workspaces/mi/mi-extension/tsconfig.json @@ -20,6 +20,7 @@ }, "exclude": [ "./resources", - "./src/test/e2e-playwright-tests/data" + "./src/test/e2e-playwright-tests/data", + "./src/test/test-resources" ] } \ No newline at end of file diff --git a/workspaces/mi/mi-visualizer/src/Visualizer.tsx b/workspaces/mi/mi-visualizer/src/Visualizer.tsx index f3c824f46c8..648870207d2 100644 --- a/workspaces/mi/mi-visualizer/src/Visualizer.tsx +++ b/workspaces/mi/mi-visualizer/src/Visualizer.tsx @@ -93,7 +93,7 @@ export function Visualizer({ mode, swaggerData }: { mode: string, swaggerData?: rpcClient.getVisualizerState().then((initialState) => { setState(newState); process.env = initialState.env || {}; - if (Object.values(newState)?.[0] === 'viewReady') { + if (Object.values(newState)?.[0] === 'viewReady' && !initialState.isLoading) { setVisualizerState(initialState); } });